aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-12-15 14:13:33 +0000
committerGitHub <noreply@github.com>2022-12-15 14:13:33 +0000
commit84a85305de56260ef9cea8116c05fa06d5e6f841 (patch)
tree71c2e377ee1573231d3bc67287f79305b423dccf /gcc
parent9c21f45e4534afaa41456f342ceff9db52814053 (diff)
parent782daee399870e2b21dce410d8bbdd32dd75b68b (diff)
downloadgcc-84a85305de56260ef9cea8116c05fa06d5e6f841.zip
gcc-84a85305de56260ef9cea8116c05fa06d5e6f841.tar.gz
gcc-84a85305de56260ef9cea8116c05fa06d5e6f841.tar.bz2
Merge #1700
1700: Merge upstream, last commit before GCC/Rust upstreaming r=CohenArthur a=tschwinge Co-authored-by: Eric Botcazou <ebotcazou@adacore.com> Co-authored-by: Richard Biener <rguenther@suse.de> Co-authored-by: Patrick Palka <ppalka@redhat.com> Co-authored-by: Jonathan Wakely <jwakely@redhat.com> Co-authored-by: Harald Anlauf <anlauf@gmx.de> Co-authored-by: Ian Lance Taylor <iant@golang.org> Co-authored-by: GCC Administrator <gccadmin@gcc.gnu.org> Co-authored-by: David Malcolm <dmalcolm@redhat.com> Co-authored-by: Lulu Cheng <chenglulu@loongson.cn> Co-authored-by: Alexandre Oliva <oliva@adacore.com> Co-authored-by: Paul-Antoine Arras <pa@codesourcery.com> Co-authored-by: Tobias Burnus <tobias@codesourcery.com> Co-authored-by: Jakub Jelinek <jakub@redhat.com> Co-authored-by: Martin Liska <mliska@suse.cz> Co-authored-by: Iskander Shakirzyanov <iskander@ispras.ru> Co-authored-by: Iain Buclaw <ibuclaw@gdcproject.org> Co-authored-by: Kyrylo Tkachov <kyrylo.tkachov@arm.com> Co-authored-by: John David Anglin <danglin@gcc.gnu.org>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8458
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in12
-rw-r--r--gcc/ada/ChangeLog1379
-rw-r--r--gcc/ada/accessibility.adb2305
-rw-r--r--gcc/ada/accessibility.ads222
-rw-r--r--gcc/ada/adaint.c6
-rw-r--r--gcc/ada/aspects.adb1
-rw-r--r--gcc/ada/atree.ads6
-rw-r--r--gcc/ada/bindgen.adb118
-rw-r--r--gcc/ada/checks.adb269
-rw-r--r--gcc/ada/checks.ads35
-rw-r--r--gcc/ada/contracts.adb534
-rw-r--r--gcc/ada/contracts.ads4
-rw-r--r--gcc/ada/debug.adb6
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_aspects.rst2
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst4
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst2
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst148
-rw-r--r--gcc/ada/doc/gnat_rm/security_hardening_features.rst126
-rw-r--r--gcc/ada/doc/gnat_rm/standard_library_routines.rst4
-rw-r--r--gcc/ada/doc/gnat_rm/the_gnat_library.rst40
-rw-r--r--gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst57
-rw-r--r--gcc/ada/doc/gnat_ugn/elaboration_order_handling_in_gnat.rst15
-rw-r--r--gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst73
-rw-r--r--gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst68
-rw-r--r--gcc/ada/doc/share/conf.py102
-rw-r--r--gcc/ada/einfo.ads21
-rw-r--r--gcc/ada/err_vars.ads13
-rw-r--r--gcc/ada/errout.adb93
-rw-r--r--gcc/ada/errout.ads33
-rw-r--r--gcc/ada/erroutc.adb38
-rw-r--r--gcc/ada/erroutc.ads2
-rw-r--r--gcc/ada/errutil.adb2
-rw-r--r--gcc/ada/exp_aggr.adb7
-rw-r--r--gcc/ada/exp_atag.adb2
-rw-r--r--gcc/ada/exp_attr.adb75
-rw-r--r--gcc/ada/exp_ch11.adb1
-rw-r--r--gcc/ada/exp_ch3.adb738
-rw-r--r--gcc/ada/exp_ch3.ads16
-rw-r--r--gcc/ada/exp_ch4.adb738
-rw-r--r--gcc/ada/exp_ch4.ads2
-rw-r--r--gcc/ada/exp_ch5.adb6
-rw-r--r--gcc/ada/exp_ch6.adb526
-rw-r--r--gcc/ada/exp_ch6.ads47
-rw-r--r--gcc/ada/exp_ch7.adb2
-rw-r--r--gcc/ada/exp_ch9.adb38
-rw-r--r--gcc/ada/exp_dbug.adb2
-rw-r--r--gcc/ada/exp_disp.adb49
-rw-r--r--gcc/ada/exp_imgv.adb43
-rw-r--r--gcc/ada/exp_intr.adb47
-rw-r--r--gcc/ada/exp_pakd.adb13
-rw-r--r--gcc/ada/exp_prag.adb1
-rw-r--r--gcc/ada/exp_put_image.adb35
-rw-r--r--gcc/ada/exp_put_image.ads6
-rw-r--r--gcc/ada/exp_spark.adb2
-rw-r--r--gcc/ada/exp_unst.adb2
-rw-r--r--gcc/ada/exp_util.adb19
-rw-r--r--gcc/ada/fe.h4
-rw-r--r--gcc/ada/freeze.adb145
-rw-r--r--gcc/ada/frontend.adb12
-rw-r--r--gcc/ada/gcc-interface/Make-lang.in3
-rw-r--r--gcc/ada/gcc-interface/Makefile.in2
-rw-r--r--gcc/ada/gcc-interface/decl.cc13
-rw-r--r--gcc/ada/gcc-interface/trans.cc31
-rw-r--r--gcc/ada/gcc-interface/utils2.cc33
-rw-r--r--gcc/ada/gen_il-fields.ads3
-rw-r--r--gcc/ada/gen_il-gen-gen_nodes.adb3
-rw-r--r--gcc/ada/gen_il-internals.adb2
-rw-r--r--gcc/ada/gnat1drv.adb7
-rw-r--r--gcc/ada/gnat_rm.texi388
-rw-r--r--gcc/ada/gnat_ugn.texi164
-rw-r--r--gcc/ada/gnatbind.adb3
-rw-r--r--gcc/ada/inline.adb20
-rw-r--r--gcc/ada/inline.ads2
-rw-r--r--gcc/ada/layout.adb3
-rw-r--r--gcc/ada/lib-xref.adb7
-rw-r--r--gcc/ada/libgnarl/s-interr.adb28
-rw-r--r--gcc/ada/libgnat/a-ngcoar.adb4
-rw-r--r--gcc/ada/libgnat/a-ngcoar.ads4
-rw-r--r--gcc/ada/libgnat/a-strsup.adb11
-rw-r--r--gcc/ada/libgnat/a-strsup.ads8
-rw-r--r--gcc/ada/libgnat/a-sttebu.adb3
-rw-r--r--gcc/ada/libgnat/a-stwisu.adb11
-rw-r--r--gcc/ada/libgnat/a-stwisu.ads8
-rw-r--r--gcc/ada/libgnat/a-stzsup.adb11
-rw-r--r--gcc/ada/libgnat/a-stzsup.ads8
-rw-r--r--gcc/ada/libgnat/a-tags.adb22
-rw-r--r--gcc/ada/libgnat/g-excact.ads5
-rw-r--r--gcc/ada/libgnat/g-souinf.ads20
-rw-r--r--gcc/ada/libgnat/g-traceb.ads36
-rw-r--r--gcc/ada/libgnat/i-c.adb15
-rw-r--r--gcc/ada/libgnat/s-regpat.adb8
-rw-r--r--gcc/ada/libgnat/s-rident.ads5
-rw-r--r--gcc/ada/libgnat/system-qnx-arm.ads2
-rw-r--r--gcc/ada/libgnat/system-rtems.ads1
-rw-r--r--gcc/ada/libgnat/system-vxworks7-aarch64-rtp-smp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-aarch64.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-arm-rtp-smp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-arm.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-ppc-kernel.ads1
-rw-r--r--gcc/ada/libgnat/system-vxworks7-ppc-rtp-smp.ads1
-rw-r--r--gcc/ada/libgnat/system-vxworks7-ppc64-kernel.ads1
-rw-r--r--gcc/ada/libgnat/system-vxworks7-ppc64-rtp-smp.ads1
-rw-r--r--gcc/ada/libgnat/system-vxworks7-x86-kernel.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-x86-rtp-smp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-x86_64-kernel.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-x86_64-rtp-smp.ads2
-rw-r--r--gcc/ada/mdll.adb68
-rw-r--r--gcc/ada/mdll.ads4
-rw-r--r--gcc/ada/opt.ads297
-rw-r--r--gcc/ada/par-ch3.adb11
-rw-r--r--gcc/ada/par-ch4.adb4
-rw-r--r--gcc/ada/par-prag.adb35
-rw-r--r--gcc/ada/pprint.adb4
-rw-r--r--gcc/ada/restrict.adb13
-rw-r--r--gcc/ada/rtsfind.adb4
-rw-r--r--gcc/ada/rtsfind.ads4
-rw-r--r--gcc/ada/sa_messages.adb539
-rw-r--r--gcc/ada/sa_messages.ads267
-rw-r--r--gcc/ada/scans.ads27
-rw-r--r--gcc/ada/scn.adb2
-rw-r--r--gcc/ada/sem_aggr.adb49
-rw-r--r--gcc/ada/sem_attr.adb177
-rw-r--r--gcc/ada/sem_aux.ads2
-rw-r--r--gcc/ada/sem_case.adb15
-rw-r--r--gcc/ada/sem_ch10.adb1
-rw-r--r--gcc/ada/sem_ch11.adb1
-rw-r--r--gcc/ada/sem_ch12.adb73
-rw-r--r--gcc/ada/sem_ch12.ads18
-rw-r--r--gcc/ada/sem_ch13.adb51
-rw-r--r--gcc/ada/sem_ch3.adb226
-rw-r--r--gcc/ada/sem_ch4.adb247
-rw-r--r--gcc/ada/sem_ch5.adb19
-rw-r--r--gcc/ada/sem_ch6.adb1862
-rw-r--r--gcc/ada/sem_ch6.ads19
-rw-r--r--gcc/ada/sem_ch7.adb32
-rw-r--r--gcc/ada/sem_ch8.adb46
-rw-r--r--gcc/ada/sem_ch9.adb14
-rw-r--r--gcc/ada/sem_dim.adb2
-rw-r--r--gcc/ada/sem_disp.adb15
-rw-r--r--gcc/ada/sem_elab.adb25
-rw-r--r--gcc/ada/sem_eval.adb7
-rw-r--r--gcc/ada/sem_prag.adb211
-rw-r--r--gcc/ada/sem_res.adb207
-rw-r--r--gcc/ada/sem_type.adb2
-rw-r--r--gcc/ada/sem_util.adb1498
-rw-r--r--gcc/ada/sem_util.ads164
-rw-r--r--gcc/ada/sem_warn.adb284
-rw-r--r--gcc/ada/sfn_scan.adb1
-rw-r--r--gcc/ada/sinfo.ads36
-rw-r--r--gcc/ada/sinput.adb4
-rw-r--r--gcc/ada/sinput.ads2
-rw-r--r--gcc/ada/switch-b.adb9
-rw-r--r--gcc/ada/switch-c.adb22
-rw-r--r--gcc/ada/treepr.adb5
-rw-r--r--gcc/ada/usage.adb4
-rw-r--r--gcc/ada/warnsw.adb934
-rw-r--r--gcc/ada/warnsw.ads537
-rw-r--r--gcc/analyzer/ChangeLog1374
-rw-r--r--gcc/analyzer/analysis-plan.cc1
-rw-r--r--gcc/analyzer/analyzer-language.cc140
-rw-r--r--gcc/analyzer/analyzer-language.h48
-rw-r--r--gcc/analyzer/analyzer-pass.cc1
-rw-r--r--gcc/analyzer/analyzer-selftests.cc1
-rw-r--r--gcc/analyzer/analyzer.cc3
-rw-r--r--gcc/analyzer/analyzer.h50
-rw-r--r--gcc/analyzer/analyzer.opt20
-rw-r--r--gcc/analyzer/bounds-checking.cc943
-rw-r--r--gcc/analyzer/call-details.cc231
-rw-r--r--gcc/analyzer/call-details.h77
-rw-r--r--gcc/analyzer/call-info.cc39
-rw-r--r--gcc/analyzer/call-info.h34
-rw-r--r--gcc/analyzer/call-string.cc17
-rw-r--r--gcc/analyzer/call-string.h2
-rw-r--r--gcc/analyzer/call-summary.cc7
-rw-r--r--gcc/analyzer/call-summary.h2
-rw-r--r--gcc/analyzer/checker-event.cc1209
-rw-r--r--gcc/analyzer/checker-event.h689
-rw-r--r--gcc/analyzer/checker-path.cc1185
-rw-r--r--gcc/analyzer/checker-path.h600
-rw-r--r--gcc/analyzer/complexity.cc1
-rw-r--r--gcc/analyzer/constraint-manager.cc1
-rw-r--r--gcc/analyzer/diagnostic-manager.cc336
-rw-r--r--gcc/analyzer/diagnostic-manager.h32
-rw-r--r--gcc/analyzer/engine.cc394
-rw-r--r--gcc/analyzer/exploded-graph.h38
-rw-r--r--gcc/analyzer/feasible-graph.cc5
-rw-r--r--gcc/analyzer/feasible-graph.h2
-rw-r--r--gcc/analyzer/infinite-recursion.cc482
-rw-r--r--gcc/analyzer/kf-analyzer.cc386
-rw-r--r--gcc/analyzer/kf-lang-cp.cc111
-rw-r--r--gcc/analyzer/kf.cc991
-rw-r--r--gcc/analyzer/known-function-manager.cc101
-rw-r--r--gcc/analyzer/known-function-manager.h28
-rw-r--r--gcc/analyzer/pending-diagnostic.cc64
-rw-r--r--gcc/analyzer/pending-diagnostic.h63
-rw-r--r--gcc/analyzer/program-point.cc1
-rw-r--r--gcc/analyzer/program-state.cc90
-rw-r--r--gcc/analyzer/program-state.h6
-rw-r--r--gcc/analyzer/region-model-asm.cc1
-rw-r--r--gcc/analyzer/region-model-impl-calls.cc1150
-rw-r--r--gcc/analyzer/region-model-manager.cc40
-rw-r--r--gcc/analyzer/region-model-manager.h9
-rw-r--r--gcc/analyzer/region-model-reachability.cc1
-rw-r--r--gcc/analyzer/region-model.cc1303
-rw-r--r--gcc/analyzer/region-model.h209
-rw-r--r--gcc/analyzer/region.cc35
-rw-r--r--gcc/analyzer/region.h62
-rw-r--r--gcc/analyzer/sm-fd.cc1532
-rw-r--r--gcc/analyzer/sm-fd.dot72
-rw-r--r--gcc/analyzer/sm-file.cc170
-rw-r--r--gcc/analyzer/sm-file.dot67
-rw-r--r--gcc/analyzer/sm-malloc.cc372
-rw-r--r--gcc/analyzer/sm-malloc.dot7
-rw-r--r--gcc/analyzer/sm-pattern-test.cc6
-rw-r--r--gcc/analyzer/sm-sensitive.cc5
-rw-r--r--gcc/analyzer/sm-signal.cc12
-rw-r--r--gcc/analyzer/sm-taint.cc205
-rw-r--r--gcc/analyzer/sm.cc10
-rw-r--r--gcc/analyzer/sm.h43
-rw-r--r--gcc/analyzer/state-purge.cc5
-rw-r--r--gcc/analyzer/store.cc57
-rw-r--r--gcc/analyzer/store.h10
-rw-r--r--gcc/analyzer/supergraph.cc1
-rw-r--r--gcc/analyzer/svalue.cc1
-rw-r--r--gcc/analyzer/trimmed-graph.cc1
-rw-r--r--gcc/analyzer/varargs.cc175
-rw-r--r--gcc/analyzer/varargs.dot56
-rw-r--r--gcc/asan.cc6
-rw-r--r--gcc/attribs.cc30
-rw-r--r--gcc/attribs.h2
-rw-r--r--gcc/builtins.cc11
-rw-r--r--gcc/c-family/ChangeLog127
-rw-r--r--gcc/c-family/c-attribs.cc5
-rw-r--r--gcc/c-family/c-common.cc8
-rw-r--r--gcc/c-family/c-common.def8
-rw-r--r--gcc/c-family/c-cppbuiltin.cc10
-rw-r--r--gcc/c-family/c-gimplify.cc4
-rw-r--r--gcc/c-family/c-lex.cc9
-rw-r--r--gcc/c-family/c-omp.cc9
-rw-r--r--gcc/c-family/c-opts.cc9
-rw-r--r--gcc/c-family/c-ppoutput.cc10
-rw-r--r--gcc/c-family/c-pragma.cc9
-rw-r--r--gcc/c-family/c.opt45
-rw-r--r--gcc/c/ChangeLog109
-rw-r--r--gcc/c/c-decl.cc311
-rw-r--r--gcc/c/c-parser.cc372
-rw-r--r--gcc/c/c-tree.h28
-rw-r--r--gcc/c/c-typeck.cc364
-rw-r--r--gcc/cfgbuild.cc49
-rw-r--r--gcc/cfghooks.cc1
-rw-r--r--gcc/cgraph.cc1
-rw-r--r--gcc/common.opt29
-rw-r--r--gcc/common/config/i386/cpuinfo.h32
-rw-r--r--gcc/common/config/i386/i386-common.cc89
-rw-r--r--gcc/common/config/i386/i386-cpuinfo.h7
-rw-r--r--gcc/common/config/i386/i386-isas.h4
-rw-r--r--gcc/common/config/riscv/riscv-common.cc4
-rw-r--r--gcc/config.gcc16
-rw-r--r--gcc/config/aarch64/aarch64-c.cc2
-rw-r--r--gcc/config/aarch64/aarch64-cores.def6
-rw-r--r--gcc/config/aarch64/aarch64-cost-tables.h107
-rw-r--r--gcc/config/aarch64/aarch64-fusion-pairs.def1
-rw-r--r--gcc/config/aarch64/aarch64-option-extensions.def2
-rw-r--r--gcc/config/aarch64/aarch64-protos.h10
-rw-r--r--gcc/config/aarch64/aarch64-simd.md145
-rw-r--r--gcc/config/aarch64/aarch64-sve-builtins-base.cc15
-rw-r--r--gcc/config/aarch64/aarch64-sve2.md45
-rw-r--r--gcc/config/aarch64/aarch64-tune.md2
-rw-r--r--gcc/config/aarch64/aarch64.cc440
-rw-r--r--gcc/config/aarch64/aarch64.h17
-rw-r--r--gcc/config/aarch64/aarch64.md188
-rw-r--r--gcc/config/aarch64/atomics.md55
-rw-r--r--gcc/config/aarch64/constraints.md15
-rw-r--r--gcc/config/aarch64/iterators.md36
-rw-r--r--gcc/config/aarch64/predicates.md18
-rw-r--r--gcc/config/arm/arm-cpus.in11
-rw-r--r--gcc/config/arm/arm-tables.opt3
-rw-r--r--gcc/config/arm/arm-tune.md2
-rw-r--r--gcc/config/arm/arm.cc33
-rw-r--r--gcc/config/arm/arm_mve.h1232
-rw-r--r--gcc/config/arm/mve.md58
-rw-r--r--gcc/config/arm/types.md10
-rw-r--r--gcc/config/arm/vfp.md8
-rw-r--r--gcc/config/bfin/bfin.h1
-rw-r--r--gcc/config/bpf/bpf.cc137
-rw-r--r--gcc/config/bpf/bpf.md17
-rw-r--r--gcc/config/gcn/gcn-builtins.def23
-rw-r--r--gcc/config/gcn/gcn-opts.h6
-rw-r--r--gcc/config/gcn/gcn-valu.md20
-rw-r--r--gcc/config/gcn/gcn.cc141
-rw-r--r--gcc/config/gcn/gcn.h40
-rw-r--r--gcc/config/gcn/gcn.md2
-rw-r--r--gcc/config/gcn/t-omp-device2
-rw-r--r--gcc/config/i386/amxfp16intrin.h (renamed from gcc/config/i386/intelmic-offload.h)27
-rw-r--r--gcc/config/i386/avx512bf16intrin.h4
-rw-r--r--gcc/config/i386/avx512fp16intrin.h44
-rw-r--r--gcc/config/i386/avx512fp16vlintrin.h34
-rw-r--r--gcc/config/i386/cmpccxaddintrin.h89
-rw-r--r--gcc/config/i386/cpuid.h4
-rw-r--r--gcc/config/i386/driver-i386.cc11
-rw-r--r--gcc/config/i386/i386-builtin-types.def9
-rw-r--r--gcc/config/i386/i386-builtin.def20
-rw-r--r--gcc/config/i386/i386-builtins.cc27
-rw-r--r--gcc/config/i386/i386-c.cc29
-rw-r--r--gcc/config/i386/i386-expand.cc266
-rw-r--r--gcc/config/i386/i386-isa.def4
-rw-r--r--gcc/config/i386/i386-options.cc62
-rw-r--r--gcc/config/i386/i386-opts.h6
-rw-r--r--gcc/config/i386/i386-protos.h3
-rw-r--r--gcc/config/i386/i386.cc173
-rw-r--r--gcc/config/i386/i386.h30
-rw-r--r--gcc/config/i386/i386.md226
-rw-r--r--gcc/config/i386/i386.opt41
-rw-r--r--gcc/config/i386/immintrin.h2
-rw-r--r--gcc/config/i386/intelmic-mkoffload.cc728
-rw-r--r--gcc/config/i386/mmx.md9
-rw-r--r--gcc/config/i386/predicates.md22
-rw-r--r--gcc/config/i386/prfchiintrin.h61
-rw-r--r--gcc/config/i386/raointintrin.h100
-rw-r--r--gcc/config/i386/smmintrin.h13
-rw-r--r--gcc/config/i386/sse.md16
-rw-r--r--gcc/config/i386/sync.md44
-rw-r--r--gcc/config/i386/t-intelmic10
-rw-r--r--gcc/config/i386/t-omp-device6
-rw-r--r--gcc/config/i386/x86-tune-costs.h60
-rw-r--r--gcc/config/i386/x86-tune.def78
-rw-r--r--gcc/config/i386/x86gprintrin.h6
-rw-r--r--gcc/config/i386/xmmintrin.h7
-rw-r--r--gcc/config/i386/znver.md67
-rw-r--r--gcc/config/loongarch/constraints.md10
-rw-r--r--gcc/config/loongarch/linux.h3
-rw-r--r--gcc/config/loongarch/loongarch-def.c2
-rw-r--r--gcc/config/loongarch/loongarch-tune.h1
-rw-r--r--gcc/config/loongarch/loongarch.cc345
-rw-r--r--gcc/config/loongarch/loongarch.h4
-rw-r--r--gcc/config/loongarch/loongarch.md173
-rw-r--r--gcc/config/loongarch/predicates.md2
-rw-r--r--gcc/config/loongarch/sync.md27
-rw-r--r--gcc/config/m68k/predicates.md2
-rw-r--r--gcc/config/mn10300/mn10300.cc6
-rw-r--r--gcc/config/nvptx/mkoffload.cc6
-rw-r--r--gcc/config/nvptx/nvptx.cc2
-rw-r--r--gcc/config/nvptx/nvptx.h2
-rw-r--r--gcc/config/pa/pa.md40
-rw-r--r--gcc/config/riscv/bitmanip.md274
-rw-r--r--gcc/config/riscv/constraints.md5
-rw-r--r--gcc/config/riscv/iterators.md12
-rw-r--r--gcc/config/riscv/predicates.md57
-rw-r--r--gcc/config/riscv/riscv-builtins.cc6
-rw-r--r--gcc/config/riscv/riscv-cores.def2
-rw-r--r--gcc/config/riscv/riscv-ftypes.def1
-rw-r--r--gcc/config/riscv/riscv-opts.h3
-rw-r--r--gcc/config/riscv/riscv-protos.h16
-rw-r--r--gcc/config/riscv/riscv-selftests.cc127
-rw-r--r--gcc/config/riscv/riscv-v.cc153
-rw-r--r--gcc/config/riscv/riscv-vector-switch.def97
-rw-r--r--gcc/config/riscv/riscv.cc450
-rw-r--r--gcc/config/riscv/riscv.h14
-rw-r--r--gcc/config/riscv/riscv.md62
-rw-r--r--gcc/config/riscv/riscv.opt3
-rw-r--r--gcc/config/riscv/vector-iterators.md32
-rw-r--r--gcc/config/riscv/vector.md372
-rw-r--r--gcc/config/rs6000/altivec.md2
-rw-r--r--gcc/config/rs6000/predicates.md2
-rw-r--r--gcc/config/rs6000/rs6000-call.cc10
-rw-r--r--gcc/config/rs6000/rs6000.cc102
-rw-r--r--gcc/config/rs6000/rs6000.md20
-rw-r--r--gcc/config/rs6000/vsx.md21
-rw-r--r--gcc/config/rtems.h4
-rw-r--r--gcc/config/sh/sh_treg_combine.cc5
-rw-r--r--gcc/config/xtensa/t-xtensa8
-rw-r--r--gcc/config/xtensa/xtensa-dynconfig.c170
-rw-r--r--gcc/config/xtensa/xtensa-protos.h1
-rw-r--r--gcc/config/xtensa/xtensa.h22
-rwxr-xr-xgcc/configure40
-rw-r--r--gcc/configure.ac30
-rw-r--r--gcc/cp/ChangeLog651
-rw-r--r--gcc/cp/Make-lang.in6
-rw-r--r--gcc/cp/call.cc407
-rw-r--r--gcc/cp/config-lang.in1
-rw-r--r--gcc/cp/constexpr.cc462
-rw-r--r--gcc/cp/constraint.cc126
-rw-r--r--gcc/cp/contracts.cc2241
-rw-r--r--gcc/cp/contracts.h305
-rw-r--r--gcc/cp/coroutines.cc1
-rw-r--r--gcc/cp/cp-gimplify.cc17
-rw-r--r--gcc/cp/cp-lang.cc3
-rw-r--r--gcc/cp/cp-objcp-common.cc42
-rw-r--r--gcc/cp/cp-objcp-common.h3
-rw-r--r--gcc/cp/cp-tree.def16
-rw-r--r--gcc/cp/cp-tree.h95
-rw-r--r--gcc/cp/decl.cc298
-rw-r--r--gcc/cp/decl2.cc23
-rw-r--r--gcc/cp/error.cc3
-rw-r--r--gcc/cp/g++spec.cc22
-rw-r--r--gcc/cp/init.cc65
-rw-r--r--gcc/cp/lambda.cc148
-rw-r--r--gcc/cp/mangle.cc15
-rw-r--r--gcc/cp/mapper-client.cc4
-rw-r--r--gcc/cp/method.cc10
-rw-r--r--gcc/cp/module.cc42
-rw-r--r--gcc/cp/parser.cc595
-rw-r--r--gcc/cp/parser.h3
-rw-r--r--gcc/cp/pt.cc592
-rw-r--r--gcc/cp/search.cc28
-rw-r--r--gcc/cp/semantics.cc49
-rw-r--r--gcc/cp/tree.cc136
-rw-r--r--gcc/cp/typeck.cc57
-rw-r--r--gcc/d/ChangeLog252
-rw-r--r--gcc/d/Make-lang.in18
-rw-r--r--gcc/d/d-target.cc6
-rw-r--r--gcc/d/decl.cc26
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/aggregate.d8
-rw-r--r--gcc/d/dmd/attrib.d14
-rw-r--r--gcc/d/dmd/blockexit.d4
-rw-r--r--gcc/d/dmd/canthrow.d2
-rw-r--r--gcc/d/dmd/clone.d20
-rw-r--r--gcc/d/dmd/cond.d6
-rw-r--r--gcc/d/dmd/constfold.d56
-rw-r--r--gcc/d/dmd/cparse.d8
-rw-r--r--gcc/d/dmd/cppmangle.d22
-rw-r--r--gcc/d/dmd/ctfeexpr.d86
-rw-r--r--gcc/d/dmd/dcast.d40
-rw-r--r--gcc/d/dmd/dclass.d29
-rw-r--r--gcc/d/dmd/declaration.d14
-rw-r--r--gcc/d/dmd/delegatize.d2
-rw-r--r--gcc/d/dmd/denum.d4
-rw-r--r--gcc/d/dmd/dimport.d12
-rw-r--r--gcc/d/dmd/dinterpret.d136
-rw-r--r--gcc/d/dmd/dmangle.d12
-rw-r--r--gcc/d/dmd/dmodule.d30
-rw-r--r--gcc/d/dmd/doc.d54
-rw-r--r--gcc/d/dmd/dscope.d29
-rw-r--r--gcc/d/dmd/dstruct.d14
-rw-r--r--gcc/d/dmd/dsymbol.d48
-rw-r--r--gcc/d/dmd/dsymbolsem.d169
-rw-r--r--gcc/d/dmd/dtemplate.d288
-rw-r--r--gcc/d/dmd/dtoh.d4
-rw-r--r--gcc/d/dmd/escape.d73
-rw-r--r--gcc/d/dmd/expression.d78
-rw-r--r--gcc/d/dmd/expressionsem.d192
-rw-r--r--gcc/d/dmd/file_manager.d138
-rw-r--r--gcc/d/dmd/func.d118
-rw-r--r--gcc/d/dmd/hdrgen.d48
-rw-r--r--gcc/d/dmd/iasmgcc.d6
-rw-r--r--gcc/d/dmd/init.d16
-rw-r--r--gcc/d/dmd/initsem.d28
-rw-r--r--gcc/d/dmd/json.d30
-rw-r--r--gcc/d/dmd/lambdacomp.d2
-rw-r--r--gcc/d/dmd/lexer.d56
-rw-r--r--gcc/d/dmd/mtype.d36
-rw-r--r--gcc/d/dmd/nogc.d10
-rw-r--r--gcc/d/dmd/ob.d2
-rw-r--r--gcc/d/dmd/objc.d4
-rw-r--r--gcc/d/dmd/opover.d34
-rw-r--r--gcc/d/dmd/optimize.d4
-rw-r--r--gcc/d/dmd/parse.d78
-rw-r--r--gcc/d/dmd/root/array.d4
-rw-r--r--gcc/d/dmd/root/filename.d2
-rw-r--r--gcc/d/dmd/root/utf.d20
-rw-r--r--gcc/d/dmd/sapply.d6
-rw-r--r--gcc/d/dmd/scope.h78
-rw-r--r--gcc/d/dmd/semantic2.d14
-rw-r--r--gcc/d/dmd/semantic3.d24
-rw-r--r--gcc/d/dmd/statement.d12
-rw-r--r--gcc/d/dmd/statement_rewrite_walker.d12
-rw-r--r--gcc/d/dmd/statementsem.d141
-rw-r--r--gcc/d/dmd/traits.d50
-rw-r--r--gcc/d/dmd/transitivevisitor.d8
-rw-r--r--gcc/d/dmd/typesem.d70
-rw-r--r--gcc/d/gdc.texi271
-rw-r--r--gcc/d/implement-d.texi2514
-rw-r--r--gcc/d/imports.cc14
-rw-r--r--gcc/d/intrinsics.cc82
-rw-r--r--gcc/d/intrinsics.def8
-rw-r--r--gcc/d/lang.opt2
-rw-r--r--gcc/d/toir.cc26
-rw-r--r--gcc/d/typeinfo.cc13
-rw-r--r--gcc/dfp.cc6
-rw-r--r--gcc/diagnostic-path.h3
-rw-r--r--gcc/diagnostic-spec.cc1
-rw-r--r--gcc/diagnostic.cc44
-rw-r--r--gcc/doc/analyzer.texi27
-rw-r--r--gcc/doc/contrib.texi2
-rw-r--r--gcc/doc/cpp.texi4
-rw-r--r--gcc/doc/cppopts.texi7
-rw-r--r--gcc/doc/extend.texi282
-rw-r--r--gcc/doc/gimple.texi3
-rw-r--r--gcc/doc/install.texi9
-rw-r--r--gcc/doc/invoke.texi805
-rw-r--r--gcc/doc/md.texi7
-rw-r--r--gcc/doc/sourcebuild.texi18
-rw-r--r--gcc/doc/tm.texi18
-rw-r--r--gcc/doc/tm.texi.in2
-rw-r--r--gcc/dojump.cc52
-rw-r--r--gcc/dojump.h4
-rw-r--r--gcc/explow.cc4
-rw-r--r--gcc/expmed.cc23
-rw-r--r--gcc/expmed.h5
-rw-r--r--gcc/expr.cc50
-rw-r--r--gcc/file-prefix-map.cc16
-rw-r--r--gcc/flag-types.h9
-rw-r--r--gcc/fold-const.cc39
-rw-r--r--gcc/fortran/ChangeLog2748
-rw-r--r--gcc/fortran/arith.cc31
-rw-r--r--gcc/fortran/array.cc19
-rw-r--r--gcc/fortran/cpp.cc2
-rw-r--r--gcc/fortran/dump-parse-tree.cc23
-rw-r--r--gcc/fortran/error.cc4
-rw-r--r--gcc/fortran/f95-lang.cc2
-rw-r--r--gcc/fortran/gfortran.h4
-rw-r--r--gcc/fortran/gfortran.texi3
-rw-r--r--gcc/fortran/interface.cc64
-rw-r--r--gcc/fortran/intrinsic.texi60
-rw-r--r--gcc/fortran/io.cc2
-rw-r--r--gcc/fortran/match.cc6
-rw-r--r--gcc/fortran/openmp.cc211
-rw-r--r--gcc/fortran/parse.cc33
-rw-r--r--gcc/fortran/primary.cc6
-rw-r--r--gcc/fortran/resolve.cc21
-rw-r--r--gcc/fortran/simplify.cc31
-rw-r--r--gcc/fortran/st.cc2
-rw-r--r--gcc/fortran/symbol.cc6
-rw-r--r--gcc/fortran/trans-array.cc57
-rw-r--r--gcc/fortran/trans-decl.cc33
-rw-r--r--gcc/fortran/trans-expr.cc31
-rw-r--r--gcc/fortran/trans-intrinsic.cc3
-rw-r--r--gcc/fortran/trans-openmp.cc19
-rw-r--r--gcc/fortran/trans-stmt.cc1
-rw-r--r--gcc/fortran/trans-types.cc25
-rw-r--r--gcc/function.cc19
-rw-r--r--gcc/gcc.cc24
-rw-r--r--gcc/generic-match-head.cc1
-rw-r--r--gcc/genmatch.cc10
-rw-r--r--gcc/genmultilib8
-rw-r--r--gcc/gimple-array-bounds.cc202
-rw-r--r--gcc/gimple-fold.cc99
-rw-r--r--gcc/gimple-fold.h1
-rw-r--r--gcc/gimple-low.cc41
-rw-r--r--gcc/gimple-match-head.cc1
-rw-r--r--gcc/gimple-predicate-analysis.cc176
-rw-r--r--gcc/gimple-predicate-analysis.h23
-rw-r--r--gcc/gimple-pretty-print.cc1
-rw-r--r--gcc/gimple-range-cache.cc36
-rw-r--r--gcc/gimple-range-cache.h1
-rw-r--r--gcc/gimple-range-infer.cc11
-rw-r--r--gcc/gimple-range-infer.h1
-rw-r--r--gcc/gimple-range-op.cc6
-rw-r--r--gcc/gimple-range.cc106
-rw-r--r--gcc/gimple-range.h2
-rw-r--r--gcc/gimple-ssa-sprintf.cc41
-rw-r--r--gcc/gimple-ssa-warn-access.cc52
-rw-r--r--gcc/gimple-ssa-warn-alloca.cc1
-rw-r--r--gcc/gimple-ssa-warn-restrict.cc7
-rw-r--r--gcc/gimple.cc1
-rw-r--r--gcc/gimplify.cc11
-rw-r--r--gcc/ginclude/float.h4
-rw-r--r--gcc/ginclude/stdarg.h4
-rw-r--r--gcc/ginclude/stdatomic.h4
-rw-r--r--gcc/ginclude/stddef.h1
-rw-r--r--gcc/ginclude/stdint-gcc.h4
-rw-r--r--gcc/glimits.h2
-rw-r--r--gcc/go/ChangeLog161
-rw-r--r--gcc/go/go-gcc.cc12
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/graphite-sese-to-poly.cc4
-rw-r--r--gcc/input.cc102
-rw-r--r--gcc/input.h4
-rw-r--r--gcc/ipa-cp.cc26
-rw-r--r--gcc/ipa-param-manipulation.cc29
-rw-r--r--gcc/ipa-param-manipulation.h4
-rw-r--r--gcc/ipa-pure-const.cc5
-rw-r--r--gcc/ipa-sra.cc7
-rw-r--r--gcc/ira-build.cc2
-rw-r--r--gcc/ira-color.cc5
-rw-r--r--gcc/jit/ChangeLog335
-rw-r--r--gcc/jit/jit-playback.cc69
-rw-r--r--gcc/jit/jit-playback.h7
-rw-r--r--gcc/jit/jit-recording.cc4
-rw-r--r--gcc/jit/jit-recording.h18
-rw-r--r--gcc/jit/libgccjit.cc7
-rw-r--r--gcc/json.cc23
-rw-r--r--gcc/json.h5
-rw-r--r--gcc/loop-init.cc3
-rw-r--r--gcc/lra-constraints.cc13
-rw-r--r--gcc/lto/ChangeLog22
-rw-r--r--gcc/lto/lto.cc14
-rw-r--r--gcc/m2/ChangeLog5
-rw-r--r--gcc/make-unique.h44
-rw-r--r--gcc/match.pd313
-rw-r--r--gcc/multiple_target.cc16
-rw-r--r--gcc/objcp/ChangeLog10
-rw-r--r--gcc/objcp/objcp-lang.cc8
-rw-r--r--gcc/omp-simd-clone.cc309
-rw-r--r--gcc/optabs.cc148
-rw-r--r--gcc/optabs.def2
-rw-r--r--gcc/optabs.h4
-rw-r--r--gcc/opts.cc6
-rw-r--r--gcc/params.opt25
-rw-r--r--gcc/passes.def8
-rw-r--r--gcc/pointer-query.cc26
-rw-r--r--gcc/pointer-query.h5
-rw-r--r--gcc/range-op-float.cc861
-rw-r--r--gcc/range-op.cc186
-rw-r--r--gcc/range-op.h13
-rw-r--r--gcc/real.cc28
-rw-r--r--gcc/real.h7
-rw-r--r--gcc/reg-stack.cc86
-rw-r--r--gcc/rust/ChangeLog6
-rw-r--r--gcc/rust/backend/rust-tree.cc2
-rw-r--r--gcc/sanopt.cc42
-rw-r--r--gcc/system.h6
-rw-r--r--gcc/target-def.h4
-rw-r--r--gcc/target.def21
-rw-r--r--gcc/target.h1
-rw-r--r--gcc/targhooks.cc73
-rw-r--r--gcc/targhooks.h7
-rw-r--r--gcc/testsuite/ChangeLog4167
-rw-r--r--gcc/testsuite/c-c++-common/asan/global-overflow-1.c2
-rw-r--r--gcc/testsuite/c-c++-common/asan/heap-overflow-1.c2
-rw-r--r--gcc/testsuite/c-c++-common/asan/pr106558.c23
-rw-r--r--gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c2
-rw-r--r--gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c2
-rw-r--r--gcc/testsuite/c-c++-common/auto-init-1.c2
-rw-r--r--gcc/testsuite/c-c++-common/auto-init-2.c2
-rw-r--r--gcc/testsuite/c-c++-common/cpp/macro-trace-1.c4
-rw-r--r--gcc/testsuite/c-c++-common/cpp/named-universal-char-escape-1.c24
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pragma-omp-unknown.c10
-rw-r--r--gcc/testsuite/c-c++-common/gomp/target-teams-1.c2
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/heap-overflow.c2
-rw-r--r--gcc/testsuite/c-c++-common/pr57371-4.c8
-rw-r--r--gcc/testsuite/c-c++-common/pr57371-5.c47
-rw-r--r--gcc/testsuite/c-c++-common/pragma-region.c11
-rw-r--r--gcc/testsuite/c-c++-common/raw-string-directive-1.c74
-rw-r--r--gcc/testsuite/c-c++-common/raw-string-directive-2.c33
-rw-r--r--gcc/testsuite/g++.dg/DRs/dr2392.C12
-rw-r--r--gcc/testsuite/g++.dg/DRs/dr2583.C45
-rw-r--r--gcc/testsuite/g++.dg/DRs/dr2604.C53
-rw-r--r--gcc/testsuite/g++.dg/abi/lambda-sig1-18.C34
-rw-r--r--gcc/testsuite/g++.dg/abi/lambda-sig1-18vs17.C40
-rw-r--r--gcc/testsuite/g++.dg/abi/lambda-tpl1-17.C6
-rw-r--r--gcc/testsuite/g++.dg/abi/lambda-tpl1-18.C6
-rw-r--r--gcc/testsuite/g++.dg/abi/lambda-tpl1-18vs17.C5
-rw-r--r--gcc/testsuite/g++.dg/abi/lambda-tpl1.h11
-rw-r--r--gcc/testsuite/g++.dg/analyzer/fd-bind-pr107783.C11
-rw-r--r--gcc/testsuite/g++.dg/analyzer/infinite-recursion-1.C84
-rw-r--r--gcc/testsuite/g++.dg/analyzer/infinite-recursion-2.C74
-rw-r--r--gcc/testsuite/g++.dg/analyzer/infinite-recursion-3.C62
-rw-r--r--gcc/testsuite/g++.dg/analyzer/named-functions.C12
-rw-r--r--gcc/testsuite/g++.dg/analyzer/pr108003.C37
-rw-r--r--gcc/testsuite/g++.dg/asan/asan_mem_test.cc20
-rw-r--r--gcc/testsuite/g++.dg/asan/asan_oob_test.cc12
-rw-r--r--gcc/testsuite/g++.dg/asan/asan_str_test.cc4
-rw-r--r--gcc/testsuite/g++.dg/asan/asan_test.cc36
-rw-r--r--gcc/testsuite/g++.dg/asan/large-func-test-1.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/auto1.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/auto3.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/auto4.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/class-deduction1.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/class5.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/class6.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/debug1.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/decl-diagnose.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/deduction-constraint1.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/diagnostic1.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/dr1430.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/equiv.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/equiv2.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/explicit-spec1a.C11
-rw-r--r--gcc/testsuite/g++.dg/concepts/expression.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/expression2.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/expression3.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/fn-concept1.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/fn-concept2.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/fn-concept3.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/fn1.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/fn10.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/fn2.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/fn3.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/fn4.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/fn5.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/fn6.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/fn8.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/fn9.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/generic-fn-err.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/generic-fn.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/inherit-ctor1.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/inherit-ctor3.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/intro1.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/intro2.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/intro3.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/intro4.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/intro5.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/intro6.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/intro7.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/locations1.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/partial-concept-id1.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/partial-concept-id2.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/partial-spec5.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/placeholder2.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/placeholder3.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/placeholder4.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/placeholder5.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/placeholder6.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr65634.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr65636.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr65681.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr65848.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr67249.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr67595.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr68434.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr71127.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr71128.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr71131.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr71385.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr85065.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/template-parm11.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/template-parm12.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/template-parm2.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/template-parm3.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/template-parm4.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/template-template-parm1.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/var-concept1.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/var-concept2.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/var-concept3.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/var-concept4.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/var-concept5.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/var-concept6.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/var-concept7.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/var-templ2.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/var-templ3.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/variadic1.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/variadic2.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/variadic3.C2
-rw-r--r--gcc/testsuite/g++.dg/concepts/variadic4.C2
-rw-r--r--gcc/testsuite/g++.dg/contracts/backtrace_handler/Makefile13
-rw-r--r--gcc/testsuite/g++.dg/contracts/backtrace_handler/README12
-rw-r--r--gcc/testsuite/g++.dg/contracts/backtrace_handler/assert_fail.cpp23
-rw-r--r--gcc/testsuite/g++.dg/contracts/backtrace_handler/example_out.txt12
-rw-r--r--gcc/testsuite/g++.dg/contracts/backtrace_handler/example_pretty.txt8
-rw-r--r--gcc/testsuite/g++.dg/contracts/backtrace_handler/handle_contract_violation.cpp26
-rwxr-xr-xgcc/testsuite/g++.dg/contracts/backtrace_handler/prettytrace.sh30
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-access1.C128
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-assume1.C30
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-assume2.C34
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-assume3.C19
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-assume4.C19
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-assume5.C34
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-assume6.C61
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-comdat1.C19
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-config1.C36
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-constexpr1.C74
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-constexpr2.C58
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-constexpr3.C10
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-conversion1.C19
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-ctor-dtor1.C177
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-ctor-dtor2.C35
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-cv1.C37
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-deduced1.C108
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-deduced2.C84
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-friend1.C40
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-ft1.C14
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-ignore1.C30
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-ignore2.C26
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-large-return.C15
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-multiline1.C19
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-multiple-inheritance1.C15
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-multiple-inheritance2.C33
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-nested-class1.C24
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-nested-class2.C40
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-nocopy1.C24
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-override.C43
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-post1.C74
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-post2.C13
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-post3.C15
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-post4.C36
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-post5.C19
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-post6.C30
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-pre1.C36
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-pre10.C190
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-pre2.C212
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-pre2a1.C33
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-pre2a2.C22
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-pre3.C525
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-pre4.C92
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-pre5.C81
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-pre6.C74
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-pre7.C134
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-pre9.C146
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-redecl1.C149
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-redecl2.C149
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-redecl3.C195
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-redecl4.C56
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-redecl5.C101
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-redecl6.C195
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-redecl7.C95
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-redecl8.C64
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-tmpl-attr1.C19
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec1.C121
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec2.C395
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec3.C45
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts1.C49
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts10.C73
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts11.C103
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts12.C15
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts13.C51
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts14.C58
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts15.C56
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts16.C34
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts17.C35
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts18.C15
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts19.C19
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts2.C13
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts20.C11
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts22.C32
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts24.C15
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts25.C57
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts3.C13
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts35.C47
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts4.C11
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts5.C13
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts6.C11
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts7.C14
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts8.C43
-rw-r--r--gcc/testsuite/g++.dg/contracts/contracts9.C45
-rw-r--r--gcc/testsuite/g++.dg/contracts/except_preload_handler/Makefile13
-rw-r--r--gcc/testsuite/g++.dg/contracts/except_preload_handler/README13
-rw-r--r--gcc/testsuite/g++.dg/contracts/except_preload_handler/assert_fail.cpp20
-rw-r--r--gcc/testsuite/g++.dg/contracts/except_preload_handler/handle_contract_violation.cpp14
-rw-r--r--gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/Makefile13
-rw-r--r--gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/README15
-rw-r--r--gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/assert_fail.cpp20
-rw-r--r--gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/handle_contract_violation.cpp14
-rw-r--r--gcc/testsuite/g++.dg/contracts/preload_handler/Makefile13
-rw-r--r--gcc/testsuite/g++.dg/contracts/preload_handler/README2
-rw-r--r--gcc/testsuite/g++.dg/contracts/preload_handler/assert_fail.cpp7
-rw-r--r--gcc/testsuite/g++.dg/contracts/preload_handler/handle_contract_violation.cpp15
-rw-r--r--gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/Makefile23
-rw-r--r--gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/README23
-rw-r--r--gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/assert_fail.cpp10
-rw-r--r--gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/handle_contract_violation.cpp13
-rw-r--r--gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/nocontinue.cpp19
-rw-r--r--gcc/testsuite/g++.dg/coroutines/pr100611.C94
-rw-r--r--gcc/testsuite/g++.dg/coroutines/pr101367.C72
-rw-r--r--gcc/testsuite/g++.dg/coroutines/pr101976.C78
-rw-r--r--gcc/testsuite/g++.dg/coroutines/pr99576_1.C124
-rw-r--r--gcc/testsuite/g++.dg/coroutines/pr99576_2.C72
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/Wredundant-move13.C61
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/attr-carries_dependency1.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ctor2.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-default-ctor.C6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-friend.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-generated1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ice5.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ice6.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-neg2.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-non-const-arg.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted3.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr65327.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-105050.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-89285-2.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-89785-2.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-neg1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-nsdmi7b.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C6
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1-18.C26
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/new1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/decomp56.C29
-rw-r--r--gcc/testsuite/g++.dg/cpp23/charset1.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit10.C96
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit11.C53
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit12.C24
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit13.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit14.C26
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit15.C35
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit16.C23
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit17.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit18.C49
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit3.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit6.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit8.C96
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit9.C53
-rw-r--r--gcc/testsuite/g++.dg/cpp23/elision4.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp23/static-operator-call4.C37
-rw-r--r--gcc/testsuite/g++.dg/cpp23/subscript10.C46
-rw-r--r--gcc/testsuite/g++.dg/cpp23/subscript11.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp23/subscript9.C29
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/bit-cast7.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-dr2428.C22
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-friend11.C21
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-placeholder10.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-placeholder7.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-placeholder8.C5
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-placeholder9.C33
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-pr65575.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-pr66091.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-pr84979-2.C5
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-pr84979-3.C5
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-pr84980.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-pr85265.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-requires31.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-requires32.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-requires33.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/consteval3.C1
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-new7.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-try5.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-virtual21.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constinit18.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/decomp5.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/decomp6.C20
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/decomp7.C20
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/spaceship-eq15.C208
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C5
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite5.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/spaceship-sfinae2.C29
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/using-enum-10.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/using-enum-10a.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/volatile1.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/volatile3.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/volatile5.C2
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/constexpr1.C2
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/return-type-loc1.C20
-rw-r--r--gcc/testsuite/g++.dg/ext/stmtexpr19.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/stmtexpr25.C17
-rw-r--r--gcc/testsuite/g++.dg/ext/vector25.C2
-rw-r--r--gcc/testsuite/g++.dg/gcov/gcov.exp4
-rw-r--r--gcc/testsuite/g++.dg/gomp/for-21.C18
-rw-r--r--gcc/testsuite/g++.dg/gomp/for-22.C57
-rw-r--r--gcc/testsuite/g++.dg/gomp/pr79664.C2
-rw-r--r--gcc/testsuite/g++.dg/gomp/pr84469.C24
-rw-r--r--gcc/testsuite/g++.dg/gomp/target-simd-clone-1.C25
-rw-r--r--gcc/testsuite/g++.dg/gomp/target-simd-clone-2.C23
-rw-r--r--gcc/testsuite/g++.dg/gomp/target-teams-1.C2
-rw-r--r--gcc/testsuite/g++.dg/guality/guality.exp4
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr107661.C45
-rw-r--r--gcc/testsuite/g++.dg/modules/bad-mapper-3.C2
-rw-r--r--gcc/testsuite/g++.dg/modules/contracts-1_a.C46
-rw-r--r--gcc/testsuite/g++.dg/modules/contracts-1_b.C33
-rw-r--r--gcc/testsuite/g++.dg/modules/contracts-2_a.C49
-rw-r--r--gcc/testsuite/g++.dg/modules/contracts-2_b.C35
-rw-r--r--gcc/testsuite/g++.dg/modules/contracts-2_c.C22
-rw-r--r--gcc/testsuite/g++.dg/modules/contracts-3_a.C41
-rw-r--r--gcc/testsuite/g++.dg/modules/contracts-3_b.C35
-rw-r--r--gcc/testsuite/g++.dg/modules/contracts-4_a.C28
-rw-r--r--gcc/testsuite/g++.dg/modules/contracts-4_b.C8
-rw-r--r--gcc/testsuite/g++.dg/modules/contracts-4_c.C9
-rw-r--r--gcc/testsuite/g++.dg/modules/contracts-4_d.C22
-rw-r--r--gcc/testsuite/g++.dg/modules/contracts-tpl-friend-1_a.C17
-rw-r--r--gcc/testsuite/g++.dg/modules/contracts-tpl-friend-1_b.C19
-rw-r--r--gcc/testsuite/g++.dg/modules/modules.exp40
-rw-r--r--gcc/testsuite/g++.dg/modules/pr99023_b.X2
-rw-r--r--gcc/testsuite/g++.dg/other/i386-2.C2
-rw-r--r--gcc/testsuite/g++.dg/other/i386-3.C2
-rw-r--r--gcc/testsuite/g++.dg/pr107803.C19
-rw-r--r--gcc/testsuite/g++.dg/pr107867.C19
-rw-r--r--gcc/testsuite/g++.dg/pr107985.C18
-rw-r--r--gcc/testsuite/g++.dg/pr93195a.C1
-rw-r--r--gcc/testsuite/g++.dg/pr99966.C23
-rw-r--r--gcc/testsuite/g++.dg/special/initpri3.C10
-rw-r--r--gcc/testsuite/g++.dg/template/canon-type-19.C18
-rw-r--r--gcc/testsuite/g++.dg/template/crash55.C3
-rw-r--r--gcc/testsuite/g++.dg/template/ref3.C3
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/allocator-opt1.C12
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/initlist-opt1.C25
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr106922.C4
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr107876.C38
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C2
-rw-r--r--gcc/testsuite/g++.dg/ubsan/vptr-4.C2
-rw-r--r--gcc/testsuite/g++.dg/vect/pr107766.cc23
-rw-r--r--gcc/testsuite/g++.dg/warn/Warray-bounds-pr104165-1.C27
-rw-r--r--gcc/testsuite/g++.dg/warn/Wdangling-reference1.C4
-rw-r--r--gcc/testsuite/g++.dg/warn/Wdangling-reference6.C38
-rw-r--r--gcc/testsuite/g++.dg/warn/Wdangling-reference7.C16
-rw-r--r--gcc/testsuite/g++.dg/warn/Wignored-qualifiers3.C24
-rw-r--r--gcc/testsuite/g++.dg/warn/Wuninitialized-pr107919-1.C15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900210_10.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/byval2.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/overload13.C2
-rw-r--r--gcc/testsuite/g++.target/aarch64/sve/pr107920.C19
-rw-r--r--gcc/testsuite/g++.target/i386/mv16.C18
-rw-r--r--gcc/testsuite/g++.target/i386/pr102566-7.C22
-rw-r--r--gcc/testsuite/g++.target/i386/pr106875.C5
-rw-r--r--gcc/testsuite/g++.target/i386/pr107404.C53
-rw-r--r--gcc/testsuite/g++.target/powerpc/pr90259.C103
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr107835.c11
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr107997.c23
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-6.x1
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-9.c31
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-9.x16
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp3
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/inf-4.c26
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr107879.c25
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-11.c2
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-34.c2
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-43.c6
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-48.c11
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c39
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c39
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c39
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c39
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c39
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c39
-rw-r--r--gcc/testsuite/gcc.dg/Wdangling-pointer-pr106868.c14
-rw-r--r--gcc/testsuite/gcc.dg/Wformat-overflow1.c28
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-pr106904.c30
-rw-r--r--gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c11
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/CWE-131-examples.c146
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/aliasing-pr106473.c5
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c3
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/allocation-size-3.c3
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/allocation-size-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-1.c59
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-2.c62
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/analyzer-debugging-fns-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h3
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/attr-const-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/attr-nonnull-pr106325.c250
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/attribute-nonnull.c18
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c5
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/call-summaries-errno.c17
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-23.c11
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/deref-before-check-1.c169
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/deref-before-check-2.c130
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr77425.c43
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/errno-1.c23
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/errno-___errno.c29
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/errno-__error.c28
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/errno-global-var.c26
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/errno-pr107777.c20
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/explode-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/explode-3.c43
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-4.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-accept.c76
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-access-mode-enum.c60
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-access-mode-macros.c (renamed from gcc/testsuite/gcc.dg/analyzer/fd-5.c)1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-access-mode-target-headers.c56
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-bind-pr107783.c5
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-bind-pr107928.c10
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-bind.c81
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-connect-pr107928.c10
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-connect.c53
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-datagram-socket.c110
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-dup-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-glibc-byte-stream-connection-server.c134
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-glibc-byte-stream-socket.c63
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-client.c57
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-socket.c53
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-glibc-make_named_socket.h47
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-listen.c70
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-manpage-getaddrinfo-client.c123
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-mappage-getaddrinfo-server.c121
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-socket-meaning.c22
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-socket-misuse.c100
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-active-open.c107
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-passive-open.c297
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-stream-socket.c100
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-symbolic-socket.c100
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fdump-analyzer-1.c14
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/feasibility-4.c42
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/feasibility-pr107582-1.c43
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/feasibility-pr107582-2.c34
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/feasibility-pr107948.c49
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/ferror-1.c6
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/file-CWE-1341-example.c41
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fileno-1.c6
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/flex-with-call-summaries.c1683
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/flex-without-call-summaries.c1680
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/getc-1.c6
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/infinite-recursion-2.c109
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/infinite-recursion-3.c18
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-limited-buggy.c25
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-limited.c22
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-unlimited-buggy.c23
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-unlimited.c22
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/infinite-recursion-5.c221
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/infinite-recursion-alloca.c27
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/infinite-recursion-inlining.c116
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/infinite-recursion-multiline-1.c41
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/infinite-recursion-multiline-2.c93
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/infinite-recursion-variadic.c34
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/infinite-recursion.c10
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/isatty-1.c56
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-1.c9
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-CWE-401-example.c37
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-CWE-415-examples.c53
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-CWE-416-examples.c60
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-CWE-590-examples.c44
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-ipa-12.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-reuse.c58
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/memcpy-1.c14
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/memcpy-pr107882.c8
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/memmove-1.c182
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/named-constants-Wunused-macros.c19
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/named-constants-via-command-line.c10
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/named-constants-via-enum-and-macro.c12
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/named-constants-via-enum.c20
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-2.c15
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-3.c15
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-4.c15
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-empty.c14
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-gc.c21
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-traditional.c16
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-undef.c18
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros.c19
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-1.c20
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-2.c15
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-3.c27
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-4.c15
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-5.c22
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-container_of.c4
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-multiline-1.c37
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-multiline-2.c32
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-char-arr.c47
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-int-arr.c28
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-struct-arr.c65
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-char-arr.c41
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-int-arr.c22
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-struct-arr.c65
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pipe-pr107486.c5
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pipe-void-return.c11
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr101962.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr104308.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr104369-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr104369-2.c3
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr105365.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr105366.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr97029.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/realloc-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/strchr-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/string-ops-concat-pair.c67
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c61
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/taint-assert-BUG_ON.c76
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/taint-assert-macro-expansion.c96
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/taint-assert-system-header.c52
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/taint-assert.c346
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/test-assert.h7
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/torture/fold-ptr-arith-pr105784.c43
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/zlib-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/asan/pr107317.c13
-rw-r--r--gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c55
-rw-r--r--gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/builtin-object-size-1.c94
-rw-r--r--gcc/testsuite/gcc.dg/builtin-object-size-2.c94
-rw-r--r--gcc/testsuite/gcc.dg/builtin-object-size-3.c95
-rw-r--r--gcc/testsuite/gcc.dg/builtin-object-size-4.c94
-rw-r--r--gcc/testsuite/gcc.dg/c11-float-8.c9
-rw-r--r--gcc/testsuite/gcc.dg/c11-keywords-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/c11-limits-1.c9
-rw-r--r--gcc/testsuite/gcc.dg/c11-stdarg-4.c9
-rw-r--r--gcc/testsuite/gcc.dg/c11-stdatomic-3.c9
-rw-r--r--gcc/testsuite/gcc.dg/c11-stddef-1.c9
-rw-r--r--gcc/testsuite/gcc.dg/c11-stdint-1.c9
-rw-r--r--gcc/testsuite/gcc.dg/c2x-auto-1.c81
-rw-r--r--gcc/testsuite/gcc.dg/c2x-auto-2.c38
-rw-r--r--gcc/testsuite/gcc.dg/c2x-auto-3.c64
-rw-r--r--gcc/testsuite/gcc.dg/c2x-auto-4.c5
-rw-r--r--gcc/testsuite/gcc.dg/c2x-constexpr-1.c312
-rw-r--r--gcc/testsuite/gcc.dg/c2x-constexpr-2a.c37
-rw-r--r--gcc/testsuite/gcc.dg/c2x-constexpr-2b.c6
-rw-r--r--gcc/testsuite/gcc.dg/c2x-constexpr-3.c236
-rw-r--r--gcc/testsuite/gcc.dg/c2x-constexpr-4.c21
-rw-r--r--gcc/testsuite/gcc.dg/c2x-constexpr-5.c21
-rw-r--r--gcc/testsuite/gcc.dg/c2x-constexpr-6.c15
-rw-r--r--gcc/testsuite/gcc.dg/c2x-constexpr-7.c13
-rw-r--r--gcc/testsuite/gcc.dg/c2x-constexpr-8.c23
-rw-r--r--gcc/testsuite/gcc.dg/c2x-constexpr-9.c39
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-13.c13
-rw-r--r--gcc/testsuite/gcc.dg/c2x-limits-1.c13
-rw-r--r--gcc/testsuite/gcc.dg/c2x-stdarg-5.c13
-rw-r--r--gcc/testsuite/gcc.dg/c2x-stdatomic-1.c13
-rw-r--r--gcc/testsuite/gcc.dg/c2x-stddef-1.c13
-rw-r--r--gcc/testsuite/gcc.dg/c2x-stdint-1.c13
-rw-r--r--gcc/testsuite/gcc.dg/c90-auto-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/cpp/c11-vararg-1.c9
-rw-r--r--gcc/testsuite/gcc.dg/cpp/c2x-va-opt-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/c2x-constexpr-dfp-1.c79
-rw-r--r--gcc/testsuite/gcc.dg/dfp/c2x-constexpr-dfp-2.c48
-rw-r--r--gcc/testsuite/gcc.dg/gnu2x-auto-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/gnu2x-constexpr-1.c17
-rw-r--r--gcc/testsuite/gcc.dg/gomp/target-simd-clone-1.c25
-rw-r--r--gcc/testsuite/gcc.dg/gomp/target-simd-clone-2.c22
-rw-r--r--gcc/testsuite/gcc.dg/gomp/target-simd-clone-3.c22
-rw-r--r--gcc/testsuite/gcc.dg/gomp/target-simd-clone-4.c26
-rw-r--r--gcc/testsuite/gcc.dg/gomp/target-simd-clone-5.c28
-rw-r--r--gcc/testsuite/gcc.dg/gomp/target-simd-clone-6.c27
-rw-r--r--gcc/testsuite/gcc.dg/gomp/target-simd-clone-7.c15
-rw-r--r--gcc/testsuite/gcc.dg/gomp/target-simd-clone-8.c25
-rw-r--r--gcc/testsuite/gcc.dg/guality/guality.exp4
-rw-r--r--gcc/testsuite/gcc.dg/guality/param-6.c20
-rw-r--r--gcc/testsuite/gcc.dg/ipa/iinline-attr.c4
-rw-r--r--gcc/testsuite/gcc.dg/loop-unswitch-18.c13
-rw-r--r--gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c18
-rw-r--r--gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.c17
-rw-r--r--gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.c22
-rw-r--r--gcc/testsuite/gcc.dg/pr102650.c20
-rw-r--r--gcc/testsuite/gcc.dg/pr103356-1.c9
-rw-r--r--gcc/testsuite/gcc.dg/pr104530.c19
-rw-r--r--gcc/testsuite/gcc.dg/pr105676.c14
-rw-r--r--gcc/testsuite/gcc.dg/pr106719.c13
-rw-r--r--gcc/testsuite/gcc.dg/pr107127.c13
-rw-r--r--gcc/testsuite/gcc.dg/pr107389.c13
-rw-r--r--gcc/testsuite/gcc.dg/pr107505.c26
-rw-r--r--gcc/testsuite/gcc.dg/pr107523.c32
-rw-r--r--gcc/testsuite/gcc.dg/pr107547.c40
-rw-r--r--gcc/testsuite/gcc.dg/pr107554.c12
-rw-r--r--gcc/testsuite/gcc.dg/pr107585.c13
-rw-r--r--gcc/testsuite/gcc.dg/pr107618.c10
-rw-r--r--gcc/testsuite/gcc.dg/pr107686.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr107787.c13
-rw-r--r--gcc/testsuite/gcc.dg/pr107805-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/pr107805-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr107937.c24
-rw-r--r--gcc/testsuite/gcc.dg/pr107967-1.c35
-rw-r--r--gcc/testsuite/gcc.dg/pr107967-2.c35
-rw-r--r--gcc/testsuite/gcc.dg/pr107967-3.c53
-rw-r--r--gcc/testsuite/gcc.dg/pr107975.c15
-rw-r--r--gcc/testsuite/gcc.dg/pr25521.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr77975.c10
-rw-r--r--gcc/testsuite/gcc.dg/pr93917.c20
-rw-r--r--gcc/testsuite/gcc.dg/pr96542.c2
-rw-r--r--gcc/testsuite/gcc.dg/redecl-19.c5
-rw-r--r--gcc/testsuite/gcc.dg/redecl-20.c9
-rw-r--r--gcc/testsuite/gcc.dg/redecl-21.c9
-rw-r--r--gcc/testsuite/gcc.dg/redecl-22.c9
-rw-r--r--gcc/testsuite/gcc.dg/redecl-23.c6
-rw-r--r--gcc/testsuite/gcc.dg/redecl-24.c6
-rw-r--r--gcc/testsuite/gcc.dg/redecl-25.c9
-rw-r--r--gcc/testsuite/gcc.dg/signbit-2.c8
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr107493.c13
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr107833.c33
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr107935.c18
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr108076.c17
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr71462.c1
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/pr108000.c93
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030808-1.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/branchless-cond.c26
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/forwprop-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-34.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loopclosedphi.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/popcount-max.c33
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr107490.c28
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr107541.c18
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr107699.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr107732.c13
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr55157.c19
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr89317.c30
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-42.c26
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-101.c47
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-18.c7
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp-float-plus.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp-update.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp122.c19
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp123.c18
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pr107183.c12
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pr107668.c12
-rw-r--r--gcc/testsuite/gcc.dg/uninit-pr107839.c13
-rw-r--r--gcc/testsuite/gcc.dg/uninit-pr40635.c33
-rw-r--r--gcc/testsuite/gcc.dg/uninit-pred-9_b.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-div-bitmask-1.c25
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-div-bitmask-2.c25
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-div-bitmask-3.c26
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-div-bitmask.h43
-rw-r--r--gcc/testsuite/gcc.misc-tests/gcov.exp4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_17.c4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/acle/bti_def.c10
-rw-r--r--gcc/testsuite/gcc.target/aarch64/acle/pauth_def.c10
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cssc_1.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cssc_2.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cssc_3.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cssc_4.c107
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cssc_5.c154
-rw-r--r--gcc/testsuite/gcc.target/aarch64/div-by-bitmask.c61
-rw-r--r--gcc/testsuite/gcc.target/aarch64/if-compare_1.c47
-rw-r--r--gcc/testsuite/gcc.target/aarch64/if-compare_2.c96
-rw-r--r--gcc/testsuite/gcc.target/aarch64/interleave-init-1.c37
-rw-r--r--gcc/testsuite/gcc.target/aarch64/ldapr-sext.c67
-rw-r--r--gcc/testsuite/gcc.target/aarch64/ldapr-zext.c67
-rw-r--r--gcc/testsuite/gcc.target/aarch64/ldapr.c34
-rw-r--r--gcc/testsuite/gcc.target/aarch64/mgeneral-regs_3.c6
-rw-r--r--gcc/testsuite/gcc.target/aarch64/mops_5.c17
-rw-r--r--gcc/testsuite/gcc.target/aarch64/mops_6.c17
-rw-r--r--gcc/testsuite/gcc.target/aarch64/mops_7.c16
-rw-r--r--gcc/testsuite/gcc.target/aarch64/movk_3.c56
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr92424-2.c4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr92424-3.c4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr98776.c11
-rw-r--r--gcc/testsuite/gcc.target/aarch64/simd/addsub_1.c56
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr107920.c10
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/addsub_1.c52
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/slp_1.c10
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/div-by-bitmask_1.c53
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/pr107717.c8
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/pr107830-1.c13
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/pr107830-2.c12
-rw-r--r--gcc/testsuite/gcc.target/aarch64/tbz_1.c95
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/cmse-20.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/cmse.exp11
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/struct-1.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/multilib.exp3
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s16.c48
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s32.c48
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s8.c48
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_u16.c48
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_u32.c48
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_u8.c48
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_s16.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_s32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_s8.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_u16.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_u32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_u8.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_f16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_f32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_u16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_u32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_u8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_u16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_u32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_u8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_f16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_f32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_s32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_s8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_u16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_u32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_u8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f16.c30
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f32.c30
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_f16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_f32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_s16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_s32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_s8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_s16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_s32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_f16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_f32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_s16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_s32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_s8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_p_s32.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_p_u32.c48
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_u32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_p_s32.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_p_u32.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_s32.c30
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_u32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_f16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_f32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_f16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_f32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_f16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_f32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_u16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_u32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_u8.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_u16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_u32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_u8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_f16.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_f32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_u16.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_u32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_u8.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_u16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_u32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_u8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_f16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_f32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_f16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_f32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_u16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_u32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_u8.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_u16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_u32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_u8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_s16.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_s32.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_s8.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_u16.c48
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_u32.c48
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_u8.c48
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_u16.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_u32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_u8.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_s16.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_s32.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_s8.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_u16.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_u32.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_u8.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_s16.c30
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_s32.c30
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_s8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_u16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_u32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_u8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u16.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u32.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u8.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_u16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_u32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_u8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_n_u16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_n_u32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_n_u8.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_u16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_u32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_u8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_f16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_f32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_f16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_f32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_f16.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_f32.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u16.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u32.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u8.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_s16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_s32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_s8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_u16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_u32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_u8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_f16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_f32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_s16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_s32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_s8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_u16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_u32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_u8.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_s16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_s32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_s8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_u16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_u32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_u8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_f16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_f32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_f16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_f32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_f16.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_f32.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_s16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_s32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_s8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_f16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_f32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_s16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_s32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_s8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_s16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_s32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_s8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_f16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_f32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_f16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_f32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_f16.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_f32.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_s16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_s32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_s8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_f16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_f32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_s16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_s32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_s8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_s16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_s32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_s8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u16.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u32.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u8.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_u16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_u32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_u8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_n_u16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_n_u32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_n_u8.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_u16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_u32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_u8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_f16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_f32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_f16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_f32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_f16.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_f32.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_s16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_s32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_s8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_f16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_f32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_s16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_s32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_s8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_s16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_s32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_s8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_f16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_f32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_f16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_f32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_f16.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_f32.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_s16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_s32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_s8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_f16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_f32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_s16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_s32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_s8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_s16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_s32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_s8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_f16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_f32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_f16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_f32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_f16.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_f32.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u16.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u32.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u8.c55
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_s16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_s32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_s8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_u16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_u32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_u8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_f16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_f32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_s16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_s32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_s8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_u16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_u32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_u8.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_s16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_s32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_s8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_u16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_u32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_u8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f16.c31
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f32.c31
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s16.c31
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s32.c31
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s64.c31
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s8.c31
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u16.c31
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u32.c31
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u64.c31
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u8.c31
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u32.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u8.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_wb_u16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_wb_u32.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_wb_u8.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_n_u16.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_n_u32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_n_u8.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_wb_u16.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_wb_u32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_wb_u8.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_n_u16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_n_u32.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_n_u8.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_wb_u16.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_wb_u32.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_wb_u8.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_f16.c49
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_f32.c49
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_u16.c49
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_u32.c49
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_u8.c49
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_f16.c29
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_f32.c29
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s16.c21
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s32.c21
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s8.c17
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u16.c31
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u32.c31
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u8.c31
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_f16.c38
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_f32.c38
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s16.c22
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s32.c22
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s8.c22
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_u16.c38
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_u32.c38
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_u8.c38
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u16.c52
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u32.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u8.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u16.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u32.c56
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u8.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_n_u16.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_n_u32.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_n_u8.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_wb_u16.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_wb_u32.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_wb_u8.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u32.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u8.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u16.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u32.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u8.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f16.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f32.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_u16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_u32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_u8.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_u16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_u32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_u8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_s16.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_s32.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_s8.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_u16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_u32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_u8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_s16.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_s32.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_s8.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_u16.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_u32.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_u8.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_s16.c26
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_s32.c26
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_s8.c26
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_u16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_u32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_u8.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_s16.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_s32.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_s8.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_u16.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_u32.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_u8.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_u16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_u32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_u8.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_u16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_u32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_u8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_s16.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_s32.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_s8.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_u16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_u32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_u8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_s16.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_s32.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_s8.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_u16.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_u32.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_u8.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_s16.c26
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_s32.c26
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_s8.c26
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_u16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_u32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_u8.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_s16.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_s32.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_s8.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_u16.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_u32.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_u8.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u16.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u8.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_wb_u16.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_wb_u32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_wb_u8.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_n_u16.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_n_u32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_n_u8.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_wb_u16.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_wb_u32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_wb_u8.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_n_u16.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_n_u32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_n_u8.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_wb_u16.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_wb_u32.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_wb_u8.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u16.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u32.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u8.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u16.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u32.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u8.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_n_u16.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_n_u32.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_n_u8.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_wb_u16.c44
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_wb_u32.c44
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_wb_u8.c44
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_n_u16.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_n_u32.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_n_u8.c54
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u16.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u32.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u8.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_f32.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_s32.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_u32.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_m_s16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_m_s32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_m_s8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_p_s16.c49
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_p_s32.c49
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_p_s8.c49
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_s16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_s32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_s8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_f16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_f32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_f16.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_f32.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f16.c47
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f32.c47
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_f16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_f32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_m_f16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_m_f32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_x_f16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_x_f32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_f16.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_f32.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f16.c47
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f32.c47
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_u16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_u32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_u8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_u16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_u32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_u8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_s16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_s32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_s8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_u16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_u32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_u8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_s16.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_s32.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_s8.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_u16.c47
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_u32.c47
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_u8.c47
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_s16.c27
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_s32.c27
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_s8.c27
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_u16.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_u32.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_u8.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_m_s16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_m_s32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_m_s8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_p_s16.c49
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_p_s32.c49
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_p_s8.c49
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_s16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_s32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_s8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_f16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_f32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_m_f16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_m_f32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_f16.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_f32.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_p_f16.c47
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_p_f32.c47
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_f16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_f32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_m_f16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_m_f32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_x_f16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_x_f32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_f16.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_f32.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_p_f16.c47
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_p_f32.c47
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_u16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_u32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_u8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_u16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_u32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_u8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_s16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_s32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_s8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_u16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_u32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_u8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_s16.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_s32.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_s8.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_u16.c47
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_u32.c47
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_u8.c47
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_s16.c26
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_s32.c26
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_s8.c26
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_u16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_u32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_u8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s16.c41
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s32.c41
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s8.c41
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_u16.c57
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_u32.c57
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_u8.c57
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_s16.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_s32.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_s8.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_u16.c44
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_u32.c44
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_u8.c44
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_p_s16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_p_s32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_p_s8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s16.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s32.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_s16.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_s32.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s8.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_u16.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_u32.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_u8.c58
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_s16.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_s32.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_s8.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_u16.c44
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_u32.c44
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_u8.c44
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_f16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_f32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_f16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_f32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_f16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_f32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_u16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_u32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_u8.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_u16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_u32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_u8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_f16.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_f32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_u16.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_u32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_u8.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_u16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_u32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_u8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_f16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_f32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_f16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_f32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_u16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_u32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_u8.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_u16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_u32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_u8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_u16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_u32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_u8.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_u16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_u32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_u8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_s16.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_s32.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_s8.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_u16.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_u32.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_u8.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_s16.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_s32.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_s8.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_u16.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_u32.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_u8.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s8.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_n_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_n_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_n_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_n_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_n_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_n_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_n_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_n_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_n_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_n_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_n_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_n_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_n_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s8.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s16.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s32.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s8.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s16.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s32.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s8.c42
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_u16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_u32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_u8.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_u16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_u32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_u8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_u16.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_u32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_u8.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_u16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_u32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_u8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_s32.c32
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_u32.c48
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_u32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_u16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_u32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_u8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_u16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_u32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_u8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_u16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_u32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_u8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_u16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_u32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_u8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_s16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_s32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_s8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_u16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_u32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_u8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f16.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s64.c27
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u16.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u64.c39
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u8.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_f16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_f32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_f16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_f32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_f16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_f32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_s16.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_s32.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_s8.c34
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_u16.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_u32.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_u8.c50
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_s16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_s32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_s8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_u16.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_u32.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_u8.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_f16.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_f32.c36
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_s16.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_s32.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_s8.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_u16.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_u32.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_u8.c37
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_s16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_s32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_s8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_u16.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_u32.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_u8.c24
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_f16.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_f32.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_f16.c56
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_f32.c56
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_s16.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_s32.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_s8.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_u16.c56
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_u32.c56
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_u8.c56
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_s16.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_s32.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_s8.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_u16.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_u32.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_u8.c40
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/pr107987.c11
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/mve-compare-1.c48
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/mve-compare-scalar-1.c48
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/mve-vabs.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/mve-vadd-1.c10
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/mve-vadd-scalar-1.c10
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/mve-vcmp.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/pr101325.c4
-rw-r--r--gcc/testsuite/gcc.target/bpf/bswap-1.c23
-rw-r--r--gcc/testsuite/gcc.target/gcn/math-builtins-1.c33
-rw-r--r--gcc/testsuite/gcc.target/gcn/unsafe-math-1.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/amx-check.h3
-rw-r--r--gcc/testsuite/gcc.target/i386/amx-helper.h61
-rw-r--r--gcc/testsuite/gcc.target/i386/amxbf16-dpbf16ps-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/amxfp16-asmatt-1.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/amxfp16-asmintel-1.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/amxfp16-dpfp16ps-2.c56
-rw-r--r--gcc/testsuite/gcc.target/i386/amxint8-dpbssd-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/amxint8-dpbsud-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/amxint8-dpbusd-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/amxint8-dpbuud-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-1.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bf16-cvtsbh2ss-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avxneconvert-1.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin_target.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/cbranchbf4.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/cmpccxadd-1.c61
-rw-r--r--gcc/testsuite/gcc.target/i386/cmpccxadd-2.c138
-rw-r--r--gcc/testsuite/gcc.target/i386/excess-precision-11.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/excess-precision-12.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/extendbfsf.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-56.inc11
-rw-r--r--gcc/testsuite/gcc.target/i386/pieces-memset-3.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/pieces-memset-37.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pieces-memset-39.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pieces-memset-50.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/pr106577.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/pr107304.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/pr107540.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/pr107546.c19
-rw-r--r--gcc/testsuite/gcc.target/i386/pr107627-1.c22
-rw-r--r--gcc/testsuite/gcc.target/i386/pr107627-2.c22
-rw-r--r--gcc/testsuite/gcc.target/i386/pr107627-3.c28
-rw-r--r--gcc/testsuite/gcc.target/i386/pr107627-4.c28
-rw-r--r--gcc/testsuite/gcc.target/i386/pr107628.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/pr107647.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr107863.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/pr107934.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/pr107969.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/pr107970.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/pr86270.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr93002.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr93492-2.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/pr93492-3.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/pr93492-4.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/pr93492-5.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/pr98167.c44
-rw-r--r--gcc/testsuite/gcc.target/i386/prefetchi-1.c40
-rw-r--r--gcc/testsuite/gcc.target/i386/prefetchi-2.c26
-rw-r--r--gcc/testsuite/gcc.target/i386/prefetchi-3.c20
-rw-r--r--gcc/testsuite/gcc.target/i386/prefetchi-4.c19
-rw-r--r--gcc/testsuite/gcc.target/i386/prefetchi-5.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/rao-helper.h79
-rw-r--r--gcc/testsuite/gcc.target/i386/raoint-1.c31
-rw-r--r--gcc/testsuite/gcc.target/i386/raoint-aadd-2.c24
-rw-r--r--gcc/testsuite/gcc.target/i386/raoint-aand-2.c25
-rw-r--r--gcc/testsuite/gcc.target/i386/raoint-aor-2.c25
-rw-r--r--gcc/testsuite/gcc.target/i386/raoint-axor-2.c25
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-12.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-13.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-14.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-22.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-23.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/x86gprintrin-1.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/x86gprintrin-2.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/x86gprintrin-3.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/x86gprintrin-4.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/x86gprintrin-5.c8
-rw-r--r--gcc/testsuite/gcc.target/loongarch/fcopysign.c16
-rw-r--r--gcc/testsuite/gcc.target/loongarch/flogb.c18
-rw-r--r--gcc/testsuite/gcc.target/loongarch/frint.c16
-rw-r--r--gcc/testsuite/gcc.target/loongarch/fscaleb.c48
-rw-r--r--gcc/testsuite/gcc.target/loongarch/ftint-no-inexact.c44
-rw-r--r--gcc/testsuite/gcc.target/loongarch/ftint.c44
-rw-r--r--gcc/testsuite/gcc.target/loongarch/imm-load.c10
-rw-r--r--gcc/testsuite/gcc.target/loongarch/imm-load1.c26
-rw-r--r--gcc/testsuite/gcc.target/loongarch/pr107713-1.c50
-rw-r--r--gcc/testsuite/gcc.target/loongarch/pr107713-2.c9
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-alloca-1.c15
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-alloca-2.c12
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-alloca-3.c12
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-alloca-4.c12
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-alloca-5.c13
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-alloca-6.c13
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-alloca.h15
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-cfa-1.c12
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-cfa-2.c12
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-prologue-1.c11
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-prologue-2.c11
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-prologue-3.c11
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-prologue-4.c11
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-prologue-5.c12
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-prologue-6.c11
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-prologue-7.c12
-rw-r--r--gcc/testsuite/gcc.target/loongarch/stack-check-prologue.h5
-rw-r--r--gcc/testsuite/gcc.target/mips/pr106462.c12
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cbranchcc4-1.c15
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cbranchcc4-2.c11
-rw-r--r--gcc/testsuite/gcc.target/powerpc/p9-vec-length-epil-8.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr100866-1.c11
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr100866-2.c13
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr105586.c1
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr107412.c19
-rw-r--r--gcc/testsuite/gcc.target/riscv/branch-1.c37
-rw-r--r--gcc/testsuite/gcc.target/riscv/builtin_pause.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/pr107786-2.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/pr107786.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/pr93304.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c40
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/dup-1.c521
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/dup-2.c75
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/macro.h6
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/spill-1.c385
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/spill-10.c41
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/spill-11.c59
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/spill-12.c47
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/spill-2.c320
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/spill-3.c254
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/spill-4.c196
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/spill-5.c130
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/spill-6.c101
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/spill-7.c114
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/spill-8.c51
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/spill-9.c42
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/spill-sp-adjust.c13
-rw-r--r--gcc/testsuite/gcc.target/riscv/sge.c12
-rw-r--r--gcc/testsuite/gcc.target/riscv/sgeu.c12
-rw-r--r--gcc/testsuite/gcc.target/riscv/shrink-wrap-1.c24
-rw-r--r--gcc/testsuite/gcc.target/riscv/sle.c12
-rw-r--r--gcc/testsuite/gcc.target/riscv/sleu.c12
-rw-r--r--gcc/testsuite/gcc.target/riscv/stack_frame.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/zawrs.c13
-rw-r--r--gcc/testsuite/gcc.target/riscv/zba-shNadd-04.c23
-rw-r--r--gcc/testsuite/gcc.target/riscv/zba-shNadd-05.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/zba-shNadd-07.c31
-rw-r--r--gcc/testsuite/gcc.target/riscv/zbb-min-max-02.c14
-rw-r--r--gcc/testsuite/gcc.target/riscv/zbb-srai-andn.c15
-rw-r--r--gcc/testsuite/gcc.target/riscv/zbs-bclri-01.c12
-rw-r--r--gcc/testsuite/gcc.target/riscv/zbs-bclri-02.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/zbs-bext.c29
-rw-r--r--gcc/testsuite/gcc.target/riscv/zbs-bexti.c31
-rw-r--r--gcc/testsuite/gcc.target/riscv/zbs-binvi.c22
-rw-r--r--gcc/testsuite/gcc.target/riscv/zbs-bseti-02.c25
-rw-r--r--gcc/testsuite/gcc.target/riscv/zbs-bseti.c27
-rw-r--r--gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c20
-rw-r--r--gcc/testsuite/gcc.target/x86_64/abi/bf16/abi-bf16.exp12
-rw-r--r--gcc/testsuite/gcc.target/x86_64/abi/bf16/args.h4
-rw-r--r--gcc/testsuite/gcc.target/x86_64/abi/bf16/asm-support-darwin.S97
-rw-r--r--gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/abi-bf16-ymm.exp12
-rw-r--r--gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/args.h4
-rw-r--r--gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/asm-support-darwin.S97
-rw-r--r--gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/abi-bf16-zmm.exp12
-rw-r--r--gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/args.h4
-rw-r--r--gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/asm-support-darwin.S113
-rw-r--r--gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch2.d40
-rw-r--r--gcc/testsuite/gdc.dg/attr_register2.d4
-rw-r--r--gcc/testsuite/gdc.dg/imports/pr108050/mod1.d2
-rw-r--r--gcc/testsuite/gdc.dg/imports/pr108050/mod2.d2
-rw-r--r--gcc/testsuite/gdc.dg/imports/pr108050/package.d2
-rw-r--r--gcc/testsuite/gdc.dg/pr107592.d13
-rw-r--r--gcc/testsuite/gdc.dg/pr108050.d4
-rw-r--r--gcc/testsuite/gdc.dg/simd2a.d12
-rw-r--r--gcc/testsuite/gdc.dg/simd2b.d12
-rw-r--r--gcc/testsuite/gdc.dg/simd2c.d12
-rw-r--r--gcc/testsuite/gdc.dg/simd2d.d12
-rw-r--r--gcc/testsuite/gdc.dg/simd2e.d12
-rw-r--r--gcc/testsuite/gdc.dg/simd2f.d12
-rw-r--r--gcc/testsuite/gdc.dg/simd2g.d12
-rw-r--r--gcc/testsuite/gdc.dg/simd2h.d12
-rw-r--r--gcc/testsuite/gdc.dg/simd2i.d12
-rw-r--r--gcc/testsuite/gdc.dg/simd2j.d12
-rw-r--r--gcc/testsuite/gdc.dg/torture/imports/pr108055conv.d26
-rw-r--r--gcc/testsuite/gdc.dg/torture/imports/pr108055spec.d18
-rw-r--r--gcc/testsuite/gdc.dg/torture/imports/pr108055write.d19
-rw-r--r--gcc/testsuite/gdc.dg/torture/pr108055.d12
-rw-r--r--gcc/testsuite/gdc.test/compilable/nogc.d3
-rw-r--r--gcc/testsuite/gdc.test/compilable/test15712.d12
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23431.d14
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23431_minimal.d28
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23433.d16
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23439.d8
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23534.d6
-rw-r--r--gcc/testsuite/gdc.test/compilable/test4375.d2
-rw-r--r--gcc/testsuite/gdc.test/compilable/vgc2.d3
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag14818.d16
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag8101.d5
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag_funclit.d14
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diagin.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail12.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail15414.d21
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail15616b.d1
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail1900.d8
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail22366.d32
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail23439.d13
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail320.d9
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail54.d10
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail99.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail_pretty_errors.d18
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice10922.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice13459.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice9540.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/imports/fail320a.d1
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/imports/fail320b.d3
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/lexer23465.d21
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/misc1.d22
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/nogc2.d3
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/retscope.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/retscope2.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/templateoverload.d22
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test19646.d8
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test21008.d6
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test21062.d24
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test23491.d19
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test23536.d19
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/throwexp.d12
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/warn14905.d23
-rw-r--r--gcc/testsuite/gdc.test/runnable/lexer.d9
-rw-r--r--gcc/testsuite/gdc.test/runnable/test21301.d116
-rw-r--r--gcc/testsuite/gdc.test/runnable/test21506.d40
-rw-r--r--gcc/testsuite/gfortran.dg/PR94104a.f9029
-rw-r--r--gcc/testsuite/gfortran.dg/PR94104b.f9029
-rw-r--r--gcc/testsuite/gfortran.dg/coarray/pr107441-caf.f9027
-rw-r--r--gcc/testsuite/gfortran.dg/contiguous_12.f907
-rw-r--r--gcc/testsuite/gfortran.dg/elemental_dependency_7.f9028
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/copyprivate-1.f9021
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/copyprivate-2.f9097
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/defaultmap-4.f904
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/defaultmap-5.f904
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/defaultmap-6.f902
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/nowait-2.f90159
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/nowait-4.f90158
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/nowait-5.f90156
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/nowait-6.f90158
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/nowait-7.f90118
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/nowait-8.f9092
-rw-r--r--gcc/testsuite/gfortran.dg/graphite/pr107865.f9018
-rw-r--r--gcc/testsuite/gfortran.dg/guality/guality.exp4
-rw-r--r--gcc/testsuite/gfortran.dg/merge_1.f9057
-rw-r--r--gcc/testsuite/gfortran.dg/merge_init_expr_2.f903
-rw-r--r--gcc/testsuite/gfortran.dg/null_actual_3.f9018
-rw-r--r--gcc/testsuite/gfortran.dg/optional_absent_6.f9060
-rw-r--r--gcc/testsuite/gfortran.dg/optional_absent_7.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/optional_absent_8.f9053
-rw-r--r--gcc/testsuite/gfortran.dg/parens_2.f902
-rw-r--r--gcc/testsuite/gfortran.dg/pr102180.f9019
-rw-r--r--gcc/testsuite/gfortran.dg/pr106911.f9018
-rw-r--r--gcc/testsuite/gfortran.dg/pr107559.f9011
-rw-r--r--gcc/testsuite/gfortran.dg/pr107577.f9013
-rw-r--r--gcc/testsuite/gfortran.dg/pr107679.f909
-rw-r--r--gcc/testsuite/gfortran.dg/pr107680.f9034
-rw-r--r--gcc/testsuite/gfortran.dg/pr107681.f9013
-rw-r--r--gcc/testsuite/gfortran.dg/pr107707.f9013
-rw-r--r--gcc/testsuite/gfortran.dg/pr107872.f9040
-rw-r--r--gcc/testsuite/gfortran.dg/pr107899.f9013
-rw-r--r--gcc/testsuite/gfortran.dg/pr107995.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/pr108010.f9054
-rw-r--r--gcc/testsuite/gfortran.dg/unpack_field_1.f9015
-rw-r--r--gcc/testsuite/gfortran.dg/widechar_11.f9051
-rw-r--r--gcc/testsuite/gnat.dg/abstract1.adb14
-rw-r--r--gcc/testsuite/gnat.dg/abstract1.ads6
-rw-r--r--gcc/testsuite/gnat.dg/machine_attr2.adb15
-rw-r--r--gcc/testsuite/gnat.dg/machine_attr2.ads8
-rw-r--r--gcc/testsuite/gnat.dg/opt100.adb13
-rw-r--r--gcc/testsuite/gnat.dg/opt100_pkg.adb17
-rw-r--r--gcc/testsuite/gnat.dg/opt100_pkg.ads23
-rw-r--r--gcc/testsuite/gnat.dg/opt99.adb15
-rw-r--r--gcc/testsuite/gnat.dg/opt99_pkg1.adb10
-rw-r--r--gcc/testsuite/gnat.dg/opt99_pkg1.ads19
-rw-r--r--gcc/testsuite/gnat.dg/opt99_pkg2.ads13
-rw-r--r--gcc/testsuite/gnat.dg/sso18.adb21
-rw-r--r--gcc/testsuite/gnat.dg/unchecked_convert9.adb2
-rw-r--r--gcc/testsuite/jit.dg/harness.h15
-rw-r--r--gcc/testsuite/jit.dg/test-expressions.c234
-rw-r--r--gcc/testsuite/lib/g++.exp4
-rw-r--r--gcc/testsuite/lib/gcc-dg.exp13
-rw-r--r--gcc/testsuite/lib/scanoffloadipa.exp148
-rw-r--r--gcc/testsuite/lib/target-supports-dg.exp15
-rw-r--r--gcc/testsuite/lib/target-supports.exp109
-rw-r--r--gcc/tree-call-cdce.cc46
-rw-r--r--gcc/tree-cfg.cc13
-rw-r--r--gcc/tree-chrec.cc3
-rw-r--r--gcc/tree-core.h21
-rw-r--r--gcc/tree-diagnostic.cc7
-rw-r--r--gcc/tree-if-conv.cc24
-rw-r--r--gcc/tree-into-ssa.cc19
-rw-r--r--gcc/tree-loop-distribution.cc7
-rw-r--r--gcc/tree-object-size.cc84
-rw-r--r--gcc/tree-pretty-print.cc8
-rw-r--r--gcc/tree-scalar-evolution.cc25
-rw-r--r--gcc/tree-ssa-alias.cc8
-rw-r--r--gcc/tree-ssa-ccp.cc114
-rw-r--r--gcc/tree-ssa-copy.cc49
-rw-r--r--gcc/tree-ssa-dce.cc15
-rw-r--r--gcc/tree-ssa-dom.cc8
-rw-r--r--gcc/tree-ssa-forwprop.cc23
-rw-r--r--gcc/tree-ssa-loop-im.cc24
-rw-r--r--gcc/tree-ssa-loop-ivopts.cc118
-rw-r--r--gcc/tree-ssa-loop-niter.cc446
-rw-r--r--gcc/tree-ssa-loop-unswitch.cc265
-rw-r--r--gcc/tree-ssa-loop.h3
-rw-r--r--gcc/tree-ssa-operands.cc4
-rw-r--r--gcc/tree-ssa-propagate.cc25
-rw-r--r--gcc/tree-ssa-sccvn.cc56
-rw-r--r--gcc/tree-ssa-sink.cc5
-rw-r--r--gcc/tree-ssa-strlen.cc4
-rw-r--r--gcc/tree-ssa-threadbackward.cc23
-rw-r--r--gcc/tree-ssa-threadedge.cc6
-rw-r--r--gcc/tree-ssa-uninit.cc4
-rw-r--r--gcc/tree-ssa.cc93
-rw-r--r--gcc/tree-ssa.h25
-rw-r--r--gcc/tree-switch-conversion.cc59
-rw-r--r--gcc/tree-switch-conversion.h8
-rw-r--r--gcc/tree-vect-data-refs.cc12
-rw-r--r--gcc/tree-vect-generic.cc11
-rw-r--r--gcc/tree-vect-patterns.cc12
-rw-r--r--gcc/tree-vect-slp-patterns.cc15
-rw-r--r--gcc/tree-vect-stmts.cc18
-rw-r--r--gcc/tree-vrp.cc3497
-rw-r--r--gcc/tree-vrp.h27
-rw-r--r--gcc/tree.cc202
-rw-r--r--gcc/tree.def5
-rw-r--r--gcc/tree.h24
-rw-r--r--gcc/tristate.h1
-rw-r--r--gcc/value-query.cc25
-rw-r--r--gcc/value-query.h8
-rw-r--r--gcc/value-range-equiv.cc330
-rw-r--r--gcc/value-range-equiv.h90
-rw-r--r--gcc/value-range-storage.cc9
-rw-r--r--gcc/value-range.cc45
-rw-r--r--gcc/varasm.cc17
-rw-r--r--gcc/vr-values.cc2091
-rw-r--r--gcc/vr-values.h111
2536 files changed, 118394 insertions, 29233 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f7ab7da..547b067 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8364 @@
+2022-12-12 Wilco Dijkstra <wilco.dijkstra@arm.com>
+
+ * config/aarch64/aarch64.cc (aarch64_rtx_costs): Add correct costs
+ for 24-bit and 12-bit shifted immediate add/sub.
+ (TARGET_CONST_ANCHOR): Define.
+ * config/aarch64/predicates.md (aarch64_pluslong_immediate):
+ Fix range check.
+
+2022-12-12 Tamar Christina <tamar.christina@arm.com>
+
+ * match.pd: Add new rule.
+
+2022-12-12 Tamar Christina <tamar.christina@arm.com>
+
+ * config/aarch64/aarch64.cc (aarch64_can_change_mode_class): Restrict
+ conversions between partial struct types properly.
+
+2022-12-12 Tamar Christina <tamar.christina@arm.com>
+
+ * config/aarch64/aarch64.md (*tb<optab><mode>1): Rename to...
+ (*tb<optab><ALLI:mode><GPI:mode>1): ... this.
+ (tbranch_<code><mode>4): New.
+ * config/aarch64/iterators.md(ZEROM, zerom): New.
+
+2022-12-12 Tamar Christina <tamar.christina@arm.com>
+
+ * dojump.cc (do_jump): Pass along value.
+ (do_jump_by_parts_greater_rtx): Likewise.
+ (do_jump_by_parts_zero_rtx): Likewise.
+ (do_jump_by_parts_equality_rtx): Likewise.
+ (do_compare_rtx_and_jump): Likewise.
+ (do_compare_and_jump): Likewise.
+ * dojump.h (do_compare_rtx_and_jump): New.
+ * optabs.cc (emit_cmp_and_jump_insn_1): Refactor to take optab to check.
+ (validate_test_and_branch): New.
+ (emit_cmp_and_jump_insns): Optiobally take a value, and when value is
+ supplied then check if it's suitable for tbranch.
+ * optabs.def (tbranch_eq$a4, tbranch_ne$a4): New.
+ * doc/md.texi (tbranch_@var{op}@var{mode}4): Document it.
+ * optabs.h (emit_cmp_and_jump_insns): New.
+ * tree.h (tree_zero_one_valued_p): New.
+
+2022-12-12 Tamar Christina <tamar.christina@arm.com>
+
+ * config/aarch64/aarch64-simd.md (*aarch64_simd_movv2hf): New.
+ (mov<mode>, movmisalign<mode>, aarch64_dup_lane<mode>,
+ aarch64_store_lane0<mode>, aarch64_simd_vec_set<mode>,
+ @aarch64_simd_vec_copy_lane<mode>, vec_set<mode>,
+ reduc_<optab>_scal_<mode>, reduc_<fmaxmin>_scal_<mode>,
+ aarch64_reduc_<optab>_internal<mode>, aarch64_get_lane<mode>,
+ vec_init<mode><Vel>, vec_extract<mode><Vel>): Support V2HF.
+ (aarch64_simd_dupv2hf): New.
+ * config/aarch64/aarch64.cc (aarch64_classify_vector_mode):
+ Add E_V2HFmode.
+ * config/aarch64/iterators.md (VHSDF_P): New.
+ (V2F, VMOVE, nunits, Vtype, Vmtype, Vetype, stype, VEL,
+ Vel, q, vp): Add V2HF.
+ * config/arm/types.md (neon_fp_reduc_add_h): New.
+
+2022-12-12 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64-c.cc (aarch64_update_cpp_builtins): Define
+ __ARM_FEATURE_PAUTH and __ARM_FEATURE_BTI when appropriate.
+ * config/aarch64/aarch64.h (TARGET_BTI): Define.
+
+2022-12-12 Richard Biener <rguenther@suse.de>
+
+ * genmatch.cc (dt_simplify::gen): Revert last change.
+ * match.pd: Revert simplification of CONSTUCTOR leaf handling.
+ (&x cmp SSA_NAME): Handle ADDR_EXPR in SSA defs.
+ * fold-const.cc (split_address_to_core_and_offset): Handle
+ ADDR_EXPRs in SSA defs.
+ (address_compare): Likewise.
+
+2022-12-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/89317
+ * tree-ssa-ccp.cc (ccp_fold): Handle GIMPLE_COND via
+ gimple_fold_stmt_to_constant_1.
+ * match.pd (&a != &a + c): Apply to pointer_plus with non-ADDR_EXPR
+ base as well.
+
+2022-12-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/89317
+ * match.pd ((p + b) - &p->c -> b - offsetof(c)): New patterns.
+
+2022-12-11 Richard Biener <rguenther@suse.de>
+
+ * genmatch.cc (dt_node::gen_kids): Handle ADDR_EXPR in both
+ the GENERIC and GIMPLE op position.
+ (dt_simplify::gen): Capture both GENERIC and GIMPLE op
+ position for ADDR_EXPR and CONSTRUCTOR.
+ * match.pd: Simplify CONSTRUCTOR leaf handling.
+
+2022-12-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/106904
+ * tree.h (strip_zero_offset_components): Declare.
+ * tree.cc (strip_zero_offset_components): Define.
+ * tree-vect-data-refs.cc (vect_create_addr_base_for_vector_ref):
+ Strip zero offset components before building the address.
+
+2022-12-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107997
+ * tree-ssa-loop-ivopts.cc: Include cfganal.h.
+ (create_new_iv) <case IP_END>: If ip_end_pos bb is non-empty and ends
+ with a stmt which ends bb, instead of adding iv update after it split
+ the latch edge and insert iterator into the new latch bb.
+
+2022-12-09 Jiufu Guo <guojiufu@linux.ibm.com>
+
+ * config/rs6000/rs6000.cc (rs6000_emit_set_const): Remove copy_rtx.
+ (rs6000_emit_set_long_const): Likewise.
+
+2022-12-09 Martin Liska <mliska@suse.cz>
+
+ * config/i386/i386-builtins.cc (fold_builtin_cpu): Use same path
+ as for PR103661.
+ * doc/extend.texi: Fix "x86-64" use.
+
+2022-12-09 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * config/rtems.h (SUBTARGET_CC1_SPEC): Rename to...
+ (OS_CC1_SPEC): ...this.
+ * gcc.cc (SUBTARGET_CC1_SPEC): Rename to...
+ (OS_CC1_SPEC): ...this.
+
+2022-12-09 David Malcolm <dmalcolm@redhat.com>
+
+ * Makefile.in (ANALYZER_OBJS): Update for renaming of
+ analyzer/region-model-impl-calls.cc to analyzer/kf.cc.
+
+2022-12-09 liuhongt <hongtao.liu@intel.com>
+
+ * doc/invoke.texi (x86 options): Document
+ -mlam={none,u48,u57}.
+ * config/i386/i386-opts.h (enum lam_type): New enum.
+ * config/i386/i386.cc (ix86_memtag_can_tag_addresses): New.
+ (ix86_memtag_set_tag): Ditto.
+ (ix86_memtag_extract_tag): Ditto.
+ (ix86_memtag_add_tag): Ditto.
+ (ix86_memtag_tag_size): Ditto.
+ (ix86_memtag_untagged_pointer): Ditto.
+ (TARGET_MEMTAG_CAN_TAG_ADDRESSES): New.
+ (TARGET_MEMTAG_ADD_TAG): Ditto.
+ (TARGET_MEMTAG_SET_TAG): Ditto.
+ (TARGET_MEMTAG_EXTRACT_TAG): Ditto.
+ (TARGET_MEMTAG_UNTAGGED_POINTER): Ditto.
+ (TARGET_MEMTAG_TAG_SIZE): Ditto.
+ (IX86_HWASAN_SHIFT): Ditto.
+ (IX86_HWASAN_TAG_SIZE): Ditto.
+ * config/i386/i386-expand.cc (ix86_expand_call): Untag code
+ pointer.
+ * config/i386/i386-options.cc (ix86_option_override_internal):
+ Error when enable -mlam=[u48|u57] for 32-bit code.
+ * config/i386/i386.opt: Add -mlam=[none|u48|u57].
+ * config/i386/i386-protos.h (ix86_memtag_untagged_pointer):
+ Declare.
+ (ix86_memtag_can_tag_addresses): Ditto.
+
+2022-12-08 Marek Polacek <polacek@redhat.com>
+
+ * doc/invoke.texi (-fsanitize=address): Suggest options to improve
+ stack traces.
+
+2022-12-08 Eugene Rozenfeld <erozen@microsoft.com>
+
+ PR ipa/108000
+ * ipa-cp.cc (ipcp_propagate_stage): Fix profile count comparison
+
+2022-12-08 David Faust <david.faust@oracle.com>
+
+ * config/bpf/bpf.md (bswap<mode>2): New define_insn.
+
+2022-12-08 Sebastian Pop <spop@amazon.com>
+
+ PR target/98776
+ * config/aarch64/aarch64-protos.h (aarch64_output_patchable_area):
+ Declared.
+ * config/aarch64/aarch64.cc (aarch64_print_patchable_function_entry):
+ Emit an UNSPECV_PATCHABLE_AREA pseudo instruction.
+ (aarch64_output_patchable_area): New.
+ * config/aarch64/aarch64.md (UNSPECV_PATCHABLE_AREA): New.
+ (patchable_area): Define.
+
+2022-12-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/106719
+ * cfgbuild.cc (find_bb_boundaries): If there are NOTEs in between
+ debug_insn (seen after flow_transfer_insn) and insn, move NOTEs
+ before all the DEBUG_INSNs and split after NOTEs. If there are
+ other insns like jump table data, clear debug_insn.
+
+2022-12-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/107627
+ * config/i386/i386.md (HALF, half): New mode attributes.
+ (*concat<half><mode>3_5, *concat<mode><dwi>3_6,
+ *concat<mode><dwi>3_7): New define_insn_and_split patterns.
+
+2022-12-08 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/107985
+ * gimple-range-op.cc
+ (gimple_range_op_handler::gimple_range_op_handler): Check if type
+ of the operands is supported.
+ * gimple-range.cc (gimple_ranger::prefill_stmt_dependencies): Do
+ not assert if here is no range-op handler.
+
+2022-12-08 Jiufu Guo <guojiufu@linux.ibm.com>
+
+ * config/rs6000/predicates.md: Use sext_hwi.
+ * config/rs6000/rs6000.cc (num_insns_constant_gpr): Likewise.
+ (darwin_rs6000_legitimate_lo_sum_const_p): Likewise.
+ (mem_operand_gpr): Likewise.
+ (mem_operand_ds_form): Likewise.
+ (rs6000_legitimize_address): Likewise.
+ (rs6000_emit_set_const): Likewise.
+ (rs6000_emit_set_long_const): Likewise.
+ (print_operand): Likewise.
+ (constant_generates_xxspltiw): Remove unnecessary expressions.
+ * config/rs6000/rs6000.md: Use sext_hwi.
+
+2022-12-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107699
+ * match.pd (&a !=/== &a.b + c -> (&a - &a.b) !=/== c): New
+ pattern variant.
+
+2022-12-08 Jakub Jelinek <jakub@redhat.com>
+
+ * range-op-float.cc (frange_nextafter): For MODE_COMPOSITE_P from
+ denormal or zero, use real_nextafter on DFmode with conversions
+ around it.
+ (frange_arithmetic): For mode_composite, on top of rounding in the
+ right direction accept extra 1ulp error for PLUS/MINUS_EXPR, extra
+ 2ulps error for MULT_EXPR and extra 3ulps error for RDIV_EXPR.
+
+2022-12-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107967
+ * range-op-float.cc (frange_arithmetic): Fix a thinko - if
+ inf is negative, use nextafter if !real_less (&result, &value)
+ rather than if real_less (&result, &value). If result is +-INF
+ while value is finite and -fno-rounding-math, don't do rounding
+ if !inexact or if result is significantly above max representable
+ value or below min representable value.
+
+2022-12-07 Max Filippov <jcmvbkbc@gmail.com>
+
+ * config.gcc (xtensa*-*-*): Add xtensa-dynconfig.o to extra_objs.
+ * config/xtensa/t-xtensa (TM_H): Add xtensa-dynconfig.h.
+ (xtensa-dynconfig.o): New rule.
+ * config/xtensa/xtensa-dynconfig.c: New file.
+ * config/xtensa/xtensa-protos.h (xtensa_get_config_strings): New
+ declaration.
+ * config/xtensa/xtensa.h (xtensa-config.h): Replace #include
+ with xtensa-dynconfig.h
+ (XCHAL_HAVE_MUL32_HIGH, XCHAL_HAVE_RELEASE_SYNC)
+ (XCHAL_HAVE_S32C1I, XCHAL_HAVE_THREADPTR)
+ (XCHAL_HAVE_FP_POSTINC): Drop definitions.
+ (TARGET_DIV32): Replace with __XCHAL_HAVE_DIV32.
+ (TARGET_CPU_CPP_BUILTINS): Add new 'builtin' variable and loop
+ through string array returned by the xtensa_get_config_strings
+ function call.
+
+2022-12-07 Wilco Dijkstra <wilco.dijkstra@arm.com>
+
+ PR target/108006
+ * config/aarch64/aarch64.cc (aarch64_expand_sve_const_vector):
+ Fix call to aarch64_move_imm to use SI/DI.
+
+2022-12-07 Richard Biener <rguenther@suse.de>
+
+ PR ipa/105676
+ * ipa-pure-const.cc (ipa_make_function_pure): Skip also
+ for functions already being const.
+
+2022-12-07 Hongyu Wang <hongyu.wang@intel.com>
+
+ * config/i386/x86-tune.def (X86_TUNE_AVOID_256FMA_CHAINS): Add
+ m_SAPPHIRERAPIDS, m_ALDERLAKE and m_CORE_ATOM.
+
+2022-12-07 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ PR target/107920
+ * config/aarch64/aarch64-sve-builtins-base.cc: Use
+ gsi_replace_with_seq_vops to handle virtual operands, and gate
+ the transform on !flag_non_call_exceptions.
+ * gimple-fold.cc (gsi_replace_with_seq_vops): Make function non static.
+ * gimple-fold.h (gsi_replace_with_seq_vops): Declare.
+
+2022-12-07 liuhongt <hongtao.liu@intel.com>
+
+ PR target/107970
+ * config/i386/mmx.md (btruncv2sf2): Add TARGET_MMX_WITH_SSE to
+ the condition.
+
+2022-12-06 Wilco Dijkstra <wilco.dijkstra@arm.com>
+
+ * config/aarch64/aarch64.cc (aarch64_bitmask_imm): Use unsigned type.
+ (aarch64_is_mov_xn_imm): New function.
+ (aarch64_move_imm): Refactor, assert mode is SImode or DImode.
+ (aarch64_internal_mov_immediate): Assert mode is SImode or DImode.
+ Simplify special cases.
+ (aarch64_uimm12_shift): Simplify code.
+ (aarch64_clamp_to_uimm12_shift): Likewise.
+ (aarch64_movw_imm): Rename to aarch64_is_movz.
+ (aarch64_float_const_rtx_p): Pass either SImode or DImode to
+ aarch64_internal_mov_immediate.
+ (aarch64_rtx_costs): Likewise.
+ * config/aarch64/aarch64.md (movdi_aarch64): Merge 'N' and 'M'
+ constraints into single 'O'.
+ (mov<mode>_aarch64): Likewise.
+ * config/aarch64/aarch64-protos.h (aarch64_move_imm): Use unsigned.
+ (aarch64_bitmask_imm): Likewise.
+ (aarch64_uimm12_shift): Likewise.
+ (aarch64_is_mov_xn_imm): New prototype.
+ * config/aarch64/constraints.md: Add 'O' for 32/64-bit immediates,
+ limit 'N' to 64-bit only moves.
+
+2022-12-06 Qing Zhao <qing.zhao@oracle.com>
+
+ * attribs.cc (strict_flex_array_level_of): New function.
+ * attribs.h (strict_flex_array_level_of): Prototype for new function.
+ * doc/invoke.texi: Update -Warray-bounds by specifying the impact from
+ -fstrict-flex-arrays. Also update -Warray-bounds=2 by eliminating its
+ impact on treating trailing arrays as flexible array members.
+ * gimple-array-bounds.cc (get_up_bounds_for_array_ref): New function.
+ (check_out_of_bounds_and_warn): New function.
+ (array_bounds_checker::check_array_ref): Update with call to the above
+ new functions.
+ * tree.cc (array_ref_flexible_size_p): Add one new argument.
+ (component_ref_sam_type): New function.
+ (component_ref_size): Control with level of strict-flex-array.
+ * tree.h (array_ref_flexible_size_p): Update prototype.
+ (enum struct special_array_member): Add two new enum values.
+ (component_ref_sam_type): New prototype.
+
+2022-12-06 David Malcolm <dmalcolm@redhat.com>
+
+ * doc/analyzer.texi: Drop out-of-date ideas for other checkers.
+
+2022-12-06 David Malcolm <dmalcolm@redhat.com>
+
+ * Makefile.in (ANALYZER_OBJS): Add analyzer/call-details.o,
+ analyzer/kf-analyzer.o, and kf-lang-cp.o.
+
+2022-12-06 Marcel Vollweiler <marcel@codesourcery.com>
+
+ * gimplify.cc (optimize_target_teams): Set initial num_teams_upper
+ to "-2" instead of "1" for non-existing num_teams clause in order to
+ disambiguate from the case of an existing num_teams clause with value 1.
+
+2022-12-06 Andre Vieira <andre.simoesdiasvieira@arm.com>
+
+ PR target/107987
+ * config/arm/mve.md (mve_vcmp<mve_cmp_op>q_n_<mode>,
+ @mve_vcmp<mve_cmp_op>q_n_f<mode>): Apply vec_duplicate to scalar
+ operand.
+
+2022-12-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/107969
+ * config/i386/i386.md (cbranchbf4, cstorebf4): Guard expanders
+ with the same condition as cbranchsf4 or cstoresf4 expanders.
+
+2022-12-06 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/104475
+ * pointer-query.h (access_ref::ref_nullptr_p): New flag.
+ * pointer-query.cc (access_ref::access_ref): Initialize
+ ref_nullptr_p.
+ (compute_objsize_r): Set ref_nullptr_p if we treat it that way.
+ (access_ref::inform_access): If ref was treated as nullptr
+ based, indicate that.
+
+2022-12-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107972
+ * range-op-float.cc (frange_drop_infs): New function.
+ (float_binary_op_range_finish): Add DIV_OP2 argument. If DIV_OP2 is
+ false and lhs is finite or if DIV_OP2 is true and lhs is non-zero and
+ not NAN, r must be finite too.
+ (foperator_div::op2_range): Pass true to DIV_OP2 of
+ float_binary_op_range_finish.
+
+2022-12-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107975
+ * range-op-float.cc (foperator_mult::op1_range,
+ foperator_div::op1_range, foperator_div::op2_range): Just
+ return float_binary_op_range_finish result if lhs is known
+ NAN, or the other operand is known NAN or UNDEFINED.
+
+2022-12-06 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ * config/aarch64/aarch64.cc (aarch64_expand_vector_init): Use dup
+ and zip1 for interleaving elements in vector initializer.
+
+2022-12-05 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/40635
+ * tree-into-ssa.cc (rewrite_update_phi_arguments): Only
+ update the argument when the reaching definition is different
+ from the current argument. Keep an existing argument
+ location.
+
+2022-12-05 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/106868
+ * gimple-ssa-warn-access.cc (pass_waccess::gimple_call_return_arg_ref):
+ Inline into single user ...
+ (pass_waccess::check_dangling_uses): ... here and adjust the
+ call and the PHI case to require that ref.aref is the address
+ of the decl.
+
+2022-12-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/106805
+ * match.pd (cmp @0 REAL_CST@1): Don't optimize x cmp NaN
+ or NaN cmp x to false/true for cmp >/>=/</<= if -ftrapping-math.
+
+2022-12-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107879
+ * range-op-float.cc (foperator_mult::op1_range): If both
+ lhs and op2 ranges contain zero or both ranges contain
+ some infinity, set r range to zero_to_inf_range depending on
+ signbit_known_p.
+ (foperator_div::op2_range): Similarly for lhs and op1 ranges.
+ (foperator_div::op1_range): If lhs range contains zero and op2
+ range contains some infinity or vice versa, set r range to
+ zero_to_inf_range depending on signbit_known_p.
+ (foperator_div::rv_fold): Fix up condition for returning known NAN.
+
+2022-12-05 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107833
+ PR tree-optimization/107839
+ * cfghooks.cc: Include tree.h.
+ * tree-ssa-loop-im.cc (movement_possibility): Wrap and
+ make stmts using any ssa_name_maybe_undef_p operand
+ to preserve execution.
+ (loop_invariant_motion_in_fun): Call mark_ssa_maybe_undefs
+ to init maybe-undefined status.
+ * tree-ssa-loop-ivopts.cc (ssa_name_maybe_undef_p,
+ ssa_name_set_maybe_undef, ssa_name_any_use_dominates_bb_p,
+ mark_ssa_maybe_undefs): Move ...
+ * tree-ssa.cc: ... here.
+ * tree-ssa.h (ssa_name_any_use_dominates_bb_p,
+ mark_ssa_maybe_undefs): Declare.
+ (ssa_name_maybe_undef_p, ssa_name_set_maybe_undef): Define.
+
+2022-12-05 Andrew Pinski <pinskia@gmail.com>
+
+ PR tree-optimization/107956
+ * tree-vect-patterns.cc (vect_recog_mask_conversion_pattern):
+ Check for NULL LHS on masked loads.
+
+2022-12-05 Kewen Lin <linkw@linux.ibm.com>
+ Richard Sandiford <richard.sandiford@arm.com>
+
+ PR tree-optimization/107412
+ * gimple-fold.cc (gimple_fold_partial_load_store_mem_ref): Use
+ untruncated type for the length, and avoid to_constant and tree
+ arithmetic for subtraction.
+
+2022-12-02 Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
+ Jason Merrill <jason@redhat.com>
+
+ * function.cc (init_function_start): Use DECL_RESULT location
+ for -Waggregate-return warning.
+
+2022-12-02 Andrew MacLeod <amacleod@redhat.com>
+
+ * fold-const.cc (fold_unary_loc): Check TREE_TYPE of node.
+ (tree_invalid_nonnegative_warnv_p): Likewise.
+
+2022-12-02 Jason Merrill <jason@redhat.com>
+
+ * gcc.cc (validate_switches): Reset suffix/starred on loop.
+
+2022-12-02 Vladimir N. Makarov <vmakarov@redhat.com>
+
+ * lra-constraints.cc (curr_insn_transform): Check available hard
+ regs for pseudo and its subreg to decide what to reload.
+
+2022-12-02 liuhongt <hongtao.liu@intel.com>
+
+ * config/i386/i386-expand.cc
+ (ix86_expand_fast_convert_bf_to_sf): Use extendbfsf2_1 for
+ nonimmediate operand.
+
+2022-12-02 Martin Liska <mliska@suse.cz>
+
+ * configure: Regenerate.
+
+2022-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/106577
+ * config/i386/i386-expand.cc (ix86_vector_duplicate_value): Save/restore
+ recog_data around recog_memoized calls.
+
+2022-12-02 Michael Collison <collison@rivosinc.com>
+
+ * match.pd ((x & 0x1) == 0) ? y : z <op> y
+ -> (-(typeof(y))(x & 0x1) & z) <op> y.
+
+2022-12-02 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107946
+ * params.opt (-param=max-unswitch-depth=): New.
+ * doc/invoke.texi (--param=max-unswitch-depth): Document.
+ * tree-ssa-loop-unswitch.cc (init_loop_unswitch_info): Honor
+ --param=max-unswitch-depth
+
+2022-12-02 Eric Gallager <egallager@gcc.gnu.org>
+
+ PR bootstrap/59447
+ * configure: Regenerate.
+ * configure.ac: Document --with-dwarf2 flag as also
+ applying to later DWARF standards.
+ * doc/install.texi: Likewise.
+
+2022-12-02 liuhongt <hongtao.liu@intel.com>
+
+ PR target/107934
+ * config/i386/i386.md (extendbfsf2_1): Change type from
+ sseishft to sseishft1.
+
+2022-12-01 Alex Coplan <alex.coplan@arm.com>
+
+ * varasm.cc (assemble_variable): Fix type confusion bug when
+ checking for ".vtable_map_vars" section.
+
+2022-12-01 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-v.cc (emit_pred_op): Adapt for mask mode.
+ * config/riscv/vector.md: Remove Tail && make policy operand for mask mode mov.
+
+2022-12-01 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-protos.h (enum vlmul_type): New enum.
+ (get_vlmul): New function.
+ (get_ratio): Ditto.
+ * config/riscv/riscv-v.cc (struct mode_vtype_group): New struct.
+ (ENTRY): Adapt for attributes.
+ (enum vlmul_type): New enum.
+ (get_vlmul): New function.
+ (get_ratio): New function.
+ * config/riscv/riscv-vector-switch.def (ENTRY): Adapt for attributes.
+ * config/riscv/riscv.cc (ENTRY): Ditto.
+ * config/riscv/vector.md (false,true): Add attributes.
+
+2022-12-01 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * config/riscv/constraints.md (Wdm): New constraint.
+ * config/riscv/predicates.md (direct_broadcast_operand): New predicate.
+ * config/riscv/riscv-protos.h (RVV_VLMAX): New macro.
+ (emit_pred_op): Refine function.
+ * config/riscv/riscv-selftests.cc (run_const_vector_selftests): New function.
+ (run_broadcast_selftests): Ditto.
+ (BROADCAST_TEST): New tests.
+ (riscv_run_selftests): More tests.
+ * config/riscv/riscv-v.cc (emit_pred_move): Refine function.
+ (emit_vlmax_vsetvl): Ditto.
+ (emit_pred_op): Ditto.
+ (expand_const_vector): New function.
+ (legitimize_move): Add constant vector support.
+ * config/riscv/riscv.cc (riscv_print_operand): New asm print rule for const vector.
+ * config/riscv/riscv.h (X0_REGNUM): New macro.
+ * config/riscv/vector-iterators.md: New attribute.
+ * config/riscv/vector.md (vec_duplicate<mode>): New pattern.
+ (@pred_broadcast<mode>): New pattern.
+
+2022-12-01 Paul-Antoine Arras <pa@codesourcery.com>
+
+ * config/gcn/gcn-opts.h (TARGET_FIJI): -march=fiji.
+ (TARGET_VEGA10): -march=gfx900.
+ (TARGET_VEGA20): -march=gfx906.
+ (TARGET_GFX908): -march=gfx908.
+ (TARGET_GFX90a): -march=gfx90a.
+ * config/gcn/gcn.h (TARGET_CPU_CPP_BUILTINS): Define a builtin that
+ uniquely maps to '-march'.
+
+2022-12-01 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107937
+ * gimple-predicate-analysis.h (predicate::is_true): New.
+ (predicate::is_false): Likewise.
+ (predicate::empty_val): Likewise.
+ (uninit_analysis::uninit_analysis): Properly initialize
+ def_preds.
+ * gimple-predicate-analysis.cc (simplify_1b): Indicate
+ whether the chain became empty.
+ (predicate::simplify): Release emptied chain before removing it.
+ (predicate::normalize): Replace temporary object with assertion.
+ (uninit_analysis::is_use_guarded): Deal with predicates
+ that simplify to true/false.
+
+2022-12-01 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107935
+ * tree-ssa-sccvn.cc (visit_phi): Honor forced VARYING on
+ backedges.
+
+2022-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/107627
+ * config/i386/i386.md (*concat<mode><dwi>3_1, *concat<mode><dwi>3_2):
+ For operands which are zero_extend arguments allow memory if
+ output operand is a register.
+ (*concat<mode><dwi>3_3, *concat<mode><dwi>3_4): Likewise. If
+ both input operands are memory, use early clobber on output operand.
+ * config/i386/i386-expand.cc (split_double_concat): Deal with corner
+ cases where one input is memory and the other is not and the address
+ of the memory input uses a register we'd overwrite before loading
+ the memory into a register.
+
+2022-12-01 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ * config/rs6000/rs6000-call.cc (swap_endian_selector_for_mode):
+ Corrects comments of this function and make them clear.
+
+2022-12-01 liuhongt <hongtao.liu@intel.com>
+
+ PR target/107863
+ * config/i386/i386-expand.cc (ix86_expand_vec_set_builtin):
+ Convert op1 to target mode whenever mode mismatch.
+
+2022-12-01 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106626
+ * diagnostic-path.h
+ (diagnostic_path::get_first_event_in_a_function): New decl.
+ * diagnostic.cc (diagnostic_path::get_first_event_in_a_function):
+ New.
+ (diagnostic_path::interprocedural_p): Ignore leading events that
+ are outside of any function.
+
+2022-12-01 David Malcolm <dmalcolm@redhat.com>
+
+ * Makefile.in (ANALYZER_OBJS): Add analyzer/bounds-checking.o.
+
+2022-12-01 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ PR target/100866
+ * config/rs6000/rs6000-call.cc (swap_endian_selector_for_mode):
+ Generate permute index directly for little endian targets.
+ * config/rs6000/vsx.md (revb_<mode>): Call vprem directly with
+ corresponding permute indexes.
+
+2022-11-30 John David Anglin <danglin@gcc.gnu.org>
+
+ * config/pa/pa.md (addvdi3): Force operand 2 to a register.
+ Remove "addi,tsv,*" instruction from unamed pattern.
+ (subvdi3): Force operand 1 to a register.
+ Remove "subi,tsv" instruction from from unamed pattern.
+
+2022-11-30 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64.md (aarch64_cpymemdi): Specify clobber of CC reg.
+ (*aarch64_cpymemdi): Likewise.
+ (aarch64_movmemdi): Likewise.
+ (aarch64_setmemdi): Likewise.
+ (*aarch64_setmemdi): Likewise.
+
+2022-11-30 Martin Liska <mliska@suse.cz>
+
+ * tree-switch-conversion.cc (bit_test_cluster::emit): Remove
+ dead variable bt_range.
+
+2022-11-30 Iskander Shakirzyanov <iskander@ispras.ru>
+ Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ PR driver/107787
+ * common.opt (Warray-bounds): Turn into alias of
+ -Warray-bounds=1.
+ * builtins.cc (c_strlen): Use OPT_Warray_bounds_
+ instead of OPT_Warray_bounds.
+ * diagnostic-spec.cc (nowarn_spec_t::nowarn_spec_t): Ditto.
+ * gimple-array-bounds.cc (array_bounds_checker::check_array_ref,
+ array_bounds_checker::check_mem_ref,
+ array_bounds_checker::check_addr_expr,
+ array_bounds_checker::check_array_bounds): Ditto.
+ * gimple-ssa-warn-restrict.cc (maybe_diag_access_bounds): Ditto.
+
+2022-11-30 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/101301
+ PR tree-optimization/103680
+ * tree-switch-conversion.cc (bit_test_cluster::emit):
+ Handle correctly remaining probability.
+ (switch_decision_tree::try_switch_expansion): Fix BB's count
+ where a cluster expansion happens.
+ (switch_decision_tree::emit_cmp_and_jump_insns): Fill up also
+ BB count.
+ (switch_decision_tree::do_jump_if_equal): Likewise.
+ (switch_decision_tree::emit_case_nodes): Handle special case
+ for BT expansion which can also fallback to a default BB.
+ * tree-switch-conversion.h (cluster::cluster): Add
+ m_default_prob probability.
+
+2022-11-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107919
+ * gimple-predicate-analysis.cc (simplify_1): Rename to ...
+ (simplify_1a): .. this.
+ (simplify_1b): New.
+ (predicate::simplify): Call both simplify_1a and simplify_1b.
+
+2022-11-30 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-uninit.cc (find_uninit_use): Dump the edge for a
+ PHI node.
+
+2022-11-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107919
+ * gimple-predicate-analysis.cc (predicate::simplify_2):
+ Handle predicates of arbitrary length.
+
+2022-11-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107835
+ * tree-chrec.cc (chrec_apply): Don't handle "{a, +, a} (x-1)"
+ as "a*x" if type is a pointer type.
+
+2022-11-30 Paul-Antoine Arras <pa@codesourcery.com>
+
+ * config/gcn/gcn.cc (gcn_omp_device_kind_arch_isa): Add gfx803.
+ * config/gcn/t-omp-device: Add gfx803.
+
+2022-11-30 Lulu Cheng <chenglulu@loongson.cn>
+
+ * config/loongarch/linux.h (STACK_CHECK_MOVING_SP):
+ Define this macro to 1.
+ * config/loongarch/loongarch.cc (STACK_CLASH_PROTECTION_GUARD_SIZE):
+ Size of guard page.
+ (loongarch_first_stack_step): Return the size of the first drop stack
+ according to whether stack checking is performed.
+ (loongarch_emit_probe_stack_range): Adjust the method of stack checking in prologue.
+ (loongarch_output_probe_stack_range): Delete useless code.
+ (loongarch_expand_prologue): Adjust the method of stack checking in prologue.
+ (loongarch_option_override_internal): Enforce that interval is the same
+ size as size so the mid-end does the right thing.
+ * config/loongarch/loongarch.h (STACK_CLASH_MAX_UNROLL_PAGES):
+ New macro decide whether to loop stack detection.
+
+2022-11-30 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/103546
+ * doc/invoke.texi (Static Analyzer Options): Add isatty, ferror,
+ fileno, and getc to the list of functions known to the analyzer.
+
+2022-11-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107852
+ * tree-ssa-sccvn.cc (visit_phi): Use equivalences recorded
+ as predicated values to elide more redundant PHIs.
+
+2022-11-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/106995
+ * tree-if-conv.cc (pass_if_conversion::execute): Also redirect the
+ versioning condition to the original loop if this very loop
+ vanished during CFG cleanup.
+
+2022-11-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107898
+ * gimple-ssa-warn-alloca.cc (alloca_call_type): Check
+ the type of the alloca argument is compatible with size_t
+ before querying ranges.
+
+2022-11-29 Richard Biener <rguenther@suse.de>
+
+ PR ipa/107897
+ * multiple_target.cc (pass_target_clone::gate): Disable
+ after errors.
+
+2022-11-29 Martin Liska <mliska@suse.cz>
+
+ * configure: Regenerate.
+
+2022-11-29 YunQiang Su <yunqiang.su@cipunited.com>
+
+ * configure.ac: add description for
+ AC_DEFINE(ENABLE_MULTIARCH, 1)
+
+2022-11-28 Andrew Pinski <apinski@marvell.com>
+
+ * match.pd ((A / (1 << B)) -> (A >> B).):
+ Fix comment.
+
+2022-11-28 Sinan <sinan.lin@linux.alibaba.com>
+
+ * config/riscv/riscv.cc (riscv_build_integer): Improve some cases
+ of loading 64bit constants for rv32.
+
+2022-11-28 Maciej W. Rozycki <macro@embecosm.com>
+
+ * config/riscv/riscv.cc (riscv_emit_int_order_test): Use EQ 0
+ rather that XOR 1 for LE and LEU operations.
+
+2022-11-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107896
+ * tree-vect-stmts.cc (supportable_widening_operation):
+ Handle non-vector mode intermediate mode.
+
+2022-11-28 Frolov Daniil <frolov.da@phystech.edu>
+
+ * gimple-ssa-sprintf.cc (fmtresult::type_max_digits): Handle
+ base == 2.
+ (tree_digits): Likewise.
+ (format_integer): Likewise.
+ (parse_directive): Add cases for %b and %B directives.
+
+2022-11-28 Fei Gao <gaofei@eswincomputing.com>
+
+ * config/riscv/riscv.cc (riscv_first_stack_step): Fix computation
+ of MIN_FIRST_STEP to cover FP save area too.
+
+2022-11-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107493
+ * tree-scalar-evolution.cc (scev_dfs::follow_ssa_edge_expr):
+ Only handle no-op and sign-changing conversions.
+
+2022-11-28 Tobias Burnus <tobias@codesourcery.com>
+
+ * config/gcn/gcn.cc (gcn_expand_builtin_1): Work on s1 instead
+ of s[0:1] and use USE to prevent removal of setting that register.
+ * config/gcn/gcn.md (prologue_use_di): Remove.
+
+2022-11-28 Yuri Gribov <y.gribov@samsung.com>
+
+ PR sanitizer/106558
+ * sanopt.cc: Do not optimize out checks for non-SSA addresses.
+
+2022-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/106875
+ * config/i386/i386.opt (x_ix86_abi): Remove TargetSave.
+ (ix86_abi): Replace it with TargetVariable.
+ * config/i386/i386-options.cc (ix86_function_specific_save,
+ ix86_function_specific_restore): Don't save and restore x_ix86_abi.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * config/arm/mve.md (mve_vrmlaldavhq_<supf>v4si,
+ mve_vrmlaldavhaq_<supf>v4si): Fix spacing vs tabs.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * config/arm/mve.md (mve_vmlaldavaq_<supf><mode>)
+ (mve_vmlaldavaxq_s<mode>, mve_vmlaldavaxq_p_<supf><mode>): Fix
+ spacing vs tabs.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * config/arm/mve.md (mve_vsubq_n_f<mode>): Fix spacing.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * config/arm/mve.md (mve_vaddlvq_p_<supf>v4si)
+ (mve_vaddq_n_<supf><mode>, mve_vaddvaq_<supf><mode>)
+ (mve_vaddlvaq_<supf>v4si, mve_vaddq_n_f<mode>)
+ (mve_vaddlvaq_p_<supf>v4si, mve_vaddq<mode>, mve_vaddq_f<mode>):
+ Fix spacing.
+
+2022-11-28 Stam Markianos-Wright <stam.markianos-wright@arm.com>
+
+ * config/arm/arm_mve.h (__arm_vsubq_x FP): New overloads.
+ (__arm_vsubq_x Integer): New.
+
+2022-11-28 Stam Markianos-Wright <stam.markianos-wright@arm.com>
+
+ PR target/107515
+ * config/arm/arm_mve.h (__ARM_mve_typeid): Add float types.
+
+2022-11-28 Stam Markianos-Wright <stam.markianos-wright@arm.com>
+
+ PR target/96795
+ * config/arm/arm_mve.h (__arm_vaddq): Fix Overloading.
+ (__arm_vmulq): Likewise.
+ (__arm_vcmpeqq): Likewise.
+ (__arm_vcmpneq): Likewise.
+ (__arm_vmaxnmavq): Likewise.
+ (__arm_vmaxnmvq): Likewise.
+ (__arm_vminnmavq): Likewise.
+ (__arm_vsubq): Likewise.
+ (__arm_vminnmvq): Likewise.
+ (__arm_vrshlq): Likewise.
+ (__arm_vqsubq): Likewise.
+ (__arm_vqdmulltq): Likewise.
+ (__arm_vqdmullbq): Likewise.
+ (__arm_vqdmulhq): Likewise.
+ (__arm_vqaddq): Likewise.
+ (__arm_vhaddq): Likewise.
+ (__arm_vhsubq): Likewise.
+ (__arm_vqdmlashq): Likewise.
+ (__arm_vqrdmlahq): Likewise.
+ (__arm_vmlasq): Likewise.
+ (__arm_vqdmlahq): Likewise.
+ (__arm_vmaxnmavq_p): Likewise.
+ (__arm_vmaxnmvq_p): Likewise.
+ (__arm_vminnmavq_p): Likewise.
+ (__arm_vminnmvq_p): Likewise.
+ (__arm_vfmasq_m): Likewise.
+ (__arm_vsetq_lane): Likewise.
+ (__arm_vcmpneq_m): Likewise.
+ (__arm_vhaddq_x): Likewise.
+ (__arm_vhsubq_x): Likewise.
+ (__arm_vqrdmlashq_m): Likewise.
+ (__arm_vqdmlashq_m): Likewise.
+ (__arm_vmlaldavaxq_p): Likewise.
+ (__arm_vmlasq_m): Likewise.
+ (__arm_vqdmulhq_m): Likewise.
+ (__arm_vqdmulltq_m): Likewise.
+ (__arm_viwdupq_m): Likewise.
+ (__arm_viwdupq_u16): Likewise.
+ (__arm_viwdupq_u32): Likewise.
+ (__arm_viwdupq_u8): Likewise.
+ (__arm_vdwdupq_m): Likewise.
+ (__arm_vdwdupq_u16): Likewise.
+ (__arm_vdwdupq_u32): Likewise.
+ (__arm_vdwdupq_u8): Likewise.
+ (__arm_vaddlvaq): Likewise.
+ (__arm_vaddlvaq_p): Likewise.
+ (__arm_vaddvaq): Likewise.
+ (__arm_vaddvaq_p): Likewise.
+ (__arm_vcmphiq_m): Likewise.
+ (__arm_vmladavaq_p): Likewise.
+ (__arm_vmladavaxq): Likewise.
+ (__arm_vmlaldavaxq): Likewise.
+ (__arm_vrmlaldavhaq_p): Likewise.
+
+2022-11-28 Stam Markianos-Wright <stam.markianos-wright@arm.com>
+
+ PR target/96795
+ * config/arm/arm_mve.h (__arm_vaddq_m_n_s8): Change types.
+ (__arm_vaddq_m_n_s32): Likewise.
+ (__arm_vaddq_m_n_s16): Likewise.
+ (__arm_vaddq_m_n_u8): Likewise.
+ (__arm_vaddq_m_n_u32): Likewise.
+ (__arm_vaddq_m_n_u16): Likewise.
+ (__arm_vaddq_m): Fix Overloading.
+ (__ARM_mve_coerce3): New.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * config/arm/mve.md (mve_vabsq_f<mode>): Fix spacing.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * config/arm/mve.md (@mve_vcmp<mve_cmp_op>q_<mode>): Fix
+ spacing.
+ * config/arm/arm_mve.h (__arm_vcmpgtq_m, __arm_vcmpleq_m)
+ (__arm_vcmpltq_m, __arm_vcmpneq_m): Add missing defines.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * config/arm/mve.md (mve_vdupq_n_f<mode>)
+ (mve_vdupq_n_<supf><mode>, mve_vdupq_m_n_<supf><mode>)
+ (mve_vdupq_m_n_f<mode>): Fix spacing.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * config/arm/mve.md (mve_vdwdupq_m_wb_u<mode>_insn): Fix spacing.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * config/arm/mve.md (mve_vddupq_u<mode>_insn): Fix 'vddup.u'
+ spacing.
+ (mve_vddupq_m_wb_u<mode>_insn): Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * config/arm/vfp.md (*thumb2_movhi_vfp, *thumb2_movhi_fp16): Fix
+ 'vmsr' spacing and reg capitalization.
+
+2022-11-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107876
+ * tree-ssa-loop-unswitch.cc (clean_up_after_unswitching): Wipe
+ dominator info if we removed an edge.
+
+2022-11-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107867
+ * tree-ssa-forwprop.cc (pass_forwprop::execute): Handle
+ abnormal cleanup after substitution.
+
+2022-11-28 Lulu Cheng <chenglulu@loongson.cn>
+
+ * config/loongarch/loongarch.cc (enum loongarch_load_imm_method):
+ Remove the member METHOD_INSV that is not currently used.
+ (struct loongarch_integer_op): Define a new member curr_value,
+ that records the value of the number stored in the destination
+ register immediately after the current instruction has run.
+ (loongarch_build_integer): Assign a value to the curr_value member variable.
+ (loongarch_move_integer): Adds information for the immediate load instruction.
+ * config/loongarch/loongarch.md (*movdi_32bit): Redefine as define_insn_and_split.
+ (*movdi_64bit): Likewise.
+ (*movsi_internal): Likewise.
+ (*movhi_internal): Likewise.
+ * config/loongarch/predicates.md: Return true as long as it is CONST_INT, ensure
+ that the immediate number is not optimized by decomposition during expand
+ optimization loop.
+
+2022-11-28 liuhongt <hongtao.liu@intel.com>
+
+ PR target/107748
+ * config/i386/avx512bf16intrin.h (_mm_cvtsbh_ss): Refined.
+ * config/i386/i386-builtin-types.def (FLOAT_FTYPE_BFLOAT16):
+ New function type.
+ * config/i386/i386-builtin.def (BDESC): New builtin.
+ * config/i386/i386-expand.cc (ix86_expand_args_builtin):
+ Handle the builtin.
+ * config/i386/i386.md (extendbfsf2): New expander.
+ (extendbfsf2_1): New define_insn.
+ (truncsfbf2): Ditto.
+
+2022-11-26 Andrew Pinski <apinski@marvell.com>
+
+ PR tree-optimization/103356
+ * match.pd: ((~a) == b -> a ^ b): New pattern.
+
+2022-11-25 Sandra Loosemore <sandra@codesourcery.com>
+
+ * common.opt (fopenmp-target-simd-clone): New option.
+ (target_simd_clone_device): New enum to go with it.
+ * doc/invoke.texi (-fopenmp-target-simd-clone): Document.
+ * flag-types.h (enum omp_target_simd_clone_device_kind): New.
+ * omp-simd-clone.cc (auto_simd_fail): New function.
+ (auto_simd_check_stmt): New function.
+ (plausible_type_for_simd_clone): New function.
+ (ok_for_auto_simd_clone): New function.
+ (simd_clone_create): Add force_local argument, make the symbol
+ have internal linkage if it is true.
+ (expand_simd_clones): Also check for cloneable functions with
+ "omp declare target". Pass explicit_p argument to
+ simd_clone.compute_vecsize_and_simdlen target hook.
+ * opts.cc (default_options_table): Add -fopenmp-target-simd-clone.
+ * target.def (TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN):
+ Add bool explicit_p argument.
+ * doc/tm.texi: Regenerated.
+ * config/aarch64/aarch64.cc
+ (aarch64_simd_clone_compute_vecsize_and_simdlen): Update.
+ * config/gcn/gcn.cc
+ (gcn_simd_clone_compute_vecsize_and_simdlen): Update.
+ * config/i386/i386.cc
+ (ix86_simd_clone_compute_vecsize_and_simdlen): Update.
+
+2022-11-25 Tamar Christina <tamar.christina@arm.com>
+
+ PR target/107830
+ * config/aarch64/aarch64.cc
+ (aarch64_vectorize_can_special_div_by_constant): Check validity during
+ codegen phase as well.
+
+2022-11-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * range-op.cc (operator_bitwise_xor::op1_range): Fix thinko.
+
+2022-11-25 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107865
+ * tree-cfg.cc (move_sese_region_to_fn): Free the number of
+ iterations of moved loops.
+
+2022-11-25 Kewen.Lin <linkw@gcc.gnu.org>
+
+ PR target/99889
+ * config/rs6000/rs6000.cc (rs6000_print_patchable_function_entry):
+ Adjust to call function default_print_patchable_function_entry.
+ * targhooks.cc (default_print_patchable_function_entry_1): Remove and
+ move the flags preparation ...
+ (default_print_patchable_function_entry): ... here, adjust to use
+ current_function_funcdef_no for label no.
+ * targhooks.h (default_print_patchable_function_entry_1): Remove.
+ * varasm.cc (default_elf_asm_named_section): Adjust code for
+ __patchable_function_entries section support with LPFE label.
+
+2022-11-24 Wilco Dijkstra <wilco.dijkstra@arm.com>
+
+ PR tree-optimization/107413
+ * config/aarch64/aarch64.cc (struct tune_params): Add
+ fma_reassoc_width to all CPU tuning structures.
+ (aarch64_reassociation_width): Use fma_reassoc_width.
+ * config/aarch64/aarch64-protos.h (struct tune_params): Add
+ fma_reassoc_width.
+
+2022-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/107317
+ * asan.cc: Include diagnostic-core.h.
+ (asan_emit_stack_protection): Return NULL early if seen_error ().
+
+2022-11-24 Aldy Hernandez <aldyh@redhat.com>
+
+ * vr-values.cc (simplify_using_ranges::compare_names): Remove.
+ (vrp_evaluate_conditional_warnv_with_ops): Remove call to
+ compare_names.
+ (simplify_using_ranges::vrp_visit_cond_stmt): Remove use_equiv_p
+ argument to vrp_evaluate_conditional_warnv_with_ops.
+ * vr-values.h (class simplify_using_ranges): Remove
+ compare_names.
+ Remove use_equiv_p to vrp_evaluate_conditional_warnv_with_ops.
+
+2022-11-24 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-vrp.cc (overflow_comparison_p_1): Remove follow_assert_exprs.
+ (overflow_comparison_p): Remove use_equiv_p.
+ * tree-vrp.h (overflow_comparison_p): Same.
+ * vr-values.cc (vrp_evaluate_conditional_warnv_with_ops): Remove
+ use_equiv_p argument to overflow_comparison_p.
+
+2022-11-24 Aldy Hernandez <aldyh@redhat.com>
+
+ * doc/gimple.texi: Remove ASSERT_EXPR references.
+ * fold-const.cc (tree_expr_nonzero_warnv_p): Same.
+ (fold_binary_loc): Same.
+ (tree_expr_nonnegative_warnv_p): Same.
+ * gimple-array-bounds.cc (get_base_decl): Same.
+ * gimple-pretty-print.cc (dump_unary_rhs): Same.
+ * gimple.cc (get_gimple_rhs_num_ops): Same.
+ * pointer-query.cc (handle_ssa_name): Same.
+ * tree-cfg.cc (verify_gimple_assign_single): Same.
+ * tree-pretty-print.cc (dump_generic_node): Same.
+ * tree-scalar-evolution.cc (scev_dfs::follow_ssa_edge_expr):Same.
+ (interpret_rhs_expr): Same.
+ * tree-ssa-operands.cc (operands_scanner::get_expr_operands): Same.
+ * tree-ssa-propagate.cc
+ (substitute_and_fold_dom_walker::before_dom_children): Same.
+ * tree-ssa-threadedge.cc: Same.
+ * tree-vrp.cc (overflow_comparison_p): Same.
+ * tree.def (ASSERT_EXPR): Add note.
+ * tree.h (ASSERT_EXPR_VAR): Remove.
+ (ASSERT_EXPR_COND): Remove.
+ * vr-values.cc (simplify_using_ranges::vrp_visit_cond_stmt):
+ Remove comment.
+
+2022-11-24 Aldy Hernandez <aldyh@redhat.com>
+
+ * Makefile.in: Remove value-range-equiv.o
+ * gimple-array-bounds.cc
+ (array_bounds_checker::array_bounds_checker): Remove comment.
+ * tree-vrp.cc (supported_types_p): Remove use of value_range_equiv.
+ * value-query.cc (class equiv_allocator): Same.
+ (range_query::allocate_value_range_equiv): Remove.
+ (range_query::free_value_range_equiv): Remove.
+ (range_query::get_value_range): Remove.
+ * value-query.h (class range_query): Remove get_value_range.
+ Remove allocate_value_range_equiv.
+ Remove free_value_range_equiv.
+ * vr-values.cc (compare_ranges): Replace value_range_equiv with
+ value_range.
+ (simplify_using_ranges::get_vr_for_comparison): Same.
+ (simplify_using_ranges::compare_names): Same.
+ * vr-values.h: Remove value_range_equiv references.
+ * value-range-equiv.cc: Removed.
+ * value-range-equiv.h: Removed.
+
+2022-11-24 Aldy Hernandez <aldyh@redhat.com>
+
+ * doc/invoke.texi: Remove docs for max-vrp-switch-assertions,
+ vrp1-mode, and vrp2-mode.
+ * params.opt: Same.
+ * range-op.cc (masked_increment): Move from tree-vrp.cc.
+ * tree-vrp.cc (class live_names): Remove.
+ (live_names::init_bitmap_if_needed): Remove.
+ (live_names::block_has_live_names_p): Remove.
+ (live_names::clear_block): Remove.
+ (live_names::merge): Remove.
+ (live_names::set): Remove.
+ (live_names::clear): Remove.
+ (live_names::live_names): Remove.
+ (live_names::~live_names): Remove.
+ (live_names::live_on_block_p): Remove.
+ (live_names::live_on_edge_p): Remove.
+ (get_single_symbol): Make static.
+ (build_symbolic_expr): Remove.
+ (adjust_symbolic_bound): Remove.
+ (combine_bound): Remove.
+ (set_value_range_with_overflow): Remove.
+ (extract_range_from_pointer_plus_expr): Remove.
+ (extract_range_from_plus_minus_expr): Remove.
+ (drop_undefines_to_varying): Remove.
+ (range_fold_binary_symbolics_p): Remove.
+ (range_fold_unary_symbolics_p): Remove.
+ (range_fold_binary_expr): Remove.
+ (infer_value_range): Remove.
+ (dump_assert_info): Remove.
+ (dump_asserts_info): Remove.
+ (add_assert_info): Remove.
+ (extract_code_and_val_from_cond_with_ops): Remove.
+ (masked_increment): Move to range-op.cc.
+ (register_edge_assert_for_2): Remove.
+ (find_case_label_index): Remove.
+ (find_case_label_range): Remove.
+ (register_edge_assert_for_1): Remove.
+ (is_masked_range_test): Remove.
+ (register_edge_assert_for): Remove.
+ (stmt_interesting_for_vrp): Remove.
+ (struct case_info): Remove.
+ (struct assert_locus): Remove.
+ (class vrp_asserts): Remove.
+ (vrp_asserts::build_assert_expr_for): Remove.
+ (vrp_asserts::dump): Remove.
+ (vrp_asserts::register_new_assert_for): Remove.
+ (vrp_asserts::finish_register_edge_assert_for): Remove.
+ (vrp_asserts::find_conditional_asserts): Remove.
+ (vrp_asserts::compare_case_labels): Remove.
+ (vrp_asserts::find_switch_asserts): Remove.
+ (vrp_asserts::find_assert_locations_in_bb): Remove.
+ (vrp_asserts::find_assert_locations): Remove.
+ (vrp_asserts::process_assert_insertions_for): Remove.
+ (vrp_asserts::compare_assert_loc): Remove.
+ (vrp_asserts::process_assert_insertions): Remove.
+ (vrp_asserts::insert_range_assertions): Remove.
+ (vrp_asserts::all_imm_uses_in_stmt_or_feed_cond): Remove.
+ (vrp_asserts::remove_range_assertions): Remove.
+ (class vrp_prop): Remove.
+ (vrp_prop::initialize): Remove.
+ (enum ssa_prop_result): Remove.
+ (vrp_prop::visit_stmt): Remove.
+ (vrp_prop::visit_phi): Remove.
+ (vrp_prop::finalize): Remove.
+ (class vrp_folder): Remove.
+ (vrp_folder::fold_predicate_in): Remove.
+ (vrp_folder::fold_stmt): Remove.
+ (vrp_folder::simplify_casted_conds): Remove.
+ (execute_vrp): Remove.
+ * tree-vrp.h (struct assert_info): Remove.
+ (register_edge_assert_for): Remove.
+ (stmt_interesting_for_vrp): Remove.
+ (infer_value_range): Remove.
+ (get_single_symbol): Remove.
+ (masked_increment): Remove.
+ (execute_ranger_vrp): Remove.
+ * vr-values.cc (set_value_range_to_nonnegative): Remove.
+ (set_value_range_to_truthvalue): Remove.
+ (vr_values::get_lattice_entry): Remove.
+ (vr_values::get_value_range): Remove.
+ (vr_values::range_of_expr): Remove.
+ (vr_values::value_of_expr): Remove.
+ (vr_values::value_on_edge): Remove.
+ (vr_values::value_of_stmt): Remove.
+ (vr_values::set_def_to_varying): Remove.
+ (vr_values::set_defs_to_varying): Remove.
+ (vr_values::update_value_range): Remove.
+ (symbolic_range_based_on_p): Remove.
+ (gimple_assign_nonzero_p): Remove.
+ (gimple_stmt_nonzero_p): Remove.
+ (vr_values::vrp_stmt_computes_nonzero): Remove.
+ (vr_values::op_with_constant_singleton_value_range): Remove.
+ (vr_values::extract_range_for_var_from_comparison_expr): Remove.
+ (vr_values::extract_range_from_assert): Remove.
+ (vr_values::extract_range_from_ssa_name): Remove.
+ (vr_values::extract_range_from_binary_expr): Remove.
+ (vr_values::extract_range_from_unary_expr): Remove.
+ (vr_values::extract_range_from_cond_expr): Remove.
+ (vr_values::extract_range_from_comparison): Remove.
+ (vr_values::extract_range_from_ubsan_builtin): Remove.
+ (vr_values::extract_range_basic): Remove.
+ (vr_values::extract_range_from_assignment): Remove.
+ (vr_values::adjust_range_with_scev): Remove.
+ (vr_values::dump): Remove.
+ (vr_values::vr_values): Remove.
+ (vr_values::~vr_values): Remove.
+ (vrp_valueize): Remove.
+ (vrp_valueize_1): Remove.
+ (get_output_for_vrp): Remove.
+ (vr_values::vrp_visit_assignment_or_call): Remove.
+ (simplify_using_ranges::vrp_evaluate_conditional): Remove.
+ (vr_values::vrp_visit_switch_stmt): Remove.
+ (vr_values::extract_range_from_stmt): Remove.
+ (vr_values::extract_range_from_phi_node): Remove.
+ (simplify_using_ranges::fold_cond): Add FIXME note.
+ (vr_values::set_vr_value): Remove.
+ (vr_values::swap_vr_value): Remove.
+ * vr-values.h (class vr_values): Remove.
+ (get_output_for_vrp): Remove.
+
+2022-11-24 Hongyu Wang <hongyu.wang@intel.com>
+
+ PR target/107692
+ * common/config/i386/i386-common.cc (ix86_optimization_table):
+ Enable loop unroll O2, disable -fweb and -frename-registers
+ by default.
+ * config/i386/i386-options.cc
+ (ix86_override_options_after_change):
+ Disable small loop unroll when funroll-loops enabled, reset
+ cunroll_grow_size when it is not explicitly enabled.
+ (ix86_option_override_internal): Call
+ ix86_override_options_after_change instead of calling
+ ix86_recompute_optlev_based_flags and ix86_default_align
+ separately.
+ * config/i386/i386.cc (ix86_loop_unroll_adjust): Adjust unroll
+ factor if -munroll-only-small-loops enabled.
+ * loop-init.cc (pass_rtl_unroll_loops::gate): Do not enable
+ loop unrolling for -O2-speed.
+ (pass_rtl_unroll_loops::execute): Rmove
+ targetm.loop_unroll_adjust check.
+
+2022-11-23 Ramana Radhakrishnan <ramana.gcc@gmail.com>
+
+ * config/arm/types.md: Update comment.
+ (is_neon_type): Add neon_fcmla, neon_fcadd.
+
+2022-11-23 Jonathan Wakely <jwakely@redhat.com>
+
+ * doc/invoke.texi (C++ Dialect Options): Recommend using
+ -Wdelete-non-virtual-dtor instead of -Wnon-virtual-dtor.
+
+2022-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR bootstrap/107722
+ * diagnostic.cc (test_diagnostic_get_location_text): Test
+ special_fname_builtin () rather than "<built-in>" and expect
+ special_fname_builtin () concatenated with ":" for it.
+
+2022-11-23 Martin Liska <mliska@suse.cz>
+
+ * Makefile.in: Set DO_LINK_MUTEX.
+
+2022-11-23 Lulu Cheng <chenglulu@loongson.cn>
+ xujiahao <xujiahao@loongson.cn>
+
+ * config/loongarch/constraints.md (ZD): New constraint.
+ * config/loongarch/loongarch-def.c: Initial number of parallel prefetch.
+ * config/loongarch/loongarch-tune.h (struct loongarch_cache):
+ Define number of parallel prefetch.
+ * config/loongarch/loongarch.cc (loongarch_option_override_internal):
+ Set up parameters to be used in prefetching algorithm.
+ * config/loongarch/loongarch.md (prefetch): New template.
+
+2022-11-23 Marek Polacek <polacek@redhat.com>
+
+ Revert:
+ 2022-11-23 Marek Polacek <polacek@redhat.com>
+
+ * Makefile.in: Set LD_PICFLAG. Use it. Set enable_host_pie.
+ Remove NO_PIE_CFLAGS and NO_PIE_FLAG. Pass LD_PICFLAG to
+ ALL_LINKERFLAGS. Use the "pic" build of libiberty if --enable-host-pie.
+ * configure.ac (--enable-host-shared): Don't set PICFLAG here.
+ (--enable-host-pie): New check. Set PICFLAG and LD_PICFLAG after this
+ check.
+ * configure: Regenerate.
+ * doc/install.texi: Document --enable-host-pie.
+
+2022-11-23 Marek Polacek <polacek@redhat.com>
+
+ Revert:
+ 2022-11-23 Marek Polacek <polacek@redhat.com>
+
+ * configure.ac (--enable-host-bind-now): New check. Add
+ -Wl,-z,now to LD_PICFLAG if --enable-host-bind-now.
+ * configure: Regenerate.
+ * doc/install.texi: Document --enable-host-bind-now.
+
+2022-11-23 Marek Polacek <polacek@redhat.com>
+
+ * configure.ac (--enable-host-bind-now): New check. Add
+ -Wl,-z,now to LD_PICFLAG if --enable-host-bind-now.
+ * configure: Regenerate.
+ * doc/install.texi: Document --enable-host-bind-now.
+
+2022-11-23 Marek Polacek <polacek@redhat.com>
+
+ * Makefile.in: Set LD_PICFLAG. Use it. Set enable_host_pie.
+ Remove NO_PIE_CFLAGS and NO_PIE_FLAG. Pass LD_PICFLAG to
+ ALL_LINKERFLAGS. Use the "pic" build of libiberty if --enable-host-pie.
+ * configure.ac (--enable-host-shared): Don't set PICFLAG here.
+ (--enable-host-pie): New check. Set PICFLAG and LD_PICFLAG after this
+ check.
+ * configure: Regenerate.
+ * doc/install.texi: Document --enable-host-pie.
+
+2022-11-22 Jeff Law <jlaw@ventanamicro.com>
+
+ * tree-ssa-dom.cc (record_edge_info): Fix thinko in last commit.
+
+2022-11-22 Jeff Law <jlaw@ventanamicro.com>
+
+ * tree-ssa-dom.cc (record_edge_info): Fix comment typos.
+
+2022-11-22 Jeff Law <jeffreyalaw@gmail.com>
+
+ * config/riscv/riscv.cc (riscv_get_separate_components): Do not
+ do shrink-wrapping for a frame with a variable size.
+
+2022-11-22 Siddhesh Poyarekar <siddhesh@gotplt.org>
+
+ * tree-object-size.cc (todo): New variable.
+ (object_sizes_execute): Use it.
+ (strdup_object_size): New function.
+ (call_object_size): Use it.
+
+2022-11-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-loop-distribution.cc (loop_distribution::classify_builtin_ldst):
+ Bail out if source and destination do not have the same storage order.
+
+2022-11-22 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-sra.cc (ipa_sra_dump_all_summaries): Dump edge summaries even
+ for non-candidates.
+
+2022-11-22 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-cp.cc (push_agg_values_from_edge): Do not consider constants
+ in unused aggregate parameters.
+
+2022-11-22 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-param-manipulation.h (ipa_param_body_adjustments): Removed
+ member m_split_modifications_p.
+ * ipa-param-manipulation.cc
+ (ipa_param_body_adjustments::common_initialization): Do not set
+ m_split_modifications_p.
+ (ipa_param_body_adjustments::ipa_param_body_adjustments): Remove
+ initializations of m_split_modifications_p.
+ (ipa_param_body_adjustments::modify_call_stmt): Check that
+ m_replacements is empty instead of m_split_modifications_p.
+
+2022-11-22 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/107661
+ * ipa-cp.cc (push_agg_values_from_edge): New parameter
+ optimize_self_recursion, use it to decide whether to pass interim to
+ the helper function.
+ (find_aggregate_values_for_callers_subset): Pass true in the new
+ parameter of push_agg_values_from_edge.
+ (cgraph_edge_brings_all_agg_vals_for_node): Pass false in the new
+ parameter of push_agg_values_from_edge.
+
+2022-11-22 Tobias Burnus <tobias@codesourcery.com>
+ Andrew Stubbs <ams@codesourcery.com>
+
+ * config/gcn/gcn-builtins.def (FIRST_CALL_THIS_THREAD_P,
+ GET_STACK_LIMIT): Add new builtins.
+ * config/gcn/gcn.cc (gcn_expand_builtin_1): Expand them.
+ * config/gcn/gcn.md (prologue_use): Add "register_operand" as
+ arg to match_operand.
+ (prologue_use_di): New; DI insn_and_split variant of the former.
+
+2022-11-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107803
+ * tree-ssa-propagate.cc (substitute_and_fold_dom_walker): Add
+ need_ab_cleanup member.
+ (substitute_and_fold_dom_walker::before_dom_children): When
+ a stmt can no longer transfer control flow abnormally set
+ need_ab_cleanup.
+ (substitute_and_fold_engine::substitute_and_fold): Cleanup
+ abnormal control flow.
+
+2022-11-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107672
+ * tree-vect-stmts.cc (supportable_widening_operation): Avoid
+ type_for_mode on vector modes.
+
+2022-11-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107766
+ * tree-vect-slp-patterns.cc (complex_mul_pattern::matches):
+ Use *node to check for FP vector types.
+
+2022-11-22 liuhongt <hongtao.liu@intel.com>
+
+ * config/i386/mmx.md (*mov<mode>_internal): Add
+ ix86_hard_reg_move_ok to condition.
+
+2022-11-22 liuhongt <hongtao.liu@intel.com>
+
+ * config/i386/i386.cc (ix86_can_change_mode_class): Also guard
+ size of TO.
+ (ix86_hard_regno_mode_ok): Remove VALID_AVX512FP16_SCALAR_MODE
+ * config/i386/i386.h (VALID_AVX512FP16_SCALAR_MODE): Merged to
+ ..
+ (VALID_AVX512F_SCALAR_MODE): .. this, also add HImode.
+ (VALID_SSE_REG_MODE): Add DI/HImode.
+
+2022-11-21 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * config/rtems.h (SUBTARGET_CC1_SPEC): Undef and define.
+
+2022-11-21 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * gcc.cc (SUBTARGET_CC1_SPEC): Define if not defined.
+ (cc1_spec): Append SUBTARGET_CC1_SPEC.
+
+2022-11-21 Dimitar Dimitrov <dimitar@dinux.eu>
+
+ * doc/sourcebuild.texi (sockets): Document new check.
+
+2022-11-21 Andrew Carlotti <andrew.carlotti@arm.com>
+
+ * tree-ssa-loop.h (tree_niter_desc): Update comment.
+
+2022-11-21 Andrew Carlotti <andrew.carlotti@arm.com>
+
+ * tree-ssa-loop-niter.cc
+ (number_of_iterations_exit_assumptions): Modify to call...
+ (number_of_iterations_bitcount): ...this new function.
+ (number_of_iterations_popcount): Now called by the above.
+ Refactor, and extract popcount expression builder to...
+ (build_popcount_expr): this new function.
+
+2022-11-21 Andrew Carlotti <andrew.carlotti@arm.com>
+
+ * tree-ssa-loop-niter.cc (ssa_defined_by_minus_one_stmt_p): Move
+ (number_of_iterations_popcount): Move, and remove separate prototype.
+
+2022-11-21 Andrew Carlotti <andrew.carlotti@arm.com>
+
+ * tree-ssa-loop-niter.cc (number_of_iterations_exit_assumptions):
+ Move at_stmt assignment.
+
+2022-11-21 Christophe Lyon <christophe.lyon@arm.com>
+
+ * genmultilib: Fix options and dirnames/osdirnames sanity check.
+
+2022-11-21 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ PR target/107786
+ * config/riscv/riscv.md
+ (*branch<ANYI:mode>_shiftedarith_equals_zero): Wrap ANYI
+ in a subreg, as our branch instructions only supports X.
+
+2022-11-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/107748
+ * config/i386/avx512fp16intrin.h (_mm512_castph512_ph128,
+ _mm512_castph512_ph256, _mm512_castph128_ph512,
+ _mm512_castph256_ph512, _mm512_set1_pch): Uglify names of local
+ variables and union members.
+ * config/i386/avx512fp16vlintrin.h (_mm256_castph256_ph128,
+ _mm256_castph128_ph256, _mm256_set1_pch, _mm_set1_pch): Likewise.
+ * config/i386/smmintrin.h (_mm_extract_ps): Likewise.
+
+2022-11-21 Christophe Lyon <christophe.lyon@arm.com>
+
+ * genmultilib: Add sanity check.
+
+2022-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config/arm/arm.cc (arm_attribute_table) <cmse_nonsecure_call>:
+ Change decl_required field to false.
+ (arm_handle_cmse_nonsecure_call): Deal with a TYPE node.
+
+2022-11-21 Andrew Pinski <apinski@marvell.com>
+
+ * gimplify.cc (gimplify_modify_expr): If
+ either *from_p or *to_p were error_operand
+ return early.
+
+2022-11-21 liuhongt <hongtao.liu@intel.com>
+
+ * config/i386/i386-builtins.cc (def_builtin): Handle "shared"
+ avx512bf16vl-avxneconvert builtins.
+
+2022-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/107183
+ * reg-stack.cc (next_flags_user): Add DEBUG_SEEN argument.
+ If >= 0 and a DEBUG_INSN would be otherwise returned, set
+ DEBUG_SEEN to 1 and ignore it.
+ (swap_rtx_condition): Add DEBUG_SEEN argument. In >= 0
+ mode only set DEBUG_SEEN to 1 if problematic DEBUG_ISNSs
+ were seen and revert all changes on success in that case.
+ Don't try to recog_memoized DEBUG_INSNs.
+ (compare_for_stack_reg): Adjust swap_rtx_condition caller.
+ If it returns true and debug_seen is 1, call swap_rtx_condition
+ again with debug_seen -1.
+
+2022-11-20 Jeff Law <jlaw@ventanamicro.com>
+
+ PR other/104044
+ * config/mn10300/mn10300.cc (mn10300_print_operand): Remove
+ extraneous semicolon.
+ * config/nvptx/nvptx.cc (nvptx_goacc_reduction_fini): Likewise.
+
+2022-11-19 Andrew Pinski <apinski@marvell.com>
+
+ PR middle-end/14840
+ * tree-core.h (tree_code_type): Constexprify
+ by including all-tree.def.
+ (tree_code_length): Likewise.
+ * tree.cc (tree_code_type): Remove.
+ (tree_code_length): Remove.
+
+2022-11-19 Thomas Schwinge <thomas@codesourcery.com>
+
+ * config/nvptx/nvptx.h (STARTFILE_SPEC): Fix 'crt0.o' for
+ '-mmainkernel'.
+
+2022-11-19 Jonathan Wakely <jwakely@redhat.com>
+ LIU Hao <lh_mouse@126.com>
+
+ * system.h [INCLUDE_MUTEX]: Include header for std::mutex.
+
+2022-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/107628
+ * config/i386/i386-protos.h (ix86_expand_fast_convert_bf_to_sf):
+ Declare.
+ * config/i386/i386-expand.cc (ix86_expand_fast_convert_bf_to_sf): New
+ function.
+ * config/i386/i386.md (cbranchbf4, cstorebf4): Use it.
+
+2022-11-19 Jeff Chapman II <jchapman@lock3software.com>
+ Andrew Sutton <asutton@lock3software.com>
+ Andrew Marmaduke <amarmaduke@lock3software.com>
+ Michael Lopez <mlopez@lock3software.com>
+ Jason Merrill <jason@redhat.com>
+
+ * doc/invoke.texi: Document contracts flags.
+
+2022-11-18 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/bitmanip.md (*minmax): Additional pattern for
+ min/max against constants that are extension-invariant.
+ * config/riscv/iterators.md (minmax_optab): Add an iterator
+ that has only min and max rtl.
+
+2022-11-18 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/bitmanip.md
+ (*branch<X:mode>_mask_twobits_equals_singlebit):
+ Handle "if ((a & T) == C)" using Zbs, when T has 2 bits set and C
+ has one of these tow bits set.
+ * config/riscv/predicates.md (const_twobits_not_arith_operand):
+ New predicate.
+
+2022-11-18 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/bitmanip.md (*<or_optab>i<mode>_extrabit):
+ New pattern for binvi+binvi/xori and bseti+bseti/ori
+ (*andi<mode>_extrabit): New pattern for bclri+bclri/andi
+ * config/riscv/iterators.md (any_or): Match or and ior
+ * config/riscv/predicates.md (const_twobits_operand):
+ New predicate.
+ (uimm_extra_bit_operand): New predicate.
+ (uimm_extra_bit_or_twobits): New predicate.
+ (not_uimm_extra_bit_operand): New predicate.
+ (not_uimm_extra_bit_or_nottwobits): New predicate.
+ * config/riscv/riscv.h (UIMM_EXTRA_BIT_OPERAND):
+ Helper for the uimm_extra_bit_operand and
+ not_uimm_extra_bit_operand predicates.
+
+2022-11-18 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/bitmanip.md: Handle corner-cases for combine
+ when chaining slli(.uw)? + addw
+ * config/riscv/riscv-protos.h (riscv_shamt_matches_mask_p):
+ Define prototype.
+ * config/riscv/riscv.cc (riscv_shamt_matches_mask_p):
+ Helper for evaluating the relationship between two operands.
+
+2022-11-18 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/bitmanip.md: Add a define_split to optimize
+ slliw + addiw + divw into sh[123]add + divw.
+
+2022-11-18 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/predicates.md (shifted_const_arith_operand): New predicate.
+ (uimm_extra_bit_operand): New predicate.
+ * config/riscv/riscv.md (*branch<ANYI:mode>_shiftedarith_equals_zero):
+ New pattern.
+ (*branch<ANYI:mode>_shiftedmask_equals_zero): New pattern.
+
+2022-11-18 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/bitmanip.md (*bsetidisi): New pattern.
+
+2022-11-18 Richard Purdie <richard.purdie@linuxfoundation.org>
+
+ * doc/invoke.texi: Document prefix-maps don't affect directives.
+
+2022-11-18 Andrew Pinski <apinski@marvell.com>
+
+ PR middle-end/107705
+ * function.cc (aggregate_value_p): Return 0 if
+ the function type was an error operand.
+
+2022-11-18 Andrew Pinski <apinski@marvell.com>
+
+ PR c/106764
+ PR c/106765
+ PR c/107307
+ * gimplify.cc (gimplify_compound_lval): Return GS_ERROR
+ if gimplify_expr had return GS_ERROR.
+ (gimplify_call_expr): Likewise.
+
+2022-11-18 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/atomics.md (*aarch64_atomic_load<ALLX:mode>_rcpc_sext):
+ Use <GPI:w> for destination format.
+ * config/aarch64/iterators.md (w_sz): Delete.
+
+2022-11-18 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64.h (TARGET_RCPC2): Define.
+ * config/aarch64/atomics.md (*aarch64_atomic_load<ALLX:mode>_rcpc_zext):
+ Adjust output template.
+ (*aarch64_atomic_load<ALLX:mode>_rcpc_sex): Guard on TARGET_RCPC2.
+ Adjust output template.
+ * config/aarch64/iterators.md (w_sz): New mode attr.
+
+2022-11-18 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107647
+ * tree-vect-slp-patterns.cc (addsub_pattern::recognize): Only
+ allow FMA generation with -ffp-contract=fast for FP types.
+ (complex_mul_pattern::matches): Likewise.
+
+2022-11-18 Jinyang He <hejinyang@loongson.cn>
+
+ PR target/107713
+ * config/loongarch/sync.md
+ (atomic_cas_value_exchange_7_<mode>): New define_insn.
+ (atomic_exchange): Use atomic_cas_value_exchange_7_si instead of
+ atomic_cas_value_cmp_and_7_si.
+
+2022-11-17 Andrew Pinski <apinski@marvell.com>
+
+ PR middle-end/107734
+ * match.pd (perm + vector op pattern): Clear the sbitmap before
+ use.
+
+2022-11-17 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/107732
+ * range-op-float.cc (foperator_abs::op1_range): Early exit when
+ result is undefined.
+
+2022-11-17 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/bitmanip.md (*bclri<mode>_nottwobits): New pattern.
+ (*bclridisi_nottwobits): New pattern, handling the sign-bit.
+ * config/riscv/predicates.md (const_nottwobits_operand):
+ New predicate.
+
+2022-11-17 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/bitmanip.md: Add a splitter to generate
+ polarity-reversed masks from a set bit using bexti + addi.
+
+2022-11-17 mtsamis <manolis.tsamis@vrull.eu>
+
+ * config/riscv/riscv.cc (struct machine_function): Add array to store
+ register wrapping information.
+ (riscv_for_each_saved_reg): Skip registers that are wrapped separetely.
+ (riscv_get_separate_components): New function.
+ (riscv_components_for_bb): Likewise.
+ (riscv_disqualify_components): Likewise.
+ (riscv_process_components): Likewise.
+ (riscv_emit_prologue_components): Likewise.
+ (riscv_emit_epilogue_components): Likewise.
+ (riscv_set_handled_components): Likewise.
+ (TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS): Define.
+ (TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB): Likewise.
+ (TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS): Likewise.
+ (TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS): Likewise.
+ (TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS): Likewise.
+ (TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS): Likewise.
+
+2022-11-17 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/atomics.md (*aarch64_atomic_load<ALLX:mode>_rcpc_zext):
+ Add mode size check to condition.
+ (*aarch64_atomic_load<ALLX:mode>_rcpc_sext): Likewise.
+
+2022-11-17 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/68097
+ * gimple-fold.cc (gimple_stmt_nonnegative_warnv_p): Call
+ range_of_stmt for floats.
+
+2022-11-17 Lili Cui <lili.cui@intel.com>
+
+ * config/i386/x86-tune.def
+ (X86_TUNE_AVX256_MOVE_BY_PIECES): Add alderlake.
+ (X86_TUNE_AVX256_STORE_BY_PIECES): Ditto.
+
+2022-11-17 Tamar Christina <tamar.christina@arm.com>
+
+ PR tree-optimization/107717
+ * match.pd: Ensure same SSA_NAME.
+
+2022-11-17 Tamar Christina <tamar.christina@arm.com>
+
+ * match.pd: Replace GET_MODE_WIDER_MODE with
+ custom code.
+
+2022-11-17 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op-float.cc (range_operator_float::fold_range): Make check
+ for maybe_isnan more readable.
+
+2022-11-17 Kewen Lin <linkw@linux.ibm.com>
+
+ * gimple-fold.cc (gimple_fold_partial_load_store_mem_ref): Use
+ tree_fits_shwi_p rather than tree_fits_uhwi_p as bias is signed.
+
+2022-11-17 Jia-Wei Chen <jiawei@iscas.ac.cn>
+
+ * config/riscv/riscv.cc (riscv_expand_epilogue):
+ Do not emit useless add sp, sp, 0 instrutions.
+
+2022-11-17 Jeff Law <jlaw@ventanamicro.com>
+
+ * config/sh/sh_treg_combine.cc: Include tm-preds.h.
+ (t_reg_operand): Remove bogus prototype.
+ (negt_reg_operand): Likewise.
+
+2022-11-16 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106649
+ * doc/invoke.texi: Document -Winvalid-constexpr.
+
+2022-11-16 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/bitmanip.md: Add split covering
+ "(a & (1 << BIT_NO)) ? 0 : 1".
+
+2022-11-16 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/bitmanip.md (*bext<mode>): Add an additional
+ pattern that allows the 3rd argument to zero_extract to be
+ an Xmode register operand.
+
+2022-11-16 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107686
+ * tree-ssa-forwprop.cc (optimize_vector_load): Restrict
+ VEC_UNPACK support to integral typed bitfield refs.
+
+2022-11-16 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/107679
+ * tree-into-ssa.cc (maybe_register_def): Use new temporary if
+ we require an uninitialized value for a parameter decl.
+
+2022-11-16 Alexander Monakov <amonakov@ispras.ru>
+
+ PR target/107676
+ * doc/invoke.texi (-mrelax-cmpxchg-loop): Reword description.
+
+2022-11-16 Alexander Monakov <amonakov@ispras.ru>
+
+ PR target/87832
+ * config/i386/znver.md: (znver1_fp_op_mul): Correct cycles in
+ the reservation.
+ (znver1_fp_op_mul_load): Ditto.
+ (znver1_mmx_mul): Ditto.
+ (znver1_mmx_load): Ditto.
+ (znver1_ssemul_ss_ps): Ditto.
+ (znver1_ssemul_ss_ps_load): Ditto.
+ (znver1_ssemul_avx256_ps): Ditto.
+ (znver1_ssemul_avx256_ps_load): Ditto.
+ (znver1_ssemul_sd_pd): Ditto.
+ (znver1_ssemul_sd_pd_load): Ditto.
+ (znver2_ssemul_sd_pd): Ditto.
+ (znver2_ssemul_sd_pd_load): Ditto.
+ (znver1_ssemul_avx256_pd): Ditto.
+ (znver1_ssemul_avx256_pd_load): Ditto.
+ (znver1_sseimul): Ditto.
+ (znver1_sseimul_avx256): Ditto.
+ (znver1_sseimul_load): Ditto.
+ (znver1_sseimul_avx256_load): Ditto.
+ (znver1_sseimul_di): Ditto.
+ (znver1_sseimul_load_di): Ditto.
+
+2022-11-16 Alexander Monakov <amonakov@ispras.ru>
+
+ PR target/87832
+ * config/i386/znver.md (znver1_fdiv): New automaton.
+ (znver1-fdiv): New unit.
+ (znver1_fp_op_div): Correct unit and cycles in the reservation.
+ (znver1_fp_op_div_load): Ditto.
+ (znver1_fp_op_idiv_load): Ditto.
+ (znver2_fp_op_idiv_load): Ditto.
+ (znver1_ssediv_ss_ps): Ditto.
+ (znver1_ssediv_ss_ps_load): Ditto.
+ (znver1_ssediv_sd_pd): Ditto.
+ (znver1_ssediv_sd_pd_load): Ditto.
+ (znver1_ssediv_avx256_ps): Ditto.
+ (znver1_ssediv_avx256_ps_load): Ditto.
+ (znver1_ssediv_avx256_pd): Ditto.
+ (znver1_ssediv_avx256_pd_load): Ditto.
+
+2022-11-16 Tobias Burnus <tobias@codesourcery.com>
+ Andrew Stubbs <ams@codesourcery.com>
+
+ * config/gcn/gcn-builtins.def (KERNARG_PTR): Add.
+ * config/gcn/gcn.cc (gcn_init_builtin_types): Change siptr_type_node,
+ sfptr_type_node and voidptr_type_node from FLAT to ADDR_SPACE_DEFAULT.
+ (gcn_expand_builtin_1): Handle GCN_BUILTIN_KERNARG_PTR.
+ (gcn_oacc_dim_size): Return in ADDR_SPACE_FLAT.
+
+2022-11-16 David Malcolm <dmalcolm@redhat.com>
+
+ * Makefile.in (ANALYZER_OBJS): Add analyzer/checker-event.o.
+
+2022-11-16 Max Filippov <jcmvbkbc@gmail.com>
+
+ PR target/107645
+ * config/m68k/predicates.md (symbolic_operand): Return false
+ when UNSPEC is under the CONST node.
+
+2022-11-16 Christoph Müllner <christoph.muellner@vrull.eu>
+
+ * doc/invoke.texi: Fix PRU/RISC-V option list formatting.
+
+2022-11-16 Tobias Burnus <tobias@codesourcery.com>
+
+ * config/nvptx/mkoffload.cc (process): Recognize '$nohost$...'
+ besides tailing '$nohost' as being for reverse offload.
+
+2022-11-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107668
+ * range-op-float.cc (float_binary_op_range_finish): Set VARYING
+ also when r is UNDEFINED.
+
+2022-11-16 Kewen Lin <linkw@linux.ibm.com>
+
+ PR rtl-optimization/90259
+ * function.cc (rest_of_handle_thread_prologue_and_epilogue): Add
+ parameter fun, and call function purge_all_dead_edges.
+ (pass_thread_prologue_and_epilogue::execute): Name unamed parameter
+ as fun, and use it for rest_of_handle_thread_prologue_and_epilogue.
+
+2022-11-15 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/riscv-builtins.cc (struct riscv_builtin_description):
+ add the pause machine-dependent builtin with no result and no
+ arguments; mark it as always present (pause is a true hint
+ that encodes into a fence-insn, if not supported with the new
+ pause semantics).
+ * config/riscv/riscv-ftypes.def: Add type for void -> void.
+ * config/riscv/riscv.md (riscv_pause): Add risc_pause and
+ UNSPECV_PAUSE
+ * doc/extend.texi: Document __builtin_riscv_pause.
+ * optabs.cc (maybe_gen_insn): Allow nops == 0 (void -> void).
+
+2022-11-15 David Faust <david.faust@oracle.com>
+
+ * config/bpf/bpf.cc (bpf_expand_builtin): Avoid use of uninitialized
+ variable in error case.
+
+2022-11-15 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106140
+ * doc/invoke.texi (Static Analyzer Options): Add
+ -Wanalyzer-fd-phase-mismatch and -Wanalyzer-fd-type-mismatch. Add
+ "socket", "bind", "listen", "accept", and "connect" to the list of
+ functions known to the analyzer.
+
+2022-11-15 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106302
+ * Makefile.in (ANALYZER_OBJS): Add analyzer/analyzer-language.o.
+ (GTFILES): Add analyzer/analyzer-language.cc.
+ * doc/analyzer.texi: Document __analyzer_dump_named_constant.
+
+2022-11-15 Lewis Hyatt <lhyatt@gmail.com>
+
+ * json.h (class string): Add M_LEN member to store the length of
+ the data. Add constructor taking an explicit length.
+ * json.cc (string::string): Implement the new constructor.
+ (string::print): Support printing strings that are not
+ null-terminated. Escape embdedded null bytes on output.
+ (test_writing_strings): Test the new null-byte-related features of
+ json::string.
+
+2022-11-15 Lewis Hyatt <lhyatt@gmail.com>
+
+ * diagnostic.cc (diagnostic_get_location_text): Use
+ special_fname_builtin () rather than a hardcoded string (which was
+ also incorrectly left untranslated previously.)
+ * input.cc (special_fname_builtin): New function.
+ (expand_location_1): Use special_fname_builtin () rather than a
+ hard-coded string.
+ (test_builtins): Likewise.
+ * input.h (special_fname_builtin): Declare.
+
+2022-11-15 Lewis Hyatt <lhyatt@gmail.com>
+
+ * tree-diagnostic.cc (maybe_unwind_expanded_macro_loc): Handle ad-hoc
+ location in return value of linemap_resolve_location().
+
+2022-11-15 Jonathan Wakely <jwakely@redhat.com>
+
+ * doc/cpp.texi (Pragmas): Use @item and @itemx for region
+ pragmas.
+
+2022-11-15 Maciej W. Rozycki <macro@embecosm.com>
+
+ * ira-color.cc (assign_hard_reg): Remove duplicate `memset' over
+ `full_costs'.
+
+2022-11-15 Andre Vieira <andre.simoesdiasvieira@arm.com>
+
+ * config/aarch64/atomics.md
+ (*aarch64_atomic_load<ALLX:mode>_rcpc_zext): New pattern.
+ (*aarch64_atomic_load<ALLX:mode>_rcpc_sext): New pattern.
+
+2022-11-15 Andre Vieira <andre.simoesdiasvieira@arm.com>
+ Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64.h (AARCH64_ISA_RCPC): New Macro.
+ (TARGET_RCPC): New Macro.
+ * config/aarch64/atomics.md (atomic_load<mode>): Change into an expand.
+ (aarch64_atomic_load<mode>_rcpc): New define_insn for ldapr.
+ (aarch64_atomic_load<mode>): Rename of old define_insn for ldar.
+ * config/aarch64/iterators.md (UNSPEC_LDAP): New unspec enum value.
+ * doc/invoke.texi (rcpc): Ammend documentation to mention the effects
+ on code generation.
+
+2022-11-15 Hongyu Wang <hongyu.wang@intel.com>
+
+ PR target/98167
+ * match.pd: New perm + vector op patterns for int and fp vector.
+
+2022-11-15 Andrew Pinski <apinski@marvell.com>
+
+ * doc/invoke.texi: Remove Score option section.
+
+2022-11-15 Andrew Pinski <apinski@marvell.com>
+
+ * doc/extend.texi: Remove picoChip builtin section.
+ * doc/invoke.texi: Remove picoChip option section.
+
+2022-11-15 Andrew Pinski <apinski@marvell.com>
+
+ * doc/extend.texi: Remove MeP documentation.
+ * doc/invoke.texi: Remove MeP Options documentation.
+
+2022-11-15 Andrew Pinski <apinski@marvell.com>
+
+ * doc/invoke.texi: Fix opindex for mcall-aixdesc and mcall-openbsd.
+
+2022-11-14 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ Revert:
+ 2022-11-14 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/riscv-cores.def (RISCV_TUNE): Add ventana-vt1.
+ (RISCV_CORE): Ditto.
+ * config/riscv/riscv-opts.h (enum riscv_microarchitecture_type): Ditto.
+ * config/riscv/riscv.cc: Add tune_info for ventana-vt1.
+ * doc/invoke.texi: Document -mcpu= and -mtune with ventana-vt1.
+
+2022-11-14 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ Revert:
+ 2022-11-14 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/riscv.cc (enum riscv_fusion_pairs): Add symbolic
+ constants to identify supported fusion patterns.
+ (struct riscv_tune_param): Add fusible_op field.
+ (riscv_macro_fusion_p): Implement.
+ (riscv_fusion_enabled_p): Implement.
+ (riscv_macro_fusion_pair_p): Implement and recognize fusible
+ idioms for Ventana VT1.
+ (TARGET_SCHED_MACRO_FUSION_P): Point to riscv_macro_fusion_p.
+ (TARGET_SCHED_MACRO_FUSION_PAIR_P): Point to
+ riscv_macro_fusion_pair_p.
+
+2022-11-14 Maciej W. Rozycki <macro@embecosm.com>
+
+ * ira-build.cc (create_insn_allocnos): Fix documentation.
+
+2022-11-14 Tamar Christina <tamar.christina@arm.com>
+
+ * match.pd: Remove returns.
+
+2022-11-14 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/bitmanip.md (orcb<mode>2): Add orc.b as an
+ unspec.
+ * config/riscv/riscv.md: Add UNSPEC_ORC_B.
+
+2022-11-14 Tamar Christina <tamar.christina@arm.com>
+
+ * target.def: Fix typo.
+
+2022-11-14 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/riscv.cc (enum riscv_fusion_pairs): Add symbolic
+ constants to identify supported fusion patterns.
+ (struct riscv_tune_param): Add fusible_op field.
+ (riscv_macro_fusion_p): Implement.
+ (riscv_fusion_enabled_p): Implement.
+ (riscv_macro_fusion_pair_p): Implement and recognize fusible
+ idioms for Ventana VT1.
+ (TARGET_SCHED_MACRO_FUSION_P): Point to riscv_macro_fusion_p.
+ (TARGET_SCHED_MACRO_FUSION_PAIR_P): Point to
+ riscv_macro_fusion_pair_p.
+
+2022-11-14 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/riscv-cores.def (RISCV_TUNE): Add ventana-vt1.
+ (RISCV_CORE): Ditto.
+ * config/riscv/riscv-opts.h (enum riscv_microarchitecture_type): Ditto.
+ * config/riscv/riscv.cc: Add tune_info for ventana-vt1.
+ * doc/invoke.texi: Document -mcpu= and -mtune with ventana-vt1.
+
+2022-11-14 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64-option-extensions.def (cssc): Define.
+ * config/aarch64/aarch64.h (AARCH64_ISA_CSSC): Define.
+ (TARGET_CSSC): Likewise.
+ * config/aarch64/aarch64.md (*aarch64_abs<mode>2_cssc_ins): New define_insn.
+ (abs<mode>2): Adjust for the above.
+ (aarch64_umax<mode>3_insn): New define_insn.
+ (umax<mode>3): Adjust for the above.
+ (*aarch64_popcount<mode>2_cssc_insn): New define_insn.
+ (popcount<mode>2): Adjust for the above.
+ (<optab><mode>3): New define_insn.
+ * config/aarch64/constraints.md (Usm): Define.
+ (Uum): Likewise.
+ * doc/invoke.texi (AArch64 options): Document +cssc.
+ * config/aarch64/iterators.md (MAXMIN_NOUMAX): New code iterator.
+ * config/aarch64/predicates.md (aarch64_sminmax_immediate): Define.
+ (aarch64_sminmax_operand): Likewise.
+ (aarch64_uminmax_immediate): Likewise.
+ (aarch64_uminmax_operand): Likewise.
+
+2022-11-14 Tamar Christina <tamar.christina@arm.com>
+
+ * config/aarch64/aarch64-sve2.md (@aarch64_bitmask_udiv<mode>3): New.
+
+2022-11-14 Tamar Christina <tamar.christina@arm.com>
+
+ * config/aarch64/aarch64-simd.md (@aarch64_bitmask_udiv<mode>3): New.
+ * config/aarch64/aarch64.cc (aarch64_vectorize_can_special_div_by_constant): New.
+
+2022-11-14 Tamar Christina <tamar.christina@arm.com>
+
+ * expmed.h (expand_divmod): Pass tree operands down in addition to RTX.
+ * expmed.cc (expand_divmod): Likewise.
+ * explow.cc (round_push, align_dynamic_address): Likewise.
+ * expr.cc (force_operand, expand_expr_divmod): Likewise.
+ * optabs.cc (expand_doubleword_mod, expand_doubleword_divmod):
+ Likewise.
+ * target.h: Include tree-core.
+ * target.def (can_special_div_by_const): New.
+ * targhooks.cc (default_can_special_div_by_const): New.
+ * targhooks.h (default_can_special_div_by_const): New.
+ * tree-vect-generic.cc (expand_vector_operation): Use it.
+ * doc/tm.texi.in: Document it.
+ * doc/tm.texi: Regenerate.
+ * tree-vect-patterns.cc (vect_recog_divmod_pattern): Check for support.
+ * tree-vect-stmts.cc (vectorizable_operation): Likewise.
+
+2022-11-14 Tamar Christina <tamar.christina@arm.com>
+
+ * generic-match-head.cc: Include langooks.
+ * gimple-match-head.cc: Likewise.
+ * match.pd: Add fneg/fadd rule.
+
+2022-11-14 Srinath Parvathaneni <srinath.parvathaneni@arm.com>
+
+ * config/arm/arm-cpus.in (cortex-x1c): Define new CPU.
+ * config/arm/arm-tables.opt: Regenerate.
+ * config/arm/arm-tune.md: Likewise.
+ * doc/invoke.texi: Document Cortex-X1C CPU.
+
+2022-11-14 Srinath Parvathaneni <srinath.parvathaneni@arm.com>
+
+ * config/aarch64/aarch64-cores.def (AARCH64_CORE): Add Cortex-X3
+ CPU.
+ * config/aarch64/aarch64-tune.md: Regenerate.
+ * doc/invoke.texi: Document Cortex-X3 CPU.
+
+2022-11-14 Andrew Pinski <apinski@marvell.com>
+
+ * doc/invoke.texi: Fix @opindex
+ for m80387 option.
+
+2022-11-14 Andrew Pinski <apinski@marvell.com>
+
+ * doc/invoke.texi: Remove the front - from
+ some @opindex.
+
+2022-11-14 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/aarch64/aarch64-cores.def (AARCH64_CORE): Add ampere1a.
+ * config/aarch64/aarch64-cost-tables.h: Add ampere1a_extra_costs.
+ * config/aarch64/aarch64-fusion-pairs.def (AARCH64_FUSION_PAIR):
+ Define a new fusion pair for A+B+1/A-B-1 (i.e., add/subtract two
+ registers and then +1/-1).
+ * config/aarch64/aarch64-tune.md: Regenerate.
+ * config/aarch64/aarch64.cc (aarch_macro_fusion_pair_p): Implement
+ idiom-matcher for the new fusion pair.
+ * doc/invoke.texi: Add ampere1a.
+
+2022-11-14 Richard Biener <rguenther@suse.de>
+
+ * match.pd: Remove duplicates.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/contrib.texi: Port from Sphinx.
+ * doc/cpp.texi: Likewise.
+ * doc/install.texi: Likewise.
+ * doc/invoke.texi: Likewise.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/cpp/character-sets.rst: New file.
+ * doc/cpp/conditional-syntax.rst: New file.
+ * doc/cpp/conditional-uses.rst: New file.
+ * doc/cpp/conditionals.rst: New file.
+ * doc/cpp/conf.py: New file.
+ * doc/cpp/copyright.rst: New file.
+ * doc/cpp/deleted-code.rst: New file.
+ * doc/cpp/diagnostics.rst: New file.
+ * doc/cpp/environment-variables.rst: New file.
+ * doc/cpp/gnu-free-documentation-license.rst: New file.
+ * doc/cpp/header-files.rst: New file.
+ * doc/cpp/header-files/alternatives-to-wrapper-ifndef.rst: New file.
+ * doc/cpp/header-files/computed-includes.rst: New file.
+ * doc/cpp/header-files/include-operation.rst: New file.
+ * doc/cpp/header-files/include-syntax.rst: New file.
+ * doc/cpp/header-files/once-only-headers.rst: New file.
+ * doc/cpp/header-files/search-path.rst: New file.
+ * doc/cpp/header-files/system-headers.rst: New file.
+ * doc/cpp/header-files/wrapper-headers.rst: New file.
+ * doc/cpp/implementation-defined-behavior.rst: New file.
+ * doc/cpp/implementation-details.rst: New file.
+ * doc/cpp/implementation-limits.rst: New file.
+ * doc/cpp/index.rst: New file.
+ * doc/cpp/indices-and-tables.rst: New file.
+ * doc/cpp/initial-processing.rst: New file.
+ * doc/cpp/invocation.rst: New file.
+ * doc/cpp/line-control.rst: New file.
+ * doc/cpp/macros.rst: New file.
+ * doc/cpp/macros/concatenation.rst: New file.
+ * doc/cpp/macros/directives-within-macro-arguments.rst: New file.
+ * doc/cpp/macros/function-like-macros.rst: New file.
+ * doc/cpp/macros/macro-arguments.rst: New file.
+ * doc/cpp/macros/macro-pitfalls.rst: New file.
+ * doc/cpp/macros/object-like-macros.rst: New file.
+ * doc/cpp/macros/predefined-macros.rst: New file.
+ * doc/cpp/macros/stringizing.rst: New file.
+ * doc/cpp/macros/undefining-and-redefining-macros.rst: New file.
+ * doc/cpp/macros/variadic-macros.rst: New file.
+ * doc/cpp/obsolete-features.rst: New file.
+ * doc/cpp/other-directives.rst: New file.
+ * doc/cpp/overview.rst: New file.
+ * doc/cpp/pragmas.rst: New file.
+ * doc/cpp/preprocessor-output.rst: New file.
+ * doc/cpp/the-preprocessing-language.rst: New file.
+ * doc/cpp/tokenization.rst: New file.
+ * doc/cpp/traditional-lexical-analysis.rst: New file.
+ * doc/cpp/traditional-macros.rst: New file.
+ * doc/cpp/traditional-miscellany.rst: New file.
+ * doc/cpp/traditional-mode.rst: New file.
+ * doc/cpp/traditional-warnings.rst: New file.
+ * doc/cppinternals/conf.py: New file.
+ * doc/cppinternals/copyright.rst: New file.
+ * doc/cppinternals/cppinternals.rst: New file.
+ * doc/cppinternals/cpplib.rst: New file.
+ * doc/cppinternals/files.rst: New file.
+ * doc/cppinternals/index.rst: New file.
+ * doc/cppinternals/indices-and-tables.rst: New file.
+ * doc/cppinternals/internal-representation-of-macros.rst: New file.
+ * doc/cppinternals/just-which-line-number-anyway.rst: New file.
+ * doc/cppinternals/lexing-a-line.rst: New file.
+ * doc/cppinternals/lexing-a-token.rst: New file.
+ * doc/cppinternals/looking-for-a-function-like-macros-opening-parenthesis.rst: New file.
+ * doc/cppinternals/macro-expansion-overview.rst: New file.
+ * doc/cppinternals/marking-tokens-ineligible-for-future-expansion.rst: New file.
+ * doc/cppinternals/multiple-include-optimization.rst: New file.
+ * doc/cppinternals/overview.rst: New file.
+ * doc/cppinternals/representation-of-line-numbers.rst: New file.
+ * doc/cppinternals/scanning-the-replacement-list-for-macros-to-expand.rst: New file.
+ * doc/gcc/binary-compatibility.rst: New file.
+ * doc/gcc/c++-implementation-defined-behavior.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/architecture.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/arrays-and-pointers.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/characters.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/declarators.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/environment.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/floating-point.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/hints.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/identifiers.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/integers.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/library-functions.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/locale-specific-behavior.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/preprocessing-directives.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/qualifiers.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/statements.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/structures-unions-enumerations-and-bit-fields.rst:
+ New file.
+ * doc/gcc/c-implementation-defined-behavior/translation.rst: New file.
+ * doc/gcc/conditionally-supported-behavior.rst: New file.
+ * doc/gcc/conf.py: New file.
+ * doc/gcc/contributing-to-gcc-development.rst: New file.
+ * doc/gcc/contributors-to-gcc.rst: New file.
+ * doc/gcc/copyright.rst: New file.
+ * doc/gcc/exception-handling.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/backwards-compatibility.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/c++-concepts.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/c++-interface-and-implementation-pragmas.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c++-language/c++-specific-variable-function-and-type-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c++-language/deprecated-features.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/extracting-the-function-pointer-from-a-bound-pointer-to-member-function.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c++-language/function-multiversioning.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/restricting-pointer-aliasing.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/type-traits.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/vague-linkage.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/when-is-a-volatile-c++-object-accessed.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c++-language/wheres-the-template.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/128-bit-integers.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/additional-floating-types.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/alternate-keywords.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/an-inline-function-is-as-fast-as-a-macro.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/arithmetic-on-void-and-function-pointers.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/arrays-of-length-zero.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/arrays-of-variable-length.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/attribute-syntax.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/binary-constants-using-the-0b-prefix.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/built-in-functions-for-memory-model-aware-atomic-operations.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/built-in-functions-to-perform-arithmetic-with-overflow-checking.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/c++-style-comments.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/case-ranges.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/cast-to-a-union-type.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/complex-numbers.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/compound-literals.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/conditionals-with-omitted-operands.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/constructing-function-calls.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/decimal-floating-types.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/aarch64-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/amd-gcn-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/arc-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/arm-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/avr-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/blackfin-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/bpf-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/c-sky-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/common-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/epiphany-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/h8-300-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/ia-64-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/m32c-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/m32r-d-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/m68k-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/mcore-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/mep-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/microblaze-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/microsoft-windows-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/mips-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/msp430-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/nds32-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/nios-ii-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/nvidia-ptx-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/powerpc-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/risc-v-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/rl78-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/rx-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/s-390-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/sh-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/symbian-os-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/v850-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/visium-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/x86-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/xstormy16-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/designated-initializers.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/determining-the-alignment-of-functions-types-or-variables.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/dollar-signs-in-identifier-names.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/double-word-integers.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/enumerator-attributes.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/fixed-point-types.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/format-checks-specific-to-particular-target-machines.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/function-names-as-strings.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/getting-the-return-or-frame-address-of-a-function.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/half-precision-floating-point.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/hex-floats.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/how-to-use-inline-assembly-language-in-c-code.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/incomplete-enum-types.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/label-attributes.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/labels-as-values.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/legacy-sync-built-in-functions-for-atomic-memory-access.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/locally-declared-labels.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/macros-with-a-variable-number-of-arguments.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/mixed-declarations-labels-and-code.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/named-address-spaces.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/nested-functions.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/non-constant-initializers.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/non-lvalue-arrays-may-have-subscripts.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/nonlocal-gotos.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/object-size-checking-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/other-built-in-functions-provided-by-gcc.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/pointer-arguments-in-variadic-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/pointers-to-arrays-with-qualifiers-work-as-expected.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/pragmas-accepted-by-gcc.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/prototypes-and-old-style-function-definitions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/referring-to-a-type-with-typeof.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/slightly-looser-rules-for-escaped-newlines.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/specifying-attributes-of-types.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/specifying-attributes-of-variables.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/statement-attributes.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/statements-and-declarations-in-expressions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/structures-with-no-members.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/support-for-offsetof.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/aarch64-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/alpha-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/altera-nios-ii-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arc-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arc-simd-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-armv8-m-security-extensions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-c-language-extensions-acle.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-floating-point-status-and-control-intrinsics.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-iwmmxt-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/avr-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/basic-powerpc-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/blackfin-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/bpf-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/fr-v-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-dsp-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-loongson-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-paired-single-support.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-simd-architecture-msa-support.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/msp430-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/nds32-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/other-mips-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/picochip-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-altivec-vsx-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-atomic-memory-operation-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-hardware-transactional-memory-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-matrix-multiply-assist-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/pru-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/risc-v-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/rx-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/s-390-system-z-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/sh-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/sparc-vis-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/ti-c6x-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/x86-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/x86-control-flow-protection-intrinsics.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/x86-transactional-memory-intrinsics.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/the-character-esc-in-constants.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/thread-local-storage.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/unnamed-structure-and-union-fields.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/using-vector-instructions-through-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/when-is-a-volatile-object-accessed.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/x86-specific-memory-model-extensions-for-transactional-memory.rst:
+ New file.
+ * doc/gcc/funding.rst: New file.
+ * doc/gcc/gcc-command-options.rst: New file.
+ * doc/gcc/gcc-command-options/c++-modules.rst: New file.
+ * doc/gcc/gcc-command-options/compiling-c++-programs.rst: New file.
+ * doc/gcc/gcc-command-options/description.rst: New file.
+ * doc/gcc/gcc-command-options/environment-variables-affecting-gcc.rst: New file.
+ * doc/gcc/gcc-command-options/gcc-developer-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/aarch64-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/adapteva-epiphany-options.rst:
+ New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/amd-gcn-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/arc-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/arm-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/avr-mmcu.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/avr-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/blackfin-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/c-sky-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/c6x-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/cris-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/darwin-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/dec-alpha-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ebpf-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/fr30-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/frv-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ft32-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/gnu-linux-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/h8-300-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/hppa-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ia-64-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ibm-rs-6000-and-powerpc-options.rst:
+ New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/lm32-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/loongarch-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/m32c-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/m32r-d-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/m680x0-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mcore-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mep-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/microblaze-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mips-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mmix-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mn10300-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/moxie-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/msp430-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/nds32-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/nios-ii-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/nvidia-ptx-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/openrisc-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/options-for-system-v.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/pdp-11-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/picochip-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/powerpc-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/pru-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/risc-v-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/rl78-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/rx-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/s-390-and-zseries-options.rst:
+ New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/score-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/sh-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/solaris-2-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/sparc-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/v850-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/vax-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/visium-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/vms-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/vxworks-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/x86-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/x86-windows-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/xstormy16-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/xtensa-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/zseries-options.rst: New file.
+ * doc/gcc/gcc-command-options/option-summary.rst: New file.
+ * doc/gcc/gcc-command-options/options-controlling-c++-dialect.rst: New file.
+ * doc/gcc/gcc-command-options/options-controlling-c-dialect.rst: New file.
+ * doc/gcc/gcc-command-options/options-controlling-objective-c-and-objective-c++-dialects.rst:
+ New file.
+ * doc/gcc/gcc-command-options/options-controlling-the-kind-of-output.rst: New file.
+ * doc/gcc/gcc-command-options/options-controlling-the-preprocessor.rst: New file.
+ * doc/gcc/gcc-command-options/options-for-code-generation-conventions.rst: New file.
+ * doc/gcc/gcc-command-options/options-for-debugging-your-program.rst: New file.
+ * doc/gcc/gcc-command-options/options-for-directory-search.rst: New file.
+ * doc/gcc/gcc-command-options/options-for-linking.rst: New file.
+ * doc/gcc/gcc-command-options/options-that-control-optimization.rst: New file.
+ * doc/gcc/gcc-command-options/options-that-control-static-analysis.rst: New file.
+ * doc/gcc/gcc-command-options/options-to-control-diagnostic-messages-formatting.rst:
+ New file.
+ * doc/gcc/gcc-command-options/options-to-request-or-suppress-warnings.rst: New file.
+ * doc/gcc/gcc-command-options/passing-options-to-the-assembler.rst: New file.
+ * doc/gcc/gcc-command-options/program-instrumentation-options.rst: New file.
+ * doc/gcc/gcc-command-options/specifying-subprocesses-and-the-switches-to-pass-to-them.rst:
+ New file.
+ * doc/gcc/gcc-command-options/using-precompiled-headers.rst: New file.
+ * doc/gcc/gcc.rst: New file.
+ * doc/gcc/gcov-dump.rst: New file.
+ * doc/gcc/gcov-tool.rst: New file.
+ * doc/gcc/gcov.rst: New file.
+ * doc/gcc/gcov/brief-description-of-gcov-data-files.rst: New file.
+ * doc/gcc/gcov/data-file-relocation-to-support-cross-profiling.rst: New file.
+ * doc/gcc/gcov/introduction-to-gcov.rst: New file.
+ * doc/gcc/gcov/invoking-gcov.rst: New file.
+ * doc/gcc/gcov/profiling-and-test-coverage-in-freestanding-environments.rst: New file.
+ * doc/gcc/gcov/using-gcov-with-gcc-optimization.rst: New file.
+ * doc/gcc/general-public-license-3.rst: New file.
+ * doc/gcc/gnu-free-documentation-license.rst: New file.
+ * doc/gcc/gnu-objective-c-features.rst: New file.
+ * doc/gcc/gnu-objective-c-features/compatibilityalias.rst: New file.
+ * doc/gcc/gnu-objective-c-features/constant-string-objects.rst: New file.
+ * doc/gcc/gnu-objective-c-features/exceptions.rst: New file.
+ * doc/gcc/gnu-objective-c-features/fast-enumeration.rst: New file.
+ * doc/gcc/gnu-objective-c-features/garbage-collection.rst: New file.
+ * doc/gcc/gnu-objective-c-features/gnu-objective-c-runtime-api.rst: New file.
+ * doc/gcc/gnu-objective-c-features/load-executing-code-before-main.rst: New file.
+ * doc/gcc/gnu-objective-c-features/messaging-with-the-gnu-objective-c-runtime.rst: New file.
+ * doc/gcc/gnu-objective-c-features/synchronization.rst: New file.
+ * doc/gcc/gnu-objective-c-features/type-encoding.rst: New file.
+ * doc/gcc/gnu.rst: New file.
+ * doc/gcc/have-you-found-a-bug.rst: New file.
+ * doc/gcc/how-and-where-to-report-bugs.rst: New file.
+ * doc/gcc/how-to-get-help-with-gcc.rst: New file.
+ * doc/gcc/index.rst: New file.
+ * doc/gcc/indices-and-tables.rst: New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc.rst: New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/actual-bugs-we-havent-fixed-yet.rst: New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/certain-changes-we-dont-want-to-make.rst:
+ New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/common-misunderstandings-with-gnu-c.rst:
+ New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/disappointments-and-misunderstandings.rst:
+ New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/fixed-header-files.rst: New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/incompatibilities-of-gcc.rst: New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/interoperation.rst: New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/standard-libraries.rst: New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/warning-messages-and-error-messages.rst:
+ New file.
+ * doc/gcc/language-standards-supported-by-gcc.rst: New file.
+ * doc/gcc/language-standards-supported-by-gcc/c++-language.rst: New file.
+ * doc/gcc/language-standards-supported-by-gcc/c-language.rst: New file.
+ * doc/gcc/language-standards-supported-by-gcc/d-language.rst: New file.
+ * doc/gcc/language-standards-supported-by-gcc/go-language.rst: New file.
+ * doc/gcc/language-standards-supported-by-gcc/objective-c-and-objective-c++-languages.rst:
+ New file.
+ * doc/gcc/language-standards-supported-by-gcc/references-for-other-languages.rst: New file.
+ * doc/gcc/lto-dump.rst: New file.
+ * doc/gcc/programming-languages-supported-by-gcc.rst: New file.
+ * doc/gcc/reporting-bugs.rst: New file.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples.rst: New file.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/alias-analysis.rst: New file.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/annotations.rst: New file.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/memory-model.rst: New file.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/ssa-operands.rst: New file.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/static-single-assignment.rst:
+ New file.
+ * doc/gccint/analysis-and-representation-of-loops.rst: New file.
+ * doc/gccint/analysis-and-representation-of-loops/data-dependency-analysis.rst: New file.
+ * doc/gccint/analysis-and-representation-of-loops/iv-analysis-on-rtl.rst: New file.
+ * doc/gccint/analysis-and-representation-of-loops/loop-closed-ssa-form.rst: New file.
+ * doc/gccint/analysis-and-representation-of-loops/loop-manipulation.rst: New file.
+ * doc/gccint/analysis-and-representation-of-loops/loop-querying.rst: New file.
+ * doc/gccint/analysis-and-representation-of-loops/loop-representation.rst: New file.
+ * doc/gccint/analysis-and-representation-of-loops/number-of-iterations-analysis.rst:
+ New file.
+ * doc/gccint/analysis-and-representation-of-loops/scalar-evolutions.rst: New file.
+ * doc/gccint/analyzer-internals.rst: New file.
+ * doc/gccint/collect2.rst: New file.
+ * doc/gccint/conf.py: New file.
+ * doc/gccint/contributing-to-gcc-development.rst: New file.
+ * doc/gccint/contributors-to-gcc.rst: New file.
+ * doc/gccint/control-flow-graph.rst: New file.
+ * doc/gccint/control-flow-graph/basic-blocks.rst: New file.
+ * doc/gccint/control-flow-graph/edges.rst: New file.
+ * doc/gccint/control-flow-graph/liveness-information.rst: New file.
+ * doc/gccint/control-flow-graph/maintaining-the-cfg.rst: New file.
+ * doc/gccint/control-flow-graph/profile-information.rst: New file.
+ * doc/gccint/copyright.rst: New file.
+ * doc/gccint/debugging-the-analyzer.rst: New file.
+ * doc/gccint/funding.rst: New file.
+ * doc/gccint/gcc-and-portability.rst: New file.
+ * doc/gccint/general-public-license-3.rst: New file.
+ * doc/gccint/generic.rst: New file.
+ * doc/gccint/generic/attributes-in-trees.rst: New file.
+ * doc/gccint/generic/c-and-c++-trees.rst: New file.
+ * doc/gccint/generic/declarations.rst: New file.
+ * doc/gccint/generic/deficiencies.rst: New file.
+ * doc/gccint/generic/expressions.rst: New file.
+ * doc/gccint/generic/functions.rst: New file.
+ * doc/gccint/generic/language-dependent-trees.rst: New file.
+ * doc/gccint/generic/overview.rst: New file.
+ * doc/gccint/generic/statements.rst: New file.
+ * doc/gccint/generic/types.rst: New file.
+ * doc/gccint/gimple-api.rst: New file.
+ * doc/gccint/gimple.rst: New file.
+ * doc/gccint/gimple/adding-a-new-gimple-statement-code.rst: New file.
+ * doc/gccint/gimple/class-hierarchy-of-gimple-statements.rst: New file.
+ * doc/gccint/gimple/exception-handling.rst: New file.
+ * doc/gccint/gimple/gimple-instruction-set.rst: New file.
+ * doc/gccint/gimple/gimple-sequences.rst: New file.
+ * doc/gccint/gimple/manipulating-gimple-statements.rst: New file.
+ * doc/gccint/gimple/operands.rst: New file.
+ * doc/gccint/gimple/sequence-iterators.rst: New file.
+ * doc/gccint/gimple/statement-and-operand-traversals.rst: New file.
+ * doc/gccint/gimple/temporaries.rst: New file.
+ * doc/gccint/gimple/tuple-representation.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleasm.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleassign.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplebind.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplecall.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplecatch.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplecond.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpledebug.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleehfilter.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplegoto.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplelabel.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplenop.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompatomicload.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompatomicstore.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompcontinue.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompcritical.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompfor.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompmaster.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompordered.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompparallel.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompreturn.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompsection.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompsections.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompsingle.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplephi.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleresx.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplereturn.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleswitch.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpletry.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplewithcleanupexpr.rst: New file.
+ * doc/gccint/gnu-free-documentation-license.rst: New file.
+ * doc/gccint/guidelines-for-diagnostics.rst: New file.
+ * doc/gccint/guidelines-for-options.rst: New file.
+ * doc/gccint/host-common.rst: New file.
+ * doc/gccint/host-configuration.rst: New file.
+ * doc/gccint/host-filesystem.rst: New file.
+ * doc/gccint/host-makefile-fragments.rst: New file.
+ * doc/gccint/host-misc.rst: New file.
+ * doc/gccint/index.rst: New file.
+ * doc/gccint/indices-and-tables.rst: New file.
+ * doc/gccint/interfacing-to-gcc-output.rst: New file.
+ * doc/gccint/introduction.rst: New file.
+ * doc/gccint/language-front-ends-in-gcc.rst: New file.
+ * doc/gccint/link-time-optimization.rst: New file.
+ * doc/gccint/link-time-optimization/design-overview.rst: New file.
+ * doc/gccint/link-time-optimization/internal-flags-controlling-lto1.rst: New file.
+ * doc/gccint/link-time-optimization/lto-file-sections.rst: New file.
+ * doc/gccint/link-time-optimization/using-summary-information-in-ipa-passes.rst: New file.
+ * doc/gccint/link-time-optimization/whole-program-assumptions-linker-plugin-and-symbol-visibilities.rst:
+ New file.
+ * doc/gccint/machine-descriptions.rst: New file.
+ * doc/gccint/machine-descriptions/c-statements-for-assembler-output.rst: New file.
+ * doc/gccint/machine-descriptions/canonicalization-of-instructions.rst: New file.
+ * doc/gccint/machine-descriptions/conditional-execution.rst: New file.
+ * doc/gccint/machine-descriptions/constant-definitions.rst: New file.
+ * doc/gccint/machine-descriptions/defining-how-to-split-instructions.rst: New file.
+ * doc/gccint/machine-descriptions/defining-jump-instruction-patterns.rst: New file.
+ * doc/gccint/machine-descriptions/defining-looping-instruction-patterns.rst: New file.
+ * doc/gccint/machine-descriptions/defining-rtl-sequences-for-code-generation.rst: New file.
+ * doc/gccint/machine-descriptions/everything-about-instruction-patterns.rst: New file.
+ * doc/gccint/machine-descriptions/example-of-defineinsn.rst: New file.
+ * doc/gccint/machine-descriptions/including-patterns-in-machine-descriptions.rst: New file.
+ * doc/gccint/machine-descriptions/instruction-attributes.rst: New file.
+ * doc/gccint/machine-descriptions/interdependence-of-patterns.rst: New file.
+ * doc/gccint/machine-descriptions/iterators.rst: New file.
+ * doc/gccint/machine-descriptions/machine-specific-peephole-optimizers.rst: New file.
+ * doc/gccint/machine-descriptions/operand-constraints.rst: New file.
+ * doc/gccint/machine-descriptions/output-templates-and-operand-substitution.rst: New file.
+ * doc/gccint/machine-descriptions/overview-of-how-the-machine-description-is-used.rst:
+ New file.
+ * doc/gccint/machine-descriptions/predicates.rst: New file.
+ * doc/gccint/machine-descriptions/rtl-template.rst: New file.
+ * doc/gccint/machine-descriptions/rtl-templates-transformations.rst: New file.
+ * doc/gccint/machine-descriptions/standard-pattern-names-for-generation.rst: New file.
+ * doc/gccint/machine-descriptions/when-the-order-of-patterns-matters.rst: New file.
+ * doc/gccint/makefile-fragments.rst: New file.
+ * doc/gccint/match-and-simplify.rst: New file.
+ * doc/gccint/memory-management-and-type-information.rst: New file.
+ * doc/gccint/memory-management-and-type-information/how-to-invoke-the-garbage-collector.rst:
+ New file.
+ * doc/gccint/memory-management-and-type-information/marking-roots-for-the-garbage-collector.rst:
+ New file.
+ * doc/gccint/memory-management-and-type-information/source-files-containing-type-information.rst:
+ New file.
+ * doc/gccint/memory-management-and-type-information/support-for-inheritance.rst: New file.
+ * doc/gccint/memory-management-and-type-information/support-for-user-provided-gc-marking-routines.rst:
+ New file.
+ * doc/gccint/memory-management-and-type-information/the-inside-of-a-gty.rst: New file.
+ * doc/gccint/memory-management-and-type-information/troubleshooting-the-garbage-collector.rst:
+ New file.
+ * doc/gccint/option-file-format.rst: New file.
+ * doc/gccint/option-properties.rst: New file.
+ * doc/gccint/option-specification-files.rst: New file.
+ * doc/gccint/passes-and-files-of-the-compiler.rst: New file.
+ * doc/gccint/passes-and-files-of-the-compiler/gimplification-pass.rst: New file.
+ * doc/gccint/passes-and-files-of-the-compiler/inter-procedural-optimization-passes.rst:
+ New file.
+ * doc/gccint/passes-and-files-of-the-compiler/optimization-info.rst: New file.
+ * doc/gccint/passes-and-files-of-the-compiler/parsing-pass.rst: New file.
+ * doc/gccint/passes-and-files-of-the-compiler/pass-manager.rst: New file.
+ * doc/gccint/passes-and-files-of-the-compiler/rtl-passes.rst: New file.
+ * doc/gccint/passes-and-files-of-the-compiler/tree-ssa-passes.rst: New file.
+ * doc/gccint/plugins.rst: New file.
+ * doc/gccint/plugins/building-gcc-plugins.rst: New file.
+ * doc/gccint/plugins/controlling-which-passes-are-being-run.rst: New file.
+ * doc/gccint/plugins/giving-information-about-a-plugin.rst: New file.
+ * doc/gccint/plugins/interacting-with-the-gcc-garbage-collector.rst: New file.
+ * doc/gccint/plugins/interacting-with-the-pass-manager.rst: New file.
+ * doc/gccint/plugins/keeping-track-of-available-passes.rst: New file.
+ * doc/gccint/plugins/loading-plugins.rst: New file.
+ * doc/gccint/plugins/plugin-api.rst: New file.
+ * doc/gccint/plugins/recording-information-about-pass-execution.rst: New file.
+ * doc/gccint/plugins/registering-custom-attributes-or-pragmas.rst: New file.
+ * doc/gccint/rtl-representation.rst: New file.
+ * doc/gccint/rtl-representation/access-to-operands.rst: New file.
+ * doc/gccint/rtl-representation/access-to-special-operands.rst: New file.
+ * doc/gccint/rtl-representation/assembler-instructions-as-expressions.rst: New file.
+ * doc/gccint/rtl-representation/bit-fields.rst: New file.
+ * doc/gccint/rtl-representation/comparison-operations.rst: New file.
+ * doc/gccint/rtl-representation/constant-expression-types.rst: New file.
+ * doc/gccint/rtl-representation/conversions.rst: New file.
+ * doc/gccint/rtl-representation/declarations.rst: New file.
+ * doc/gccint/rtl-representation/embedded-side-effects-on-addresses.rst: New file.
+ * doc/gccint/rtl-representation/flags-in-an-rtl-expression.rst: New file.
+ * doc/gccint/rtl-representation/insns.rst: New file.
+ * doc/gccint/rtl-representation/machine-modes.rst: New file.
+ * doc/gccint/rtl-representation/on-the-side-ssa-form-for-rtl.rst: New file.
+ * doc/gccint/rtl-representation/reading-rtl.rst: New file.
+ * doc/gccint/rtl-representation/registers-and-memory.rst: New file.
+ * doc/gccint/rtl-representation/rtl-classes-and-formats.rst: New file.
+ * doc/gccint/rtl-representation/rtl-expressions-for-arithmetic.rst: New file.
+ * doc/gccint/rtl-representation/rtl-object-types.rst: New file.
+ * doc/gccint/rtl-representation/rtl-representation-of-function-call-insns.rst: New file.
+ * doc/gccint/rtl-representation/side-effect-expressions.rst: New file.
+ * doc/gccint/rtl-representation/structure-sharing-assumptions.rst: New file.
+ * doc/gccint/rtl-representation/variable-location-debug-information-in-rtl.rst: New file.
+ * doc/gccint/rtl-representation/vector-operations.rst: New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants.rst: New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/alignment-of-polyints.rst: New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/arithmetic-on-polyints.rst: New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/comparisons-involving-polyint.rst:
+ New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/computing-bounds-on-polyints.rst:
+ New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/consequences-of-using-polyint.rst:
+ New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/converting-polyints.rst: New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/guidelines-for-using-polyint.rst:
+ New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/miscellaneous-polyint-routines.rst:
+ New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/overview-of-polyint.rst: New file.
+ * doc/gccint/source-tree-structure-and-build-system.rst: New file.
+ * doc/gccint/source-tree-structure-and-build-system/configure-terms-and-history.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory.rst: New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/anatomy-of-a-language-front-end.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/anatomy-of-a-target-back-end.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/build-system-in-the-gcc-directory.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/building-documentation.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/configuration-in-the-gcc-directory.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/headers-installed-by-gcc.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/library-source-files-and-headers-under-the-gcc-directory.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/makefile-targets.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/subdirectories-of-gcc.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/top-level-source-directory.rst:
+ New file.
+ * doc/gccint/standard-header-file-directories.rst: New file.
+ * doc/gccint/static-analyzer.rst: New file.
+ * doc/gccint/target-macros.rst: New file.
+ * doc/gccint/target-macros/adding-support-for-named-address-spaces.rst: New file.
+ * doc/gccint/target-macros/addressing-modes.rst: New file.
+ * doc/gccint/target-macros/adjusting-the-instruction-scheduler.rst: New file.
+ * doc/gccint/target-macros/anchored-addresses.rst: New file.
+ * doc/gccint/target-macros/c++-abi-parameters.rst: New file.
+ * doc/gccint/target-macros/condition-code-status.rst: New file.
+ * doc/gccint/target-macros/controlling-debugging-information-format.rst: New file.
+ * doc/gccint/target-macros/controlling-the-compilation-driver-gcc.rst: New file.
+ * doc/gccint/target-macros/cross-compilation-and-floating-point.rst: New file.
+ * doc/gccint/target-macros/d-abi-parameters.rst: New file.
+ * doc/gccint/target-macros/defining-coprocessor-specifics-for-mips-targets.rst: New file.
+ * doc/gccint/target-macros/defining-data-structures-for-per-function-information.rst:
+ New file.
+ * doc/gccint/target-macros/defining-target-specific-uses-of-attribute.rst: New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language.rst: New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/assembler-commands-for-alignment.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/assembler-commands-for-exception-regions.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/how-initialization-functions-are-handled.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/macros-controlling-initialization-routines.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-and-generation-of-labels.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-assembler-instructions.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-data.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-dispatch-tables.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-uninitialized-variables.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/the-overall-framework-of-an-assembler-file.rst:
+ New file.
+ * doc/gccint/target-macros/describing-relative-costs-of-operations.rst: New file.
+ * doc/gccint/target-macros/dividing-the-output-into-sections-texts-data.rst: New file.
+ * doc/gccint/target-macros/emulating-tls.rst: New file.
+ * doc/gccint/target-macros/implementing-the-varargs-macros.rst: New file.
+ * doc/gccint/target-macros/implicit-calls-to-library-routines.rst: New file.
+ * doc/gccint/target-macros/layout-of-source-language-data-types.rst: New file.
+ * doc/gccint/target-macros/miscellaneous-parameters.rst: New file.
+ * doc/gccint/target-macros/mode-switching-instructions.rst: New file.
+ * doc/gccint/target-macros/parameters-for-precompiled-header-validity-checking.rst:
+ New file.
+ * doc/gccint/target-macros/position-independent-code.rst: New file.
+ * doc/gccint/target-macros/register-classes.rst: New file.
+ * doc/gccint/target-macros/register-usage.rst: New file.
+ * doc/gccint/target-macros/run-time-target-specification.rst: New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions.rst: New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/basic-stack-layout.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/caller-saves-register-allocation.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/eliminating-frame-pointer-and-arg-pointer.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/exception-handling-support.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/function-entry-and-exit.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/generating-code-for-profiling.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/how-large-values-are-returned.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/how-scalar-function-values-are-returned.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/miscellaneous-register-hooks.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/passing-arguments-in-registers.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/passing-function-arguments-on-the-stack.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/permitting-tail-calls.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/registers-that-address-the-stack-frame.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/shrink-wrapping-separate-components.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/specifying-how-stack-checking-is-done.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/stack-smashing-protection.rst:
+ New file.
+ * doc/gccint/target-macros/storage-layout.rst: New file.
+ * doc/gccint/target-macros/support-for-nested-functions.rst: New file.
+ * doc/gccint/target-macros/the-global-targetm-variable.rst: New file.
+ * doc/gccint/target-makefile-fragments.rst: New file.
+ * doc/gccint/testsuites.rst: New test.
+ * doc/gccint/testsuites/ada-language-testsuites.rst: New test.
+ * doc/gccint/testsuites/c-language-testsuites.rst: New test.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests.rst: New test.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/commands-for-use-in-dg-final.rst:
+ New test.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/features-for-dg-add-options.rst:
+ New test.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/keywords-describing-target-attributes.rst:
+ New test.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/selecting-targets-to-which-a-test-applies.rst:
+ New test.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/syntax-and-descriptions-of-test-directives.rst:
+ New test.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/variants-of-dg-require-support.rst:
+ New test.
+ * doc/gccint/testsuites/idioms-used-in-testsuite-code.rst: New test.
+ * doc/gccint/testsuites/support-for-testing-binary-compatibility.rst: New test.
+ * doc/gccint/testsuites/support-for-testing-gcov.rst: New test.
+ * doc/gccint/testsuites/support-for-testing-gimple-passes.rst: New test.
+ * doc/gccint/testsuites/support-for-testing-link-time-optimizations.rst: New test.
+ * doc/gccint/testsuites/support-for-testing-profile-directed-optimizations.rst: New test.
+ * doc/gccint/testsuites/support-for-testing-rtl-passes.rst: New test.
+ * doc/gccint/testsuites/support-for-torture-testing-using-multiple-options.rst: New test.
+ * doc/gccint/the-gcc-low-level-runtime-library.rst: New file.
+ * doc/gccint/the-gcc-low-level-runtime-library/language-independent-routines-for-exception-handling.rst:
+ New file.
+ * doc/gccint/the-gcc-low-level-runtime-library/miscellaneous-runtime-library-routines.rst:
+ New file.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-decimal-floating-point-emulation.rst:
+ New file.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-fixed-point-fractional-emulation.rst:
+ New file.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-floating-point-emulation.rst:
+ New file.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-integer-arithmetic.rst:
+ New file.
+ * doc/gccint/the-language.rst: New file.
+ * doc/gccint/user-experience-guidelines.rst: New file.
+ * doc/install/binaries.rst: New file.
+ * doc/install/building.rst: New file.
+ * doc/install/building/building-a-cross-compiler.rst: New file.
+ * doc/install/building/building-a-native-compiler.rst: New file.
+ * doc/install/building/building-in-parallel.rst: New file.
+ * doc/install/building/building-the-ada-compiler.rst: New file.
+ * doc/install/building/building-the-d-compiler.rst: New file.
+ * doc/install/building/building-with-profile-feedback.rst: New file.
+ * doc/install/conf.py: New file.
+ * doc/install/configuration.rst: New file.
+ * doc/install/copyright.rst: New file.
+ * doc/install/downloading-gcc.rst: New file.
+ * doc/install/final-installation.rst: New file.
+ * doc/install/gnu-free-documentation-license.rst: New file.
+ * doc/install/host-target-specific-installation-notes-for-gcc.rst: New file.
+ * doc/install/how-can-you-run-the-testsuite-on-selected-tests.rst: New test.
+ * doc/install/how-to-interpret-test-results.rst: New file.
+ * doc/install/index.rst: New file.
+ * doc/install/indices-and-tables.rst: New file.
+ * doc/install/installing-gcc.rst: New file.
+ * doc/install/passing-options-and-running-multiple-testsuites.rst: New test.
+ * doc/install/prerequisites.rst: New file.
+ * doc/install/submitting-test-results.rst: New file.
+ * doc/install/testing.rst: New file.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/gcc/gcc-command-options/options-controlling-c++-dialect.rst: Revert.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * common/common-target.def: Port to RST.
+ * target.def: Port to RST.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gccint/target-macros/adding-support-for-named-address-spaces.rst: Use tm.rst.in file.
+ * doc/gccint/target-macros/addressing-modes.rst: Likewise.
+ * doc/gccint/target-macros/adjusting-the-instruction-scheduler.rst: Likewise.
+ * doc/gccint/target-macros/anchored-addresses.rst: Likewise.
+ * doc/gccint/target-macros/c++-abi-parameters.rst: Likewise.
+ * doc/gccint/target-macros/condition-code-status.rst: Likewise.
+ * doc/gccint/target-macros/controlling-debugging-information-format.rst: Likewise.
+ * doc/gccint/target-macros/controlling-the-compilation-driver-gcc.rst: Likewise.
+ * doc/gccint/target-macros/d-abi-parameters.rst: Likewise.
+ * doc/gccint/target-macros/defining-target-specific-uses-of-attribute.rst: Likewise.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/assembler-commands-for-exception-regions.rst:
+ Likewise.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/macros-controlling-initialization-routines.rst:
+ Likewise.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-and-generation-of-labels.rst:
+ Likewise.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-assembler-instructions.rst:
+ Likewise.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-data.rst:
+ Likewise.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-dispatch-tables.rst:
+ Likewise.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/the-overall-framework-of-an-assembler-file.rst:
+ Likewise.
+ * doc/gccint/target-macros/describing-relative-costs-of-operations.rst: Likewise.
+ * doc/gccint/target-macros/dividing-the-output-into-sections-texts-data.rst: Likewise.
+ * doc/gccint/target-macros/emulating-tls.rst: Likewise.
+ * doc/gccint/target-macros/implementing-the-varargs-macros.rst: Likewise.
+ * doc/gccint/target-macros/implicit-calls-to-library-routines.rst: Likewise.
+ * doc/gccint/target-macros/layout-of-source-language-data-types.rst: Likewise.
+ * doc/gccint/target-macros/miscellaneous-parameters.rst: Likewise.
+ * doc/gccint/target-macros/mode-switching-instructions.rst: Likewise.
+ * doc/gccint/target-macros/parameters-for-precompiled-header-validity-checking.rst:
+ Likewise.
+ * doc/gccint/target-macros/register-classes.rst: Likewise.
+ * doc/gccint/target-macros/register-usage.rst: Likewise.
+ * doc/gccint/target-macros/run-time-target-specification.rst: Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/basic-stack-layout.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/eliminating-frame-pointer-and-arg-pointer.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/function-entry-and-exit.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/generating-code-for-profiling.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/how-large-values-are-returned.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/how-scalar-function-values-are-returned.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/miscellaneous-register-hooks.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/passing-arguments-in-registers.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/passing-function-arguments-on-the-stack.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/permitting-tail-calls.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/registers-that-address-the-stack-frame.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/shrink-wrapping-separate-components.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/specifying-how-stack-checking-is-done.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/stack-smashing-protection.rst:
+ Likewise.
+ * doc/gccint/target-macros/storage-layout.rst: Likewise.
+ * doc/gccint/target-macros/support-for-nested-functions.rst: Likewise.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * Makefile.in: Support Sphinx based documentation.
+ * configure: Regenerate.
+ * configure.ac: Support Sphinx based documentation.
+ * genhooks.cc (struct s_hook): Emit tm.rst.in file.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gccint/target-macros/tm.rst.in: New file.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/analyzer.texi: Removed.
+ * doc/avr-mmcu.texi: Removed.
+ * doc/bugreport.texi: Removed.
+ * doc/cfg.texi: Removed.
+ * doc/collect2.texi: Removed.
+ * doc/compat.texi: Removed.
+ * doc/configfiles.texi: Removed.
+ * doc/configterms.texi: Removed.
+ * doc/contrib.texi: Removed.
+ * doc/contribute.texi: Removed.
+ * doc/cpp.texi: Removed.
+ * doc/cppdiropts.texi: Removed.
+ * doc/cppenv.texi: Removed.
+ * doc/cppinternals.texi: Removed.
+ * doc/cppopts.texi: Removed.
+ * doc/cppwarnopts.texi: Removed.
+ * doc/extend.texi: Removed.
+ * doc/fragments.texi: Removed.
+ * doc/frontends.texi: Removed.
+ * doc/gcc.texi: Removed.
+ * doc/gccint.texi: Removed.
+ * doc/gcov-dump.texi: Removed.
+ * doc/gcov-tool.texi: Removed.
+ * doc/gcov.texi: Removed.
+ * doc/generic.texi: Removed.
+ * doc/gimple.texi: Removed.
+ * doc/gnu.texi: Removed.
+ * doc/gty.texi: Removed.
+ * doc/headerdirs.texi: Removed.
+ * doc/hostconfig.texi: Removed.
+ * doc/implement-c.texi: Removed.
+ * doc/implement-cxx.texi: Removed.
+ * doc/include/fdl.texi: Removed.
+ * doc/include/funding.texi: Removed.
+ * doc/include/gcc-common.texi: Removed.
+ * doc/include/gpl_v3.texi: Removed.
+ * doc/install.texi: Removed.
+ * doc/interface.texi: Removed.
+ * doc/invoke.texi: Removed.
+ * doc/languages.texi: Removed.
+ * doc/libgcc.texi: Removed.
+ * doc/loop.texi: Removed.
+ * doc/lto-dump.texi: Removed.
+ * doc/lto.texi: Removed.
+ * doc/makefile.texi: Removed.
+ * doc/match-and-simplify.texi: Removed.
+ * doc/md.texi: Removed.
+ * doc/objc.texi: Removed.
+ * doc/optinfo.texi: Removed.
+ * doc/options.texi: Removed.
+ * doc/passes.texi: Removed.
+ * doc/plugins.texi: Removed.
+ * doc/poly-int.texi: Removed.
+ * doc/portability.texi: Removed.
+ * doc/rtl.texi: Removed.
+ * doc/service.texi: Removed.
+ * doc/sourcebuild.texi: Removed.
+ * doc/standards.texi: Removed.
+ * doc/tm.texi: Removed.
+ * doc/tree-ssa.texi: Removed.
+ * doc/trouble.texi: Removed.
+ * doc/ux.texi: Removed.
+ * doc/tm.texi.in: Removed.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * target.def: Use proper lexers for target macros.
+ * doc/gccint/target-macros/tm.rst.in: Re-generate.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Makefile.in: Support --with-sphinx-build.
+ * configure.ac:
+ * configure: Regenerate.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/gcc/gcc-command-options/options-controlling-the-kind-of-output.rst:
+ Fix cross manual refs.
+ * doc/gcc/language-standards-supported-by-gcc/references-for-other-languages.rst:
+ Likewise.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gccint/target-macros/defining-the-output-assembler-language/assembler-commands-for-exception-regions.rst:
+ Do not include tm.rst.in.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/the-overall-framework-of-an-assembler-file.rst:
+ Likewise.
+ * doc/gccint/target-macros/run-time-target-specification.rst:
+ Likewise.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/passing-arguments-in-registers.rst:
+ Port to RST.
+ * doc/gccint/target-macros/storage-layout.rst: Likewise.
+ * doc/gcc/gcc-command-options/machine-dependent-options/x86-options.rst: Sync with master.
+ * doc/gcc/gcc-command-options/option-summary.rst: Likewise.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Makefile.in: Support installation if sphinx-build is missing.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Makefile.in: Add vpath default for .rst files.
+ * config/avr/avr-devices.cc: For port RST.
+ * config/avr/avr-mcus.def: Update path.
+ * config/avr/gen-avr-mmcu-texi.cc: Moved to...
+ * config/avr/gen-avr-mmcu-rst.cc: ...here.
+ * config/avr/t-avr: Update to rst.
+ * doc/gcc/gcc-command-options/machine-dependent-options/avr-mmcu.rst: Re-generate.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * opts.cc (get_option_html_page): Port to sphinx URLs.
+ (get_option_url): Likewise.
+ (test_get_option_html_page): Likewise.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/cpp/character-sets.rst:
+ Add trailing newline.
+ * doc/cpp/conditional-syntax.rst:
+ Add trailing newline.
+ * doc/cpp/conditional-uses.rst:
+ Add trailing newline.
+ * doc/cpp/conditionals.rst:
+ Add trailing newline.
+ * doc/cpp/copyright.rst:
+ Add trailing newline.
+ * doc/cpp/deleted-code.rst:
+ Add trailing newline.
+ * doc/cpp/diagnostics.rst:
+ Add trailing newline.
+ * doc/cpp/environment-variables.rst:
+ Add trailing newline.
+ * doc/cpp/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/cpp/header-files.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/alternatives-to-wrapper-ifndef.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/computed-includes.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/include-operation.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/include-syntax.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/once-only-headers.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/search-path.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/system-headers.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/wrapper-headers.rst:
+ Add trailing newline.
+ * doc/cpp/implementation-defined-behavior.rst:
+ Add trailing newline.
+ * doc/cpp/implementation-details.rst:
+ Add trailing newline.
+ * doc/cpp/implementation-limits.rst:
+ Add trailing newline.
+ * doc/cpp/index.rst:
+ Add trailing newline.
+ * doc/cpp/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/cpp/initial-processing.rst:
+ Add trailing newline.
+ * doc/cpp/invocation.rst:
+ Add trailing newline.
+ * doc/cpp/line-control.rst:
+ Add trailing newline.
+ * doc/cpp/macros.rst:
+ Add trailing newline.
+ * doc/cpp/macros/concatenation.rst:
+ Add trailing newline.
+ * doc/cpp/macros/directives-within-macro-arguments.rst:
+ Add trailing newline.
+ * doc/cpp/macros/function-like-macros.rst:
+ Add trailing newline.
+ * doc/cpp/macros/macro-arguments.rst:
+ Add trailing newline.
+ * doc/cpp/macros/macro-pitfalls.rst:
+ Add trailing newline.
+ * doc/cpp/macros/object-like-macros.rst:
+ Add trailing newline.
+ * doc/cpp/macros/predefined-macros.rst:
+ Add trailing newline.
+ * doc/cpp/macros/stringizing.rst:
+ Add trailing newline.
+ * doc/cpp/macros/undefining-and-redefining-macros.rst:
+ Add trailing newline.
+ * doc/cpp/macros/variadic-macros.rst:
+ Add trailing newline.
+ * doc/cpp/obsolete-features.rst:
+ Add trailing newline.
+ * doc/cpp/other-directives.rst:
+ Add trailing newline.
+ * doc/cpp/overview.rst:
+ Add trailing newline.
+ * doc/cpp/pragmas.rst:
+ Add trailing newline.
+ * doc/cpp/preprocessor-output.rst:
+ Add trailing newline.
+ * doc/cpp/the-preprocessing-language.rst:
+ Add trailing newline.
+ * doc/cpp/tokenization.rst:
+ Add trailing newline.
+ * doc/cpp/traditional-lexical-analysis.rst:
+ Add trailing newline.
+ * doc/cpp/traditional-macros.rst:
+ Add trailing newline.
+ * doc/cpp/traditional-miscellany.rst:
+ Add trailing newline.
+ * doc/cpp/traditional-mode.rst:
+ Add trailing newline.
+ * doc/cpp/traditional-warnings.rst:
+ Add trailing newline.
+ * doc/cppinternals/copyright.rst:
+ Add trailing newline.
+ * doc/cppinternals/cppinternals.rst:
+ Add trailing newline.
+ * doc/cppinternals/cpplib.rst:
+ Add trailing newline.
+ * doc/cppinternals/files.rst:
+ Add trailing newline.
+ * doc/cppinternals/index.rst:
+ Add trailing newline.
+ * doc/cppinternals/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/cppinternals/internal-representation-of-macros.rst:
+ Add trailing newline.
+ * doc/cppinternals/just-which-line-number-anyway.rst:
+ Add trailing newline.
+ * doc/cppinternals/lexing-a-line.rst:
+ Add trailing newline.
+ * doc/cppinternals/lexing-a-token.rst:
+ Add trailing newline.
+ * doc/cppinternals/looking-for-a-function-like-macros-opening-parenthesis.rst:
+ Add trailing newline.
+ * doc/cppinternals/macro-expansion-overview.rst:
+ Add trailing newline.
+ * doc/cppinternals/marking-tokens-ineligible-for-future-expansion.rst:
+ Add trailing newline.
+ * doc/cppinternals/multiple-include-optimization.rst:
+ Add trailing newline.
+ * doc/cppinternals/overview.rst:
+ Add trailing newline.
+ * doc/cppinternals/representation-of-line-numbers.rst:
+ Add trailing newline.
+ * doc/cppinternals/scanning-the-replacement-list-for-macros-to-expand.rst:
+ Add trailing newline.
+ * doc/gcc/binary-compatibility.rst:
+ Add trailing newline.
+ * doc/gcc/c++-implementation-defined-behavior.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/architecture.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/arrays-and-pointers.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/characters.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/declarators.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/environment.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/floating-point.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/hints.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/identifiers.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/integers.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/library-functions.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/locale-specific-behavior.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/preprocessing-directives.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/qualifiers.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/statements.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/structures-unions-enumerations-and-bit-fields.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/translation.rst:
+ Add trailing newline.
+ * doc/gcc/conditionally-supported-behavior.rst:
+ Add trailing newline.
+ * doc/gcc/contributing-to-gcc-development.rst:
+ Add trailing newline.
+ * doc/gcc/contributors-to-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/copyright.rst:
+ Add trailing newline.
+ * doc/gcc/exception-handling.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/backwards-compatibility.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/c++-concepts.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/c++-interface-and-implementation-pragmas.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/c++-specific-variable-function-and-type-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/deprecated-features.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/extracting-the-function-pointer-from-a-bound-pointer-to-member-function.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/function-multiversioning.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/restricting-pointer-aliasing.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/type-traits.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/vague-linkage.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/when-is-a-volatile-c++-object-accessed.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/wheres-the-template.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/128-bit-integers.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/additional-floating-types.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/alternate-keywords.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/an-inline-function-is-as-fast-as-a-macro.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/arithmetic-on-void-and-function-pointers.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/arrays-of-length-zero.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/arrays-of-variable-length.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/attribute-syntax.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/binary-constants-using-the-0b-prefix.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/built-in-functions-for-memory-model-aware-atomic-operations.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/built-in-functions-to-perform-arithmetic-with-overflow-checking.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/c++-style-comments.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/case-ranges.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/cast-to-a-union-type.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/complex-numbers.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/compound-literals.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/conditionals-with-omitted-operands.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/constructing-function-calls.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/decimal-floating-types.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/aarch64-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/amd-gcn-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/arc-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/arm-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/avr-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/blackfin-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/bpf-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/c-sky-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/common-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/epiphany-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/h8-300-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/ia-64-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/m32c-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/m32r-d-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/m68k-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/mcore-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/mep-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/microblaze-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/microsoft-windows-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/mips-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/msp430-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/nds32-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/nios-ii-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/nvidia-ptx-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/powerpc-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/risc-v-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/rl78-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/rx-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/s-390-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/sh-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/symbian-os-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/v850-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/visium-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/x86-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/xstormy16-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/designated-initializers.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/determining-the-alignment-of-functions-types-or-variables.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/dollar-signs-in-identifier-names.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/double-word-integers.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/enumerator-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/fixed-point-types.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/format-checks-specific-to-particular-target-machines.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/function-names-as-strings.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/getting-the-return-or-frame-address-of-a-function.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/half-precision-floating-point.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/hex-floats.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/how-to-use-inline-assembly-language-in-c-code.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/incomplete-enum-types.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/label-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/labels-as-values.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/legacy-sync-built-in-functions-for-atomic-memory-access.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/locally-declared-labels.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/macros-with-a-variable-number-of-arguments.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/mixed-declarations-labels-and-code.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/named-address-spaces.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/nested-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/non-constant-initializers.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/non-lvalue-arrays-may-have-subscripts.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/nonlocal-gotos.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/object-size-checking-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/other-built-in-functions-provided-by-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/pointer-arguments-in-variadic-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/pointers-to-arrays-with-qualifiers-work-as-expected.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/pragmas-accepted-by-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/prototypes-and-old-style-function-definitions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/referring-to-a-type-with-typeof.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/slightly-looser-rules-for-escaped-newlines.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/specifying-attributes-of-types.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/specifying-attributes-of-variables.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/statement-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/statements-and-declarations-in-expressions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/structures-with-no-members.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/support-for-offsetof.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/aarch64-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/alpha-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/altera-nios-ii-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arc-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arc-simd-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-armv8-m-security-extensions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-c-language-extensions-acle.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-floating-point-status-and-control-intrinsics.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-iwmmxt-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/avr-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/basic-powerpc-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/blackfin-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/bpf-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/fr-v-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-dsp-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-loongson-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-paired-single-support.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-simd-architecture-msa-support.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/msp430-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/nds32-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/other-mips-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/picochip-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-altivec-vsx-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-atomic-memory-operation-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-hardware-transactional-memory-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-matrix-multiply-assist-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/pru-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/risc-v-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/rx-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/s-390-system-z-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/sh-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/sparc-vis-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/ti-c6x-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/x86-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/x86-control-flow-protection-intrinsics.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/x86-transactional-memory-intrinsics.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/the-character-esc-in-constants.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/thread-local-storage.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/unnamed-structure-and-union-fields.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/using-vector-instructions-through-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/when-is-a-volatile-object-accessed.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/x86-specific-memory-model-extensions-for-transactional-memory.rst:
+ Add trailing newline.
+ * doc/gcc/funding.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/compiling-c++-programs.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/description.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/environment-variables-affecting-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/gcc-developer-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/aarch64-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/adapteva-epiphany-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/amd-gcn-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/arc-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/arm-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/avr-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/blackfin-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/c-sky-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/c6x-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/cris-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/darwin-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/dec-alpha-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ebpf-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/fr30-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/frv-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ft32-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/gnu-linux-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/h8-300-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/hppa-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ia-64-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ibm-rs-6000-and-powerpc-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/lm32-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/loongarch-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/m32c-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/m32r-d-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/m680x0-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mcore-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mep-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/microblaze-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mips-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mmix-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mn10300-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/moxie-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/msp430-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/nds32-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/nios-ii-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/nvidia-ptx-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/openrisc-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/options-for-system-v.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/pdp-11-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/picochip-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/powerpc-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/pru-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/risc-v-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/rl78-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/rx-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/s-390-and-zseries-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/score-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/sh-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/solaris-2-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/sparc-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/v850-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/vax-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/visium-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/vms-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/vxworks-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/x86-windows-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/xstormy16-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/xtensa-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/zseries-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-controlling-c++-dialect.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-controlling-c-dialect.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-controlling-objective-c-and-objective-c++-dialects.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-controlling-the-kind-of-output.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-controlling-the-preprocessor.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-for-code-generation-conventions.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-for-debugging-your-program.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-for-directory-search.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-for-linking.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-that-control-optimization.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-that-control-static-analysis.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-to-control-diagnostic-messages-formatting.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-to-request-or-suppress-warnings.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/passing-options-to-the-assembler.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/program-instrumentation-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/specifying-subprocesses-and-the-switches-to-pass-to-them.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/using-precompiled-headers.rst:
+ Add trailing newline.
+ * doc/gcc/gcc.rst:
+ Add trailing newline.
+ * doc/gcc/gcov-dump.rst:
+ Add trailing newline.
+ * doc/gcc/gcov-tool.rst:
+ Add trailing newline.
+ * doc/gcc/gcov.rst:
+ Add trailing newline.
+ * doc/gcc/gcov/brief-description-of-gcov-data-files.rst:
+ Add trailing newline.
+ * doc/gcc/gcov/data-file-relocation-to-support-cross-profiling.rst:
+ Add trailing newline.
+ * doc/gcc/gcov/introduction-to-gcov.rst:
+ Add trailing newline.
+ * doc/gcc/gcov/invoking-gcov.rst:
+ Add trailing newline.
+ * doc/gcc/gcov/profiling-and-test-coverage-in-freestanding-environments.rst:
+ Add trailing newline.
+ * doc/gcc/gcov/using-gcov-with-gcc-optimization.rst:
+ Add trailing newline.
+ * doc/gcc/general-public-license-3.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/compatibilityalias.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/constant-string-objects.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/exceptions.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/fast-enumeration.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/garbage-collection.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/gnu-objective-c-runtime-api.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/load-executing-code-before-main.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/messaging-with-the-gnu-objective-c-runtime.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/synchronization.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/type-encoding.rst:
+ Add trailing newline.
+ * doc/gcc/gnu.rst:
+ Add trailing newline.
+ * doc/gcc/have-you-found-a-bug.rst:
+ Add trailing newline.
+ * doc/gcc/how-and-where-to-report-bugs.rst:
+ Add trailing newline.
+ * doc/gcc/how-to-get-help-with-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/index.rst:
+ Add trailing newline.
+ * doc/gcc/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/actual-bugs-we-havent-fixed-yet.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/certain-changes-we-dont-want-to-make.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/common-misunderstandings-with-gnu-c.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/disappointments-and-misunderstandings.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/fixed-header-files.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/incompatibilities-of-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/interoperation.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/standard-libraries.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/warning-messages-and-error-messages.rst:
+ Add trailing newline.
+ * doc/gcc/language-standards-supported-by-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/language-standards-supported-by-gcc/c++-language.rst:
+ Add trailing newline.
+ * doc/gcc/language-standards-supported-by-gcc/c-language.rst:
+ Add trailing newline.
+ * doc/gcc/language-standards-supported-by-gcc/d-language.rst:
+ Add trailing newline.
+ * doc/gcc/language-standards-supported-by-gcc/go-language.rst:
+ Add trailing newline.
+ * doc/gcc/language-standards-supported-by-gcc/objective-c-and-objective-c++-languages.rst:
+ Add trailing newline.
+ * doc/gcc/lto-dump.rst:
+ Add trailing newline.
+ * doc/gcc/programming-languages-supported-by-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/reporting-bugs.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/alias-analysis.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/annotations.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/memory-model.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/ssa-operands.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/static-single-assignment.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/data-dependency-analysis.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/iv-analysis-on-rtl.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/loop-closed-ssa-form.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/loop-manipulation.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/loop-querying.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/loop-representation.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/number-of-iterations-analysis.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/scalar-evolutions.rst:
+ Add trailing newline.
+ * doc/gccint/analyzer-internals.rst:
+ Add trailing newline.
+ * doc/gccint/collect2.rst:
+ Add trailing newline.
+ * doc/gccint/contributing-to-gcc-development.rst:
+ Add trailing newline.
+ * doc/gccint/contributors-to-gcc.rst:
+ Add trailing newline.
+ * doc/gccint/control-flow-graph.rst:
+ Add trailing newline.
+ * doc/gccint/control-flow-graph/basic-blocks.rst:
+ Add trailing newline.
+ * doc/gccint/control-flow-graph/edges.rst:
+ Add trailing newline.
+ * doc/gccint/control-flow-graph/liveness-information.rst:
+ Add trailing newline.
+ * doc/gccint/control-flow-graph/maintaining-the-cfg.rst:
+ Add trailing newline.
+ * doc/gccint/control-flow-graph/profile-information.rst:
+ Add trailing newline.
+ * doc/gccint/copyright.rst:
+ Add trailing newline.
+ * doc/gccint/debugging-the-analyzer.rst:
+ Add trailing newline.
+ * doc/gccint/funding.rst:
+ Add trailing newline.
+ * doc/gccint/gcc-and-portability.rst:
+ Add trailing newline.
+ * doc/gccint/general-public-license-3.rst:
+ Add trailing newline.
+ * doc/gccint/generic.rst:
+ Add trailing newline.
+ * doc/gccint/generic/attributes-in-trees.rst:
+ Add trailing newline.
+ * doc/gccint/generic/c-and-c++-trees.rst:
+ Add trailing newline.
+ * doc/gccint/generic/declarations.rst:
+ Add trailing newline.
+ * doc/gccint/generic/deficiencies.rst:
+ Add trailing newline.
+ * doc/gccint/generic/expressions.rst:
+ Add trailing newline.
+ * doc/gccint/generic/functions.rst:
+ Add trailing newline.
+ * doc/gccint/generic/language-dependent-trees.rst:
+ Add trailing newline.
+ * doc/gccint/generic/overview.rst:
+ Add trailing newline.
+ * doc/gccint/generic/statements.rst:
+ Add trailing newline.
+ * doc/gccint/generic/types.rst:
+ Add trailing newline.
+ * doc/gccint/gimple-api.rst:
+ Add trailing newline.
+ * doc/gccint/gimple.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/adding-a-new-gimple-statement-code.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/class-hierarchy-of-gimple-statements.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/exception-handling.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/gimple-instruction-set.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/gimple-sequences.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/manipulating-gimple-statements.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/operands.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/sequence-iterators.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/statement-and-operand-traversals.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/temporaries.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-representation.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleasm.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleassign.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplebind.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplecall.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplecatch.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplecond.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpledebug.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleehfilter.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplegoto.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplelabel.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplenop.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompatomicload.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompatomicstore.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompcontinue.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompcritical.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompfor.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompmaster.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompordered.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompparallel.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompreturn.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompsection.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompsections.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompsingle.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplephi.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleresx.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplereturn.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleswitch.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpletry.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplewithcleanupexpr.rst:
+ Add trailing newline.
+ * doc/gccint/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/gccint/guidelines-for-diagnostics.rst:
+ Add trailing newline.
+ * doc/gccint/guidelines-for-options.rst:
+ Add trailing newline.
+ * doc/gccint/host-common.rst:
+ Add trailing newline.
+ * doc/gccint/host-configuration.rst:
+ Add trailing newline.
+ * doc/gccint/host-filesystem.rst:
+ Add trailing newline.
+ * doc/gccint/host-makefile-fragments.rst:
+ Add trailing newline.
+ * doc/gccint/host-misc.rst:
+ Add trailing newline.
+ * doc/gccint/index.rst:
+ Add trailing newline.
+ * doc/gccint/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/gccint/interfacing-to-gcc-output.rst:
+ Add trailing newline.
+ * doc/gccint/introduction.rst:
+ Add trailing newline.
+ * doc/gccint/language-front-ends-in-gcc.rst:
+ Add trailing newline.
+ * doc/gccint/link-time-optimization.rst:
+ Add trailing newline.
+ * doc/gccint/link-time-optimization/design-overview.rst:
+ Add trailing newline.
+ * doc/gccint/link-time-optimization/internal-flags-controlling-lto1.rst:
+ Add trailing newline.
+ * doc/gccint/link-time-optimization/lto-file-sections.rst:
+ Add trailing newline.
+ * doc/gccint/link-time-optimization/using-summary-information-in-ipa-passes.rst:
+ Add trailing newline.
+ * doc/gccint/link-time-optimization/whole-program-assumptions-linker-plugin-and-symbol-visibilities.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/c-statements-for-assembler-output.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/canonicalization-of-instructions.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/conditional-execution.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/constant-definitions.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/defining-how-to-split-instructions.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/defining-jump-instruction-patterns.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/defining-looping-instruction-patterns.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/defining-rtl-sequences-for-code-generation.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/everything-about-instruction-patterns.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/example-of-defineinsn.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/including-patterns-in-machine-descriptions.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/instruction-attributes.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/interdependence-of-patterns.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/iterators.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/machine-specific-peephole-optimizers.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/operand-constraints.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/output-templates-and-operand-substitution.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/overview-of-how-the-machine-description-is-used.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/predicates.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/rtl-template.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/rtl-templates-transformations.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/standard-pattern-names-for-generation.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/when-the-order-of-patterns-matters.rst:
+ Add trailing newline.
+ * doc/gccint/makefile-fragments.rst:
+ Add trailing newline.
+ * doc/gccint/match-and-simplify.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information/how-to-invoke-the-garbage-collector.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information/marking-roots-for-the-garbage-collector.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information/source-files-containing-type-information.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information/support-for-inheritance.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information/support-for-user-provided-gc-marking-routines.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information/the-inside-of-a-gty.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information/troubleshooting-the-garbage-collector.rst:
+ Add trailing newline.
+ * doc/gccint/option-file-format.rst:
+ Add trailing newline.
+ * doc/gccint/option-properties.rst:
+ Add trailing newline.
+ * doc/gccint/option-specification-files.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler/gimplification-pass.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler/inter-procedural-optimization-passes.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler/optimization-info.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler/parsing-pass.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler/pass-manager.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler/rtl-passes.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler/tree-ssa-passes.rst:
+ Add trailing newline.
+ * doc/gccint/plugins.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/building-gcc-plugins.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/controlling-which-passes-are-being-run.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/giving-information-about-a-plugin.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/interacting-with-the-gcc-garbage-collector.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/interacting-with-the-pass-manager.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/keeping-track-of-available-passes.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/loading-plugins.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/plugin-api.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/recording-information-about-pass-execution.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/registering-custom-attributes-or-pragmas.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/access-to-operands.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/access-to-special-operands.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/assembler-instructions-as-expressions.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/bit-fields.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/comparison-operations.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/constant-expression-types.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/conversions.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/declarations.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/embedded-side-effects-on-addresses.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/flags-in-an-rtl-expression.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/insns.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/machine-modes.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/on-the-side-ssa-form-for-rtl.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/reading-rtl.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/registers-and-memory.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/rtl-classes-and-formats.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/rtl-expressions-for-arithmetic.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/rtl-object-types.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/rtl-representation-of-function-call-insns.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/side-effect-expressions.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/structure-sharing-assumptions.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/variable-location-debug-information-in-rtl.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/vector-operations.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/alignment-of-polyints.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/arithmetic-on-polyints.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/comparisons-involving-polyint.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/computing-bounds-on-polyints.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/consequences-of-using-polyint.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/converting-polyints.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/guidelines-for-using-polyint.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/miscellaneous-polyint-routines.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/overview-of-polyint.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/configure-terms-and-history.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/anatomy-of-a-language-front-end.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/anatomy-of-a-target-back-end.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/build-system-in-the-gcc-directory.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/configuration-in-the-gcc-directory.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/headers-installed-by-gcc.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/library-source-files-and-headers-under-the-gcc-directory.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/makefile-targets.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/subdirectories-of-gcc.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/top-level-source-directory.rst:
+ Add trailing newline.
+ * doc/gccint/standard-header-file-directories.rst:
+ Add trailing newline.
+ * doc/gccint/static-analyzer.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/controlling-debugging-information-format.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/controlling-the-compilation-driver-gcc.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/cross-compilation-and-floating-point.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-coprocessor-specifics-for-mips-targets.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-data-structures-for-per-function-information.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/assembler-commands-for-alignment.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/how-initialization-functions-are-handled.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/macros-controlling-initialization-routines.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-and-generation-of-labels.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-assembler-instructions.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-data.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-uninitialized-variables.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/implicit-calls-to-library-routines.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/layout-of-source-language-data-types.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/position-independent-code.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/register-usage.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/basic-stack-layout.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/caller-saves-register-allocation.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/exception-handling-support.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/passing-function-arguments-on-the-stack.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/registers-that-address-the-stack-frame.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/support-for-nested-functions.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/the-global-targetm-variable.rst:
+ Add trailing newline.
+ * doc/gccint/target-makefile-fragments.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/ada-language-testsuites.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/c-language-testsuites.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/commands-for-use-in-dg-final.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/features-for-dg-add-options.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/keywords-describing-target-attributes.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/selecting-targets-to-which-a-test-applies.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/syntax-and-descriptions-of-test-directives.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/variants-of-dg-require-support.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/idioms-used-in-testsuite-code.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/support-for-testing-binary-compatibility.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/support-for-testing-gcov.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/support-for-testing-gimple-passes.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/support-for-testing-link-time-optimizations.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/support-for-testing-profile-directed-optimizations.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/support-for-testing-rtl-passes.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/support-for-torture-testing-using-multiple-options.rst:
+ Add trailing newline.
+ * doc/gccint/the-gcc-low-level-runtime-library.rst:
+ Add trailing newline.
+ * doc/gccint/the-gcc-low-level-runtime-library/language-independent-routines-for-exception-handling.rst:
+ Add trailing newline.
+ * doc/gccint/the-gcc-low-level-runtime-library/miscellaneous-runtime-library-routines.rst:
+ Add trailing newline.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-decimal-floating-point-emulation.rst:
+ Add trailing newline.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-fixed-point-fractional-emulation.rst:
+ Add trailing newline.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-floating-point-emulation.rst:
+ Add trailing newline.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-integer-arithmetic.rst:
+ Add trailing newline.
+ * doc/gccint/the-language.rst:
+ Add trailing newline.
+ * doc/gccint/user-experience-guidelines.rst:
+ Add trailing newline.
+ * doc/install/binaries.rst:
+ Add trailing newline.
+ * doc/install/building.rst:
+ Add trailing newline.
+ * doc/install/building/building-a-cross-compiler.rst:
+ Add trailing newline.
+ * doc/install/building/building-a-native-compiler.rst:
+ Add trailing newline.
+ * doc/install/building/building-in-parallel.rst:
+ Add trailing newline.
+ * doc/install/building/building-the-ada-compiler.rst:
+ Add trailing newline.
+ * doc/install/building/building-the-d-compiler.rst:
+ Add trailing newline.
+ * doc/install/building/building-with-profile-feedback.rst:
+ Add trailing newline.
+ * doc/install/configuration.rst:
+ Add trailing newline.
+ * doc/install/copyright.rst:
+ Add trailing newline.
+ * doc/install/downloading-gcc.rst:
+ Add trailing newline.
+ * doc/install/final-installation.rst:
+ Add trailing newline.
+ * doc/install/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/install/host-target-specific-installation-notes-for-gcc.rst:
+ Add trailing newline.
+ * doc/install/how-can-you-run-the-testsuite-on-selected-tests.rst:
+ Add trailing newline.
+ * doc/install/how-to-interpret-test-results.rst:
+ Add trailing newline.
+ * doc/install/index.rst:
+ Add trailing newline.
+ * doc/install/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/install/installing-gcc.rst:
+ Add trailing newline.
+ * doc/install/passing-options-and-running-multiple-testsuites.rst:
+ Add trailing newline.
+ * doc/install/prerequisites.rst:
+ Add trailing newline.
+ * doc/install/submitting-test-results.rst:
+ Add trailing newline.
+ * doc/install/testing.rst:
+ Add trailing newline.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * Makefile.in: Use new install URL.
+ * doc/gcc/gcc-command-options/machine-dependent-options/avr-options.rst:
+ Use intersphinx link.
+ * doc/gcc/gcc-command-options/options-to-control-diagnostic-messages-formatting.rst:
+ Use new URL.
+ * doc/gccint/source-tree-structure-and-build-system.rst: Use
+ intersphinx link.
+ * doc/install/host-target-specific-installation-notes-for-gcc.rst: Likewise.
+ * doc/install/installing-gcc.rst: Likewise.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+ Sinan <sinan.lin@linux.alibaba.com>
+
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/ssa-operands.rst:
+ Add missing variable name.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/cpp/conf.py: Add newline at last line.
+ * doc/cppinternals/conf.py: Add newline at last line.
+ * doc/gcc/conf.py: Add newline at last line.
+ * doc/gccint/conf.py: Add newline at last line.
+ * doc/install/conf.py: Add newline at last line.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/gcc/gcc-command-options/options-that-control-static-analysis.rst:
+ Revert.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/cpp/pragmas.rst: Revert.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/gcc/gcc-command-options/machine-dependent-options/aarch64-options.rst: Revert.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/gcc/gcc-command-options/machine-dependent-options/aarch64-options.rst: Revert.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/gcc/gcc-command-options/options-that-control-static-analysis.rst: Revert.
+ * doc/gcc/gcc-command-options/options-to-request-or-suppress-warnings.rst: Revert.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-13 Jonathan Wakely <jwakely@redhat.com>
+
+ * doc/install/testing.rst: Remove anachronism about separate
+ source tarballs.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-13 Martin Liska <mliska@suse.cz>
+
+ PR other/107620
+ * configure: Regenerate.
+ * configure.ac: Always set sphinx-build.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/gcc/gcc-command-options/option-summary.rst: Revert.
+ * doc/gcc/gcc-command-options/options-that-control-static-analysis.rst: Revert.
+
+2022-11-14 Haochen Jiang <haochen.jiang@intel.com>
+
+ * common/config/i386/i386-common.cc
+ (OPTION_MASK_ISA2_AMX_INT8_SET): Add AMX-TILE dependency.
+ (OPTION_MASK_ISA2_AMX_BF16_SET): Ditto.
+ (OPTION_MASK_ISA2_AMX_FP16_SET): Ditto.
+ (OPTION_MASK_ISA2_AMX_TILE_UNSET): Disable AMX_{INT8,
+ BF16, FP16} when disable AMX_TILE.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/gcc/gcc-command-options/machine-dependent-options/x86-options.rst:
+ Revert.
+ * doc/gcc/gcc-command-options/option-summary.rst:
+ Revert.
+
+2022-11-14 Hongyu Wang <hongyu.wang@intel.com>
+
+ * common/config/i386/i386-common.cc (ix86_optimization_table):
+ Enable small loop unroll at O2 by default.
+ * config/i386/i386.cc (ix86_loop_unroll_adjust): Adjust unroll
+ factor if -munroll-only-small-loops enabled and -funroll-loops/
+ -funroll-all-loops are disabled.
+ * config/i386/i386.h (struct processor_costs): Add 2 field
+ small_unroll_ninsns and small_unroll_factor.
+ * config/i386/i386.opt: Add -munroll-only-small-loops.
+ * doc/gcc/gcc-command-options/machine-dependent-options/x86-options.rst:
+ Document -munroll-only-small-loops.
+ * doc/gcc/gcc-command-options/option-summary.rst: Likewise.
+ * loop-init.cc (pass_rtl_unroll_loops::gate): Enable rtl
+ loop unrolling for -O2-speed and above if target hook
+ loop_unroll_adjust exists.
+ (pass_rtl_unroll_loops::execute): Set UAP_UNROLL flag
+ when target hook loop_unroll_adjust exists.
+ * config/i386/x86-tune-costs.h: Update all processor costs
+ with small_unroll_ninsns = 4 and small_unroll_factor = 2.
+
+2022-11-13 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106235
+ * doc/gcc/gcc-command-options/option-summary.rst: Add
+ -Wno-analyzer-tainted-assertion.
+ * doc/gcc/gcc-command-options/options-that-control-static-analysis.rst:
+ Add -Wno-analyzer-tainted-assertion.
+
+2022-11-13 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/bitmanip.md: New define_split.
+
+2022-11-13 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/riscv.cc (riscv_rtx_costs): Recognize shNadd,
+ if expressed as a plus and multiplication with a power-of-2.
+ Split costing for MINUS from PLUS.
+
+2022-11-13 Martin Liska <mliska@suse.cz>
+
+ PR other/107620
+ * configure: Regenerate.
+ * configure.ac: Always set sphinx-build.
+
+2022-11-13 Joseph Myers <joseph@codesourcery.com>
+
+ * ginclude/float.h [__STDC_VERSION__ > 201710L]
+ (__STDC_VERSION_FLOAT_H__): New macro.
+ * ginclude/stdarg.h [__STDC_VERSION__ > 201710L]
+ (__STDC_VERSION_STDARG_H__): New macro.
+ * ginclude/stdatomic.h [__STDC_VERSION__ > 201710L]
+ (__STDC_VERSION_STDATOMIC_H__): New macro.
+ * ginclude/stddef.h [__STDC_VERSION__ > 201710L]
+ (__STDC_VERSION_STDDEF_H__): New macro.
+ * ginclude/stdint-gcc.h [__STDC_VERSION__ > 201710L]
+ (__STDC_VERSION_STDINT_H__): New macro.
+ * glimits.h [__STDC_VERSION__ > 201710L]
+ (__STDC_VERSION_LIMITS_H__): New macro.
+
+2022-11-13 Jonathan Wakely <jwakely@redhat.com>
+
+ * doc/install/testing.rst: Remove anachronism about separate
+ source tarballs.
+
+2022-11-12 Joseph Myers <joseph@codesourcery.com>
+
+ * dfp.cc (decimal_from_binary): Convert a canonical NaN to a
+ canonical NaN.
+
+2022-11-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * value-range.cc (range_tests_signbit): Move to set from here...
+ (range_tests_signed_zeros): ...to here.
+
+2022-11-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op-float.cc (build_lt): Adjust with frange_nextafter
+ instead of default to a closed range.
+ (build_gt): Same.
+
+2022-11-12 Aldy Hernandez <aldyh@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * range-op-float.cc (float_binary_op_range_finish): New function.
+ (foperator_plus::op1_range): New.
+ (foperator_plus::op2_range): New.
+ (foperator_minus::op1_range): New.
+ (foperator_minus::op2_range): New.
+ (foperator_mult::op1_range): New.
+ (foperator_mult::op2_range): New.
+ (foperator_div::op1_range): New.
+ (foperator_div::op2_range): New.
+
+2022-11-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107569
+ * range-op-float.cc (zero_p, contains_p, singleton_inf_p,
+ signbit_known_p, zero_range, inf_range, zero_to_inf_range): New
+ functions.
+ (foperator_mult_div_base): New class.
+ (foperator_mult, foperator_div): Derive from that and use
+ protected static method from it as well as above new functions
+ to simplify the code.
+
+2022-11-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107569
+ * range-op-float.cc (foperator_div): New class.
+ (floating_op_table::floating_op_table): Use foperator_div
+ for RDIV_EXPR.
+
+2022-11-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107569
+ PR tree-optimization/107591
+ * range-op.h (range_operator_float::rv_fold): Add relation_kind
+ argument.
+ * range-op-float.cc (range_operator_float::fold_range): Name
+ last argument trio and pass trio.op1_op2 () as last argument to
+ rv_fold.
+ (range_operator_float::rv_fold): Add relation_kind argument.
+ (foperator_plus::rv_fold, foperator_minus::rv_fold): Likewise.
+ (foperator_mult): New class.
+ (floating_op_table::floating_op_table): Use foperator_mult for
+ MULT_EXPR.
+
+2022-11-12 Xi Ruoyao <xry111@xry111.site>
+
+ * config/loongarch/loongarch.md (UNSPEC_FLOGB): New unspec.
+ (type): Add flogb.
+ (logb_non_negative<mode>2): New instruction template.
+ (logb<mode>2): New define_expand.
+
+2022-11-12 Xi Ruoyao <xry111@xry111.site>
+
+ * config/loongarch/loongarch.md (UNSPEC_FSCALEB): New unspec.
+ (type): Add fscaleb.
+ (IMODE): New mode attr.
+ (ldexp<mode>3): New instruction template.
+
+2022-11-12 Xi Ruoyao <xry111@xry111.site>
+
+ * config/loongarch/loongarch.md (UNSPEC_FTINT): New unspec.
+ (UNSPEC_FTINTRM): Likewise.
+ (UNSPEC_FTINTRP): Likewise.
+ (LRINT): New define_int_iterator.
+ (lrint_pattern): New define_int_attr.
+ (lrint_submenmonic): Likewise.
+ (lrint_allow_inexact): Likewise.
+ (ANYFI): New define_mode_iterator.
+ (lrint<ANYF><ANYFI>): New instruction template.
+
+2022-11-12 Xi Ruoyao <xry111@xry111.site>
+
+ * config/loongarch/loongarch.md (frint_<fmt>): Rename to ..
+ (rint<mode>2): .. this.
+
+2022-11-11 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106147
+ * doc/gcc/gcc-command-options/options-that-control-static-analysis.rst:
+ Add -Wanalyzer-infinite-recursion.
+ * doc/gcc/gcc-command-options/options-to-request-or-suppress-warnings.rst
+ (-Winfinite-recursion): Mention -Wanalyzer-infinite-recursion.
+
+2022-11-11 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106147
+ * Makefile.in (ANALYZER_OBJS): Add analyzer/infinite-recursion.o.
+
+2022-11-11 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/107523
+ * gimple-range.cc (gimple_ranger::update_stmt): Use fur_stmt
+ rather than fur_depend.
+
+2022-11-11 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-vrp.cc (rvrp_folder::rvrp_folder): Init m_last_bb_stmt.
+ (rvrp_folder::pre_fold_bb): Set m_last_bb_stmt.
+ (rvrp_folder::pre_fold_stmt): Check for transitive inferred ranges.
+ (rvrp_folder::fold_stmt): Check in pre_fold_stmt instead.
+
+2022-11-11 Srinath Parvathaneni <srinath.parvathaneni@arm.com>
+
+ * config/aarch64/aarch64-cores.def (AARCH64_CORE): Add Cortex-X1C
+ CPU.
+ * config/aarch64/aarch64-tune.md: Regenerate.
+ * doc/gcc/gcc-command-options/machine-dependent-options/aarch64-options.rst:
+ Document Cortex-X1C CPU.
+
+2022-11-11 Srinath Parvathaneni <srinath.parvathaneni@arm.com>
+
+ * config/aarch64/aarch64-cores.def (AARCH64_CORE): Add Cortex-A715
+ CPU.
+ * config/aarch64/aarch64-tune.md: Regenerate.
+ * doc/gcc/gcc-command-options/machine-dependent-options/aarch64-options.rst:
+ Document Cortex-A715 CPU.
+
+2022-11-11 Richard Biener <rguenther@suse.de>
+ Nikita Voronov <nik_1357@mail.ru>
+
+ PR tree-optimization/107554
+ * tree-ssa-strlen.cc (strlen_pass::count_nonzero_bytes):
+ Use unsigned HOST_WIDE_INT type for the strlen.
+
+2022-11-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/105142
+ * gimple-fold.cc (fosa_unwind): New global.
+ (follow_outer_ssa_edges): When the SSA definition to follow
+ is does not dominate fosa_bb, temporarily clear flow-sensitive
+ info. Make sure to not expand stmts with not defined overflow.
+ (maybe_fold_comparisons_from_match_pd): Set up unwind stack
+ for follow_outer_ssa_edges and unwind flow-sensitive info
+ clearing after matching.
+
+2022-11-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op.cc (operator_mult::fold_range): Remove.
+ (operator_div::fold_range): Remove.
+ (operator_bitwise_and): Remove.
+
+2022-11-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op.cc (update_known_bitmask): Avoid unnecessary intersection.
+
+2022-11-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op.cc (range_operator::fold_range): Call
+ update_known_bitmask.
+ (operator_bitwise_and::fold_range): Avoid setting nonzero bits
+ when range is undefined.
+
+2022-11-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op.cc (class operator_div): Remove tree code.
+ (operator_div::wi_op_overflows): Handle EXACT_DIV_EXPR as
+ TRUNC_DIV_EXPR.
+
+2022-11-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op.cc: (range_op_table::set): Set m_code.
+ (integral_table::integral_table): Handle shared entries.
+ (pointer_table::pointer_table): Same.
+ * range-op.h (class range_operator): Add m_code.
+
+2022-11-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107618
+ * tree-ssa-copy.cc (stmt_may_generate_copy): Simulate all
+ assignments with a single SSA use.
+ (copy_prop_visit_assignment): Use gimple_fold_stmt_to_constant_1
+ to perform simple constant folding.
+ (copy_prop::visit_stmt): Visit all assignments.
+
+2022-11-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/84646
+ * tree-ssa-dce.cc (pass_dce::set_pass_param): Add param
+ wheter to run update-address-taken.
+ (pass_dce::execute): Honor it.
+ * passes.def: Exchange last DCE and CD-DCE invocations.
+ Swap pass_tail_calls and the last DCE.
+
+2022-11-11 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+ Monk Chiang <monk.chiang@sifive.com>
+
+ * config/riscv/riscv-v.cc (emit_pred_move): Adjust for scalable register spilling.
+ (legitimize_move): Ditto.
+ * config/riscv/riscv.cc (riscv_v_adjust_scalable_frame): New function.
+ (riscv_first_stack_step): Adjust for scalable register spilling.
+ (riscv_expand_prologue): Ditto.
+ (riscv_expand_epilogue): Ditto.
+ (riscv_dwarf_poly_indeterminate_value): New function.
+ (TARGET_DWARF_POLY_INDETERMINATE_VALUE): New target hook support for register spilling.
+ * config/riscv/riscv.h (RISCV_DWARF_VLENB): New macro.
+ (RISCV_PROLOGUE_TEMP2_REGNUM): Ditto.
+ (RISCV_PROLOGUE_TEMP2): Ditto.
+ * config/riscv/vector-iterators.md: New iterators.
+ * config/riscv/vector.md (*mov<mode>): Fix it for register spilling.
+ (*mov<mode>_whole): New pattern.
+ (*mov<mode>_fract): New pattern.
+ (@pred_mov<mode>): Fix it for register spilling.
+
+2022-11-11 Jonathan Wakely <jwakely@redhat.com>
+
+ PR c/85487
+ * doc/cpp/pragmas.rst (Pragmas): Document region pragmas.
+
+2022-11-11 Haochen Jiang <haochen.jiang@intel.com>
+
+ * config/i386/i386-builtin.def (BDESC): Add
+ OPTION_MASK_ISA2_PREFETCHI for prefetchi builtin.
+ * config/i386/i386-expand.cc (ix86_expand_builtin):
+ Add ISA check before emit_insn.
+ * config/i386/prfchiintrin.h: Add target for intrin.
+
+2022-11-10 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/99671
+ * tristate.h (tristate::is_unknown): New.
+
+2022-11-10 David Malcolm <dmalcolm@redhat.com>
+
+ * doc/gcc/gcc-command-options/options-that-control-static-analysis.rst:
+ Add -Wanalyzer-deref-before-check.
+
+2022-11-10 Marek Polacek <polacek@redhat.com>
+
+ * doc/gcc/gcc-command-options/options-controlling-c++-dialect.rst:
+ Extend the description of -Wdangling-reference.
+
+2022-11-10 Andrew Pinski <apinski@marvell.com>
+
+ * config/bfin/bfin.h (SLOW_SHORT_ACCESS): Delete.
+ * config/i386/i386.h (SLOW_SHORT_ACCESS): Delete.
+ * system.h: Poison SLOW_SHORT_ACCESS
+
+2022-11-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * value-range.cc (frange::set_nonnegative): Remove NAN sign handling.
+ (range_tests_signed_zeros): Adjust test.
+
+2022-11-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/84646
+ * tree-ssa-forwprop.cc (pass_forwprop::execute): Improve
+ copy propagation across PHIs.
+
+2022-11-10 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/riscv-cores.def (RISCV_TUNE): Update
+ sifive-7-series to point to the sifive_7 pipeline description.
+
+2022-11-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/84646
+ * tree-ssa-ccp.cc (set_lattice_value): Make sure we
+ allow a const -> copy transition and avoid using meet
+ in that case.
+
+2022-11-10 Martin Liska <mliska@suse.cz>
+
+ * doc/cpp/conf.py: Add newline at last line.
+ * doc/cppinternals/conf.py: Add newline at last line.
+ * doc/gcc/conf.py: Add newline at last line.
+ * doc/gccint/conf.py: Add newline at last line.
+ * doc/install/conf.py: Add newline at last line.
+
+2022-11-10 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-loop-unswitch.cc (init_loop_unswitch_info): First collect
+ candidates and determine the outermost loop to unswitch.
+ (tree_ssa_unswitch_loops): First perform all guard hoisting,
+ then perform unswitching on innermost loop predicates.
+ (find_unswitching_predicates_for_bb): Keep track of the
+ outermost loop to unswitch.
+ (evaluate_bbs): Adjust exit test.
+ (tree_unswitch_single_loop): Dump whether we unswitched an outer
+ loop.
+ (tree_unswitch_loop): Remove assert we unswitch only innermost
+ loops.
+
+2022-11-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/107585
+ PR target/107546
+ * config/i386/i386-expand.cc (ix86_expand_int_sse_cmp): Use
+ gen_int_mode rather than GEN_INT.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+ Sinan <sinan.lin@linux.alibaba.com>
+
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/ssa-operands.rst:
+ Add missing variable name.
+
+2022-11-09 Aldy Hernandez <aldyh@redhat.com>
+
+ * value-range-storage.cc (frange_storage_slot::get_frange): Clear
+ NAN if appropriate.
+ * value-range.cc (range_tests_floats): New test.
+
+2022-11-09 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op-float.cc (class foperator_plus): Remove op[12]_range.
+ (class foperator_minus): Same.
+
+2022-11-09 Qing Zhao <qing.zhao@oracle.com>
+
+ * gimple-array-bounds.cc (trailing_array): Replace
+ array_at_struct_end_p with new name and update comments.
+ * gimple-fold.cc (get_range_strlen_tree): Likewise.
+ * gimple-ssa-warn-restrict.cc (builtin_memref::builtin_memref):
+ Likewise.
+ * graphite-sese-to-poly.cc (bounds_are_valid): Likewise.
+ * tree-if-conv.cc (idx_within_array_bound): Likewise.
+ * tree-object-size.cc (addr_object_size): Likewise.
+ * tree-ssa-alias.cc (component_ref_to_zero_sized_trailing_array_p):
+ Likewise.
+ (stmt_kills_ref_p): Likewise.
+ * tree-ssa-loop-niter.cc (idx_infer_loop_bounds): Likewise.
+ * tree-ssa-strlen.cc (maybe_set_strlen_range): Likewise.
+ * tree.cc (array_at_struct_end_p): Rename to ...
+ (array_ref_flexible_size_p): ... this.
+ (component_ref_size): Replace array_at_struct_end_p with new name.
+ * tree.h (array_at_struct_end_p): Rename to ...
+ (array_ref_flexible_size_p): ... this.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Makefile.in: Use new install URL.
+ * doc/gcc/gcc-command-options/machine-dependent-options/avr-options.rst:
+ Use intersphinx link.
+ * doc/gcc/gcc-command-options/options-to-control-diagnostic-messages-formatting.rst:
+ Use new URL.
+ * doc/gccint/source-tree-structure-and-build-system.rst: Use
+ intersphinx link.
+ * doc/install/host-target-specific-installation-notes-for-gcc.rst: Likewise.
+ * doc/install/installing-gcc.rst: Likewise.
+
+2022-11-09 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/84646
+ * tree-ssa-threadbackward.cc (back_threader::maybe_register_path):
+ Remove premature cycle rejection.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/cpp/character-sets.rst:
+ Add trailing newline.
+ * doc/cpp/conditional-syntax.rst:
+ Add trailing newline.
+ * doc/cpp/conditional-uses.rst:
+ Add trailing newline.
+ * doc/cpp/conditionals.rst:
+ Add trailing newline.
+ * doc/cpp/copyright.rst:
+ Add trailing newline.
+ * doc/cpp/deleted-code.rst:
+ Add trailing newline.
+ * doc/cpp/diagnostics.rst:
+ Add trailing newline.
+ * doc/cpp/environment-variables.rst:
+ Add trailing newline.
+ * doc/cpp/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/cpp/header-files.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/alternatives-to-wrapper-ifndef.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/computed-includes.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/include-operation.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/include-syntax.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/once-only-headers.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/search-path.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/system-headers.rst:
+ Add trailing newline.
+ * doc/cpp/header-files/wrapper-headers.rst:
+ Add trailing newline.
+ * doc/cpp/implementation-defined-behavior.rst:
+ Add trailing newline.
+ * doc/cpp/implementation-details.rst:
+ Add trailing newline.
+ * doc/cpp/implementation-limits.rst:
+ Add trailing newline.
+ * doc/cpp/index.rst:
+ Add trailing newline.
+ * doc/cpp/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/cpp/initial-processing.rst:
+ Add trailing newline.
+ * doc/cpp/invocation.rst:
+ Add trailing newline.
+ * doc/cpp/line-control.rst:
+ Add trailing newline.
+ * doc/cpp/macros.rst:
+ Add trailing newline.
+ * doc/cpp/macros/concatenation.rst:
+ Add trailing newline.
+ * doc/cpp/macros/directives-within-macro-arguments.rst:
+ Add trailing newline.
+ * doc/cpp/macros/function-like-macros.rst:
+ Add trailing newline.
+ * doc/cpp/macros/macro-arguments.rst:
+ Add trailing newline.
+ * doc/cpp/macros/macro-pitfalls.rst:
+ Add trailing newline.
+ * doc/cpp/macros/object-like-macros.rst:
+ Add trailing newline.
+ * doc/cpp/macros/predefined-macros.rst:
+ Add trailing newline.
+ * doc/cpp/macros/stringizing.rst:
+ Add trailing newline.
+ * doc/cpp/macros/undefining-and-redefining-macros.rst:
+ Add trailing newline.
+ * doc/cpp/macros/variadic-macros.rst:
+ Add trailing newline.
+ * doc/cpp/obsolete-features.rst:
+ Add trailing newline.
+ * doc/cpp/other-directives.rst:
+ Add trailing newline.
+ * doc/cpp/overview.rst:
+ Add trailing newline.
+ * doc/cpp/pragmas.rst:
+ Add trailing newline.
+ * doc/cpp/preprocessor-output.rst:
+ Add trailing newline.
+ * doc/cpp/the-preprocessing-language.rst:
+ Add trailing newline.
+ * doc/cpp/tokenization.rst:
+ Add trailing newline.
+ * doc/cpp/traditional-lexical-analysis.rst:
+ Add trailing newline.
+ * doc/cpp/traditional-macros.rst:
+ Add trailing newline.
+ * doc/cpp/traditional-miscellany.rst:
+ Add trailing newline.
+ * doc/cpp/traditional-mode.rst:
+ Add trailing newline.
+ * doc/cpp/traditional-warnings.rst:
+ Add trailing newline.
+ * doc/cppinternals/copyright.rst:
+ Add trailing newline.
+ * doc/cppinternals/cppinternals.rst:
+ Add trailing newline.
+ * doc/cppinternals/cpplib.rst:
+ Add trailing newline.
+ * doc/cppinternals/files.rst:
+ Add trailing newline.
+ * doc/cppinternals/index.rst:
+ Add trailing newline.
+ * doc/cppinternals/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/cppinternals/internal-representation-of-macros.rst:
+ Add trailing newline.
+ * doc/cppinternals/just-which-line-number-anyway.rst:
+ Add trailing newline.
+ * doc/cppinternals/lexing-a-line.rst:
+ Add trailing newline.
+ * doc/cppinternals/lexing-a-token.rst:
+ Add trailing newline.
+ * doc/cppinternals/looking-for-a-function-like-macros-opening-parenthesis.rst:
+ Add trailing newline.
+ * doc/cppinternals/macro-expansion-overview.rst:
+ Add trailing newline.
+ * doc/cppinternals/marking-tokens-ineligible-for-future-expansion.rst:
+ Add trailing newline.
+ * doc/cppinternals/multiple-include-optimization.rst:
+ Add trailing newline.
+ * doc/cppinternals/overview.rst:
+ Add trailing newline.
+ * doc/cppinternals/representation-of-line-numbers.rst:
+ Add trailing newline.
+ * doc/cppinternals/scanning-the-replacement-list-for-macros-to-expand.rst:
+ Add trailing newline.
+ * doc/gcc/binary-compatibility.rst:
+ Add trailing newline.
+ * doc/gcc/c++-implementation-defined-behavior.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/architecture.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/arrays-and-pointers.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/characters.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/declarators.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/environment.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/floating-point.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/hints.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/identifiers.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/integers.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/library-functions.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/locale-specific-behavior.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/preprocessing-directives.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/qualifiers.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/statements.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/structures-unions-enumerations-and-bit-fields.rst:
+ Add trailing newline.
+ * doc/gcc/c-implementation-defined-behavior/translation.rst:
+ Add trailing newline.
+ * doc/gcc/conditionally-supported-behavior.rst:
+ Add trailing newline.
+ * doc/gcc/contributing-to-gcc-development.rst:
+ Add trailing newline.
+ * doc/gcc/contributors-to-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/copyright.rst:
+ Add trailing newline.
+ * doc/gcc/exception-handling.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/backwards-compatibility.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/c++-concepts.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/c++-interface-and-implementation-pragmas.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/c++-specific-variable-function-and-type-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/deprecated-features.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/extracting-the-function-pointer-from-a-bound-pointer-to-member-function.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/function-multiversioning.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/restricting-pointer-aliasing.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/type-traits.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/vague-linkage.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/when-is-a-volatile-c++-object-accessed.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c++-language/wheres-the-template.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/128-bit-integers.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/additional-floating-types.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/alternate-keywords.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/an-inline-function-is-as-fast-as-a-macro.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/arithmetic-on-void-and-function-pointers.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/arrays-of-length-zero.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/arrays-of-variable-length.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/attribute-syntax.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/binary-constants-using-the-0b-prefix.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/built-in-functions-for-memory-model-aware-atomic-operations.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/built-in-functions-to-perform-arithmetic-with-overflow-checking.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/c++-style-comments.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/case-ranges.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/cast-to-a-union-type.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/complex-numbers.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/compound-literals.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/conditionals-with-omitted-operands.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/constructing-function-calls.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/decimal-floating-types.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/aarch64-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/amd-gcn-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/arc-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/arm-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/avr-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/blackfin-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/bpf-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/c-sky-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/common-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/epiphany-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/h8-300-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/ia-64-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/m32c-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/m32r-d-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/m68k-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/mcore-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/mep-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/microblaze-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/microsoft-windows-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/mips-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/msp430-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/nds32-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/nios-ii-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/nvidia-ptx-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/powerpc-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/risc-v-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/rl78-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/rx-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/s-390-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/sh-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/symbian-os-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/v850-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/visium-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/x86-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/xstormy16-function-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/designated-initializers.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/determining-the-alignment-of-functions-types-or-variables.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/dollar-signs-in-identifier-names.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/double-word-integers.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/enumerator-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/fixed-point-types.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/format-checks-specific-to-particular-target-machines.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/function-names-as-strings.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/getting-the-return-or-frame-address-of-a-function.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/half-precision-floating-point.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/hex-floats.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/how-to-use-inline-assembly-language-in-c-code.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/incomplete-enum-types.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/label-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/labels-as-values.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/legacy-sync-built-in-functions-for-atomic-memory-access.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/locally-declared-labels.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/macros-with-a-variable-number-of-arguments.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/mixed-declarations-labels-and-code.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/named-address-spaces.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/nested-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/non-constant-initializers.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/non-lvalue-arrays-may-have-subscripts.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/nonlocal-gotos.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/object-size-checking-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/other-built-in-functions-provided-by-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/pointer-arguments-in-variadic-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/pointers-to-arrays-with-qualifiers-work-as-expected.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/pragmas-accepted-by-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/prototypes-and-old-style-function-definitions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/referring-to-a-type-with-typeof.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/slightly-looser-rules-for-escaped-newlines.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/specifying-attributes-of-types.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/specifying-attributes-of-variables.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/statement-attributes.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/statements-and-declarations-in-expressions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/structures-with-no-members.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/support-for-offsetof.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/aarch64-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/alpha-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/altera-nios-ii-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arc-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arc-simd-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-armv8-m-security-extensions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-c-language-extensions-acle.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-floating-point-status-and-control-intrinsics.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-iwmmxt-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/avr-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/basic-powerpc-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/blackfin-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/bpf-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/fr-v-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-dsp-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-loongson-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-paired-single-support.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-simd-architecture-msa-support.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/msp430-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/nds32-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/other-mips-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/picochip-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-altivec-vsx-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-atomic-memory-operation-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-hardware-transactional-memory-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-matrix-multiply-assist-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/pru-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/risc-v-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/rx-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/s-390-system-z-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/sh-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/sparc-vis-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/ti-c6x-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/x86-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/x86-control-flow-protection-intrinsics.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/x86-transactional-memory-intrinsics.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/the-character-esc-in-constants.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/thread-local-storage.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/unnamed-structure-and-union-fields.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/using-vector-instructions-through-built-in-functions.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/when-is-a-volatile-object-accessed.rst:
+ Add trailing newline.
+ * doc/gcc/extensions-to-the-c-language-family/x86-specific-memory-model-extensions-for-transactional-memory.rst:
+ Add trailing newline.
+ * doc/gcc/funding.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/compiling-c++-programs.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/description.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/environment-variables-affecting-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/gcc-developer-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/aarch64-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/adapteva-epiphany-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/amd-gcn-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/arc-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/arm-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/avr-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/blackfin-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/c-sky-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/c6x-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/cris-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/darwin-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/dec-alpha-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ebpf-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/fr30-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/frv-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ft32-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/gnu-linux-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/h8-300-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/hppa-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ia-64-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ibm-rs-6000-and-powerpc-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/lm32-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/loongarch-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/m32c-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/m32r-d-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/m680x0-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mcore-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mep-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/microblaze-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mips-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mmix-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mn10300-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/moxie-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/msp430-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/nds32-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/nios-ii-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/nvidia-ptx-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/openrisc-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/options-for-system-v.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/pdp-11-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/picochip-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/powerpc-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/pru-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/risc-v-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/rl78-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/rx-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/s-390-and-zseries-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/score-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/sh-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/solaris-2-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/sparc-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/v850-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/vax-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/visium-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/vms-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/vxworks-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/x86-windows-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/xstormy16-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/xtensa-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/machine-dependent-options/zseries-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-controlling-c++-dialect.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-controlling-c-dialect.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-controlling-objective-c-and-objective-c++-dialects.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-controlling-the-kind-of-output.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-controlling-the-preprocessor.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-for-code-generation-conventions.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-for-debugging-your-program.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-for-directory-search.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-for-linking.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-that-control-optimization.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-that-control-static-analysis.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-to-control-diagnostic-messages-formatting.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/options-to-request-or-suppress-warnings.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/passing-options-to-the-assembler.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/program-instrumentation-options.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/specifying-subprocesses-and-the-switches-to-pass-to-them.rst:
+ Add trailing newline.
+ * doc/gcc/gcc-command-options/using-precompiled-headers.rst:
+ Add trailing newline.
+ * doc/gcc/gcc.rst:
+ Add trailing newline.
+ * doc/gcc/gcov-dump.rst:
+ Add trailing newline.
+ * doc/gcc/gcov-tool.rst:
+ Add trailing newline.
+ * doc/gcc/gcov.rst:
+ Add trailing newline.
+ * doc/gcc/gcov/brief-description-of-gcov-data-files.rst:
+ Add trailing newline.
+ * doc/gcc/gcov/data-file-relocation-to-support-cross-profiling.rst:
+ Add trailing newline.
+ * doc/gcc/gcov/introduction-to-gcov.rst:
+ Add trailing newline.
+ * doc/gcc/gcov/invoking-gcov.rst:
+ Add trailing newline.
+ * doc/gcc/gcov/profiling-and-test-coverage-in-freestanding-environments.rst:
+ Add trailing newline.
+ * doc/gcc/gcov/using-gcov-with-gcc-optimization.rst:
+ Add trailing newline.
+ * doc/gcc/general-public-license-3.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/compatibilityalias.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/constant-string-objects.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/exceptions.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/fast-enumeration.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/garbage-collection.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/gnu-objective-c-runtime-api.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/load-executing-code-before-main.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/messaging-with-the-gnu-objective-c-runtime.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/synchronization.rst:
+ Add trailing newline.
+ * doc/gcc/gnu-objective-c-features/type-encoding.rst:
+ Add trailing newline.
+ * doc/gcc/gnu.rst:
+ Add trailing newline.
+ * doc/gcc/have-you-found-a-bug.rst:
+ Add trailing newline.
+ * doc/gcc/how-and-where-to-report-bugs.rst:
+ Add trailing newline.
+ * doc/gcc/how-to-get-help-with-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/index.rst:
+ Add trailing newline.
+ * doc/gcc/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/actual-bugs-we-havent-fixed-yet.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/certain-changes-we-dont-want-to-make.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/common-misunderstandings-with-gnu-c.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/disappointments-and-misunderstandings.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/fixed-header-files.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/incompatibilities-of-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/interoperation.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/standard-libraries.rst:
+ Add trailing newline.
+ * doc/gcc/known-causes-of-trouble-with-gcc/warning-messages-and-error-messages.rst:
+ Add trailing newline.
+ * doc/gcc/language-standards-supported-by-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/language-standards-supported-by-gcc/c++-language.rst:
+ Add trailing newline.
+ * doc/gcc/language-standards-supported-by-gcc/c-language.rst:
+ Add trailing newline.
+ * doc/gcc/language-standards-supported-by-gcc/d-language.rst:
+ Add trailing newline.
+ * doc/gcc/language-standards-supported-by-gcc/go-language.rst:
+ Add trailing newline.
+ * doc/gcc/language-standards-supported-by-gcc/objective-c-and-objective-c++-languages.rst:
+ Add trailing newline.
+ * doc/gcc/lto-dump.rst:
+ Add trailing newline.
+ * doc/gcc/programming-languages-supported-by-gcc.rst:
+ Add trailing newline.
+ * doc/gcc/reporting-bugs.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/alias-analysis.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/annotations.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/memory-model.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/ssa-operands.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/static-single-assignment.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/data-dependency-analysis.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/iv-analysis-on-rtl.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/loop-closed-ssa-form.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/loop-manipulation.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/loop-querying.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/loop-representation.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/number-of-iterations-analysis.rst:
+ Add trailing newline.
+ * doc/gccint/analysis-and-representation-of-loops/scalar-evolutions.rst:
+ Add trailing newline.
+ * doc/gccint/analyzer-internals.rst:
+ Add trailing newline.
+ * doc/gccint/collect2.rst:
+ Add trailing newline.
+ * doc/gccint/contributing-to-gcc-development.rst:
+ Add trailing newline.
+ * doc/gccint/contributors-to-gcc.rst:
+ Add trailing newline.
+ * doc/gccint/control-flow-graph.rst:
+ Add trailing newline.
+ * doc/gccint/control-flow-graph/basic-blocks.rst:
+ Add trailing newline.
+ * doc/gccint/control-flow-graph/edges.rst:
+ Add trailing newline.
+ * doc/gccint/control-flow-graph/liveness-information.rst:
+ Add trailing newline.
+ * doc/gccint/control-flow-graph/maintaining-the-cfg.rst:
+ Add trailing newline.
+ * doc/gccint/control-flow-graph/profile-information.rst:
+ Add trailing newline.
+ * doc/gccint/copyright.rst:
+ Add trailing newline.
+ * doc/gccint/debugging-the-analyzer.rst:
+ Add trailing newline.
+ * doc/gccint/funding.rst:
+ Add trailing newline.
+ * doc/gccint/gcc-and-portability.rst:
+ Add trailing newline.
+ * doc/gccint/general-public-license-3.rst:
+ Add trailing newline.
+ * doc/gccint/generic.rst:
+ Add trailing newline.
+ * doc/gccint/generic/attributes-in-trees.rst:
+ Add trailing newline.
+ * doc/gccint/generic/c-and-c++-trees.rst:
+ Add trailing newline.
+ * doc/gccint/generic/declarations.rst:
+ Add trailing newline.
+ * doc/gccint/generic/deficiencies.rst:
+ Add trailing newline.
+ * doc/gccint/generic/expressions.rst:
+ Add trailing newline.
+ * doc/gccint/generic/functions.rst:
+ Add trailing newline.
+ * doc/gccint/generic/language-dependent-trees.rst:
+ Add trailing newline.
+ * doc/gccint/generic/overview.rst:
+ Add trailing newline.
+ * doc/gccint/generic/statements.rst:
+ Add trailing newline.
+ * doc/gccint/generic/types.rst:
+ Add trailing newline.
+ * doc/gccint/gimple-api.rst:
+ Add trailing newline.
+ * doc/gccint/gimple.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/adding-a-new-gimple-statement-code.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/class-hierarchy-of-gimple-statements.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/exception-handling.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/gimple-instruction-set.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/gimple-sequences.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/manipulating-gimple-statements.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/operands.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/sequence-iterators.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/statement-and-operand-traversals.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/temporaries.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-representation.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleasm.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleassign.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplebind.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplecall.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplecatch.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplecond.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpledebug.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleehfilter.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplegoto.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplelabel.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplenop.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompatomicload.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompatomicstore.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompcontinue.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompcritical.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompfor.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompmaster.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompordered.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompparallel.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompreturn.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompsection.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompsections.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompsingle.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplephi.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleresx.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplereturn.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleswitch.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpletry.rst:
+ Add trailing newline.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplewithcleanupexpr.rst:
+ Add trailing newline.
+ * doc/gccint/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/gccint/guidelines-for-diagnostics.rst:
+ Add trailing newline.
+ * doc/gccint/guidelines-for-options.rst:
+ Add trailing newline.
+ * doc/gccint/host-common.rst:
+ Add trailing newline.
+ * doc/gccint/host-configuration.rst:
+ Add trailing newline.
+ * doc/gccint/host-filesystem.rst:
+ Add trailing newline.
+ * doc/gccint/host-makefile-fragments.rst:
+ Add trailing newline.
+ * doc/gccint/host-misc.rst:
+ Add trailing newline.
+ * doc/gccint/index.rst:
+ Add trailing newline.
+ * doc/gccint/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/gccint/interfacing-to-gcc-output.rst:
+ Add trailing newline.
+ * doc/gccint/introduction.rst:
+ Add trailing newline.
+ * doc/gccint/language-front-ends-in-gcc.rst:
+ Add trailing newline.
+ * doc/gccint/link-time-optimization.rst:
+ Add trailing newline.
+ * doc/gccint/link-time-optimization/design-overview.rst:
+ Add trailing newline.
+ * doc/gccint/link-time-optimization/internal-flags-controlling-lto1.rst:
+ Add trailing newline.
+ * doc/gccint/link-time-optimization/lto-file-sections.rst:
+ Add trailing newline.
+ * doc/gccint/link-time-optimization/using-summary-information-in-ipa-passes.rst:
+ Add trailing newline.
+ * doc/gccint/link-time-optimization/whole-program-assumptions-linker-plugin-and-symbol-visibilities.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/c-statements-for-assembler-output.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/canonicalization-of-instructions.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/conditional-execution.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/constant-definitions.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/defining-how-to-split-instructions.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/defining-jump-instruction-patterns.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/defining-looping-instruction-patterns.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/defining-rtl-sequences-for-code-generation.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/everything-about-instruction-patterns.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/example-of-defineinsn.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/including-patterns-in-machine-descriptions.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/instruction-attributes.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/interdependence-of-patterns.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/iterators.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/machine-specific-peephole-optimizers.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/operand-constraints.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/output-templates-and-operand-substitution.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/overview-of-how-the-machine-description-is-used.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/predicates.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/rtl-template.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/rtl-templates-transformations.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/standard-pattern-names-for-generation.rst:
+ Add trailing newline.
+ * doc/gccint/machine-descriptions/when-the-order-of-patterns-matters.rst:
+ Add trailing newline.
+ * doc/gccint/makefile-fragments.rst:
+ Add trailing newline.
+ * doc/gccint/match-and-simplify.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information/how-to-invoke-the-garbage-collector.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information/marking-roots-for-the-garbage-collector.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information/source-files-containing-type-information.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information/support-for-inheritance.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information/support-for-user-provided-gc-marking-routines.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information/the-inside-of-a-gty.rst:
+ Add trailing newline.
+ * doc/gccint/memory-management-and-type-information/troubleshooting-the-garbage-collector.rst:
+ Add trailing newline.
+ * doc/gccint/option-file-format.rst:
+ Add trailing newline.
+ * doc/gccint/option-properties.rst:
+ Add trailing newline.
+ * doc/gccint/option-specification-files.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler/gimplification-pass.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler/inter-procedural-optimization-passes.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler/optimization-info.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler/parsing-pass.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler/pass-manager.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler/rtl-passes.rst:
+ Add trailing newline.
+ * doc/gccint/passes-and-files-of-the-compiler/tree-ssa-passes.rst:
+ Add trailing newline.
+ * doc/gccint/plugins.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/building-gcc-plugins.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/controlling-which-passes-are-being-run.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/giving-information-about-a-plugin.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/interacting-with-the-gcc-garbage-collector.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/interacting-with-the-pass-manager.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/keeping-track-of-available-passes.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/loading-plugins.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/plugin-api.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/recording-information-about-pass-execution.rst:
+ Add trailing newline.
+ * doc/gccint/plugins/registering-custom-attributes-or-pragmas.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/access-to-operands.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/access-to-special-operands.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/assembler-instructions-as-expressions.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/bit-fields.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/comparison-operations.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/constant-expression-types.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/conversions.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/declarations.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/embedded-side-effects-on-addresses.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/flags-in-an-rtl-expression.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/insns.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/machine-modes.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/on-the-side-ssa-form-for-rtl.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/reading-rtl.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/registers-and-memory.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/rtl-classes-and-formats.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/rtl-expressions-for-arithmetic.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/rtl-object-types.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/rtl-representation-of-function-call-insns.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/side-effect-expressions.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/structure-sharing-assumptions.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/variable-location-debug-information-in-rtl.rst:
+ Add trailing newline.
+ * doc/gccint/rtl-representation/vector-operations.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/alignment-of-polyints.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/arithmetic-on-polyints.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/comparisons-involving-polyint.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/computing-bounds-on-polyints.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/consequences-of-using-polyint.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/converting-polyints.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/guidelines-for-using-polyint.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/miscellaneous-polyint-routines.rst:
+ Add trailing newline.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/overview-of-polyint.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/configure-terms-and-history.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/anatomy-of-a-language-front-end.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/anatomy-of-a-target-back-end.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/build-system-in-the-gcc-directory.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/configuration-in-the-gcc-directory.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/headers-installed-by-gcc.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/library-source-files-and-headers-under-the-gcc-directory.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/makefile-targets.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/subdirectories-of-gcc.rst:
+ Add trailing newline.
+ * doc/gccint/source-tree-structure-and-build-system/top-level-source-directory.rst:
+ Add trailing newline.
+ * doc/gccint/standard-header-file-directories.rst:
+ Add trailing newline.
+ * doc/gccint/static-analyzer.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/controlling-debugging-information-format.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/controlling-the-compilation-driver-gcc.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/cross-compilation-and-floating-point.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-coprocessor-specifics-for-mips-targets.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-data-structures-for-per-function-information.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/assembler-commands-for-alignment.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/how-initialization-functions-are-handled.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/macros-controlling-initialization-routines.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-and-generation-of-labels.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-assembler-instructions.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-data.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-uninitialized-variables.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/implicit-calls-to-library-routines.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/layout-of-source-language-data-types.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/position-independent-code.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/register-usage.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/basic-stack-layout.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/caller-saves-register-allocation.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/exception-handling-support.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/passing-function-arguments-on-the-stack.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/registers-that-address-the-stack-frame.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/support-for-nested-functions.rst:
+ Add trailing newline.
+ * doc/gccint/target-macros/the-global-targetm-variable.rst:
+ Add trailing newline.
+ * doc/gccint/target-makefile-fragments.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/ada-language-testsuites.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/c-language-testsuites.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/commands-for-use-in-dg-final.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/features-for-dg-add-options.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/keywords-describing-target-attributes.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/selecting-targets-to-which-a-test-applies.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/syntax-and-descriptions-of-test-directives.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/variants-of-dg-require-support.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/idioms-used-in-testsuite-code.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/support-for-testing-binary-compatibility.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/support-for-testing-gcov.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/support-for-testing-gimple-passes.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/support-for-testing-link-time-optimizations.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/support-for-testing-profile-directed-optimizations.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/support-for-testing-rtl-passes.rst:
+ Add trailing newline.
+ * doc/gccint/testsuites/support-for-torture-testing-using-multiple-options.rst:
+ Add trailing newline.
+ * doc/gccint/the-gcc-low-level-runtime-library.rst:
+ Add trailing newline.
+ * doc/gccint/the-gcc-low-level-runtime-library/language-independent-routines-for-exception-handling.rst:
+ Add trailing newline.
+ * doc/gccint/the-gcc-low-level-runtime-library/miscellaneous-runtime-library-routines.rst:
+ Add trailing newline.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-decimal-floating-point-emulation.rst:
+ Add trailing newline.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-fixed-point-fractional-emulation.rst:
+ Add trailing newline.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-floating-point-emulation.rst:
+ Add trailing newline.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-integer-arithmetic.rst:
+ Add trailing newline.
+ * doc/gccint/the-language.rst:
+ Add trailing newline.
+ * doc/gccint/user-experience-guidelines.rst:
+ Add trailing newline.
+ * doc/install/binaries.rst:
+ Add trailing newline.
+ * doc/install/building.rst:
+ Add trailing newline.
+ * doc/install/building/building-a-cross-compiler.rst:
+ Add trailing newline.
+ * doc/install/building/building-a-native-compiler.rst:
+ Add trailing newline.
+ * doc/install/building/building-in-parallel.rst:
+ Add trailing newline.
+ * doc/install/building/building-the-ada-compiler.rst:
+ Add trailing newline.
+ * doc/install/building/building-the-d-compiler.rst:
+ Add trailing newline.
+ * doc/install/building/building-with-profile-feedback.rst:
+ Add trailing newline.
+ * doc/install/configuration.rst:
+ Add trailing newline.
+ * doc/install/copyright.rst:
+ Add trailing newline.
+ * doc/install/downloading-gcc.rst:
+ Add trailing newline.
+ * doc/install/final-installation.rst:
+ Add trailing newline.
+ * doc/install/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/install/host-target-specific-installation-notes-for-gcc.rst:
+ Add trailing newline.
+ * doc/install/how-can-you-run-the-testsuite-on-selected-tests.rst:
+ Add trailing newline.
+ * doc/install/how-to-interpret-test-results.rst:
+ Add trailing newline.
+ * doc/install/index.rst:
+ Add trailing newline.
+ * doc/install/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/install/installing-gcc.rst:
+ Add trailing newline.
+ * doc/install/passing-options-and-running-multiple-testsuites.rst:
+ Add trailing newline.
+ * doc/install/prerequisites.rst:
+ Add trailing newline.
+ * doc/install/submitting-test-results.rst:
+ Add trailing newline.
+ * doc/install/testing.rst:
+ Add trailing newline.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * opts.cc (get_option_html_page): Port to sphinx URLs.
+ (get_option_url): Likewise.
+ (test_get_option_html_page): Likewise.
+
+2022-11-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107569
+ * range-op-float.cc (foperator_abs::op1_range): Clear NaNs
+ from the negatives frange before unioning it into r.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Makefile.in: Add vpath default for .rst files.
+ * config/avr/avr-devices.cc: For port RST.
+ * config/avr/avr-mcus.def: Update path.
+ * config/avr/gen-avr-mmcu-texi.cc: Moved to...
+ * config/avr/gen-avr-mmcu-rst.cc: ...here.
+ * config/avr/t-avr: Update to rst.
+ * doc/gcc/gcc-command-options/machine-dependent-options/avr-mmcu.rst: Re-generate.
+
+2022-11-09 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * config/riscv/riscv.cc (riscv_rtx_costs): Add BSWAP.
+
+2022-11-09 Xi Ruoyao <xry111@xry111.site>
+
+ * config/loongarch/loongarch.cc (loongarch_emit_int_compare):
+ Avoid signed overflow.
+
+2022-11-09 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op-float.cc (foperator_plus::op1_range): New.
+ (foperator_plus::op2_range): New.
+ (foperator_minus::op1_range): New.
+ (foperator_minus::op2_range): New.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Makefile.in: Support installation if sphinx-build is missing.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/passing-arguments-in-registers.rst:
+ Port to RST.
+ * doc/gccint/target-macros/storage-layout.rst: Likewise.
+ * doc/gcc/gcc-command-options/machine-dependent-options/x86-options.rst: Sync with master.
+ * doc/gcc/gcc-command-options/option-summary.rst: Likewise.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gccint/target-macros/defining-the-output-assembler-language/assembler-commands-for-exception-regions.rst:
+ Do not include tm.rst.in.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/the-overall-framework-of-an-assembler-file.rst:
+ Likewise.
+ * doc/gccint/target-macros/run-time-target-specification.rst:
+ Likewise.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gcc/gcc-command-options/options-controlling-the-kind-of-output.rst:
+ Fix cross manual refs.
+ * doc/gcc/language-standards-supported-by-gcc/references-for-other-languages.rst:
+ Likewise.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Makefile.in: Support --with-sphinx-build.
+ * configure.ac:
+ * configure: Regenerate.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * target.def: Use proper lexers for target macros.
+ * doc/gccint/target-macros/tm.rst.in: Re-generate.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/analyzer.texi: Removed.
+ * doc/avr-mmcu.texi: Removed.
+ * doc/bugreport.texi: Removed.
+ * doc/cfg.texi: Removed.
+ * doc/collect2.texi: Removed.
+ * doc/compat.texi: Removed.
+ * doc/configfiles.texi: Removed.
+ * doc/configterms.texi: Removed.
+ * doc/contrib.texi: Removed.
+ * doc/contribute.texi: Removed.
+ * doc/cpp.texi: Removed.
+ * doc/cppdiropts.texi: Removed.
+ * doc/cppenv.texi: Removed.
+ * doc/cppinternals.texi: Removed.
+ * doc/cppopts.texi: Removed.
+ * doc/cppwarnopts.texi: Removed.
+ * doc/extend.texi: Removed.
+ * doc/fragments.texi: Removed.
+ * doc/frontends.texi: Removed.
+ * doc/gcc.texi: Removed.
+ * doc/gccint.texi: Removed.
+ * doc/gcov-dump.texi: Removed.
+ * doc/gcov-tool.texi: Removed.
+ * doc/gcov.texi: Removed.
+ * doc/generic.texi: Removed.
+ * doc/gimple.texi: Removed.
+ * doc/gnu.texi: Removed.
+ * doc/gty.texi: Removed.
+ * doc/headerdirs.texi: Removed.
+ * doc/hostconfig.texi: Removed.
+ * doc/implement-c.texi: Removed.
+ * doc/implement-cxx.texi: Removed.
+ * doc/include/fdl.texi: Removed.
+ * doc/include/funding.texi: Removed.
+ * doc/include/gcc-common.texi: Removed.
+ * doc/include/gpl_v3.texi: Removed.
+ * doc/install.texi: Removed.
+ * doc/interface.texi: Removed.
+ * doc/invoke.texi: Removed.
+ * doc/languages.texi: Removed.
+ * doc/libgcc.texi: Removed.
+ * doc/loop.texi: Removed.
+ * doc/lto-dump.texi: Removed.
+ * doc/lto.texi: Removed.
+ * doc/makefile.texi: Removed.
+ * doc/match-and-simplify.texi: Removed.
+ * doc/md.texi: Removed.
+ * doc/objc.texi: Removed.
+ * doc/optinfo.texi: Removed.
+ * doc/options.texi: Removed.
+ * doc/passes.texi: Removed.
+ * doc/plugins.texi: Removed.
+ * doc/poly-int.texi: Removed.
+ * doc/portability.texi: Removed.
+ * doc/rtl.texi: Removed.
+ * doc/service.texi: Removed.
+ * doc/sourcebuild.texi: Removed.
+ * doc/standards.texi: Removed.
+ * doc/tm.texi: Removed.
+ * doc/tree-ssa.texi: Removed.
+ * doc/trouble.texi: Removed.
+ * doc/ux.texi: Removed.
+ * doc/tm.texi.in: Removed.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gccint/target-macros/tm.rst.in: New file.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Makefile.in: Support Sphinx based documentation.
+ * configure: Regenerate.
+ * configure.ac: Support Sphinx based documentation.
+ * genhooks.cc (struct s_hook): Emit tm.rst.in file.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gccint/target-macros/adding-support-for-named-address-spaces.rst: Use tm.rst.in file.
+ * doc/gccint/target-macros/addressing-modes.rst: Likewise.
+ * doc/gccint/target-macros/adjusting-the-instruction-scheduler.rst: Likewise.
+ * doc/gccint/target-macros/anchored-addresses.rst: Likewise.
+ * doc/gccint/target-macros/c++-abi-parameters.rst: Likewise.
+ * doc/gccint/target-macros/condition-code-status.rst: Likewise.
+ * doc/gccint/target-macros/controlling-debugging-information-format.rst: Likewise.
+ * doc/gccint/target-macros/controlling-the-compilation-driver-gcc.rst: Likewise.
+ * doc/gccint/target-macros/d-abi-parameters.rst: Likewise.
+ * doc/gccint/target-macros/defining-target-specific-uses-of-attribute.rst: Likewise.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/assembler-commands-for-exception-regions.rst:
+ Likewise.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/macros-controlling-initialization-routines.rst:
+ Likewise.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-and-generation-of-labels.rst:
+ Likewise.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-assembler-instructions.rst:
+ Likewise.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-data.rst:
+ Likewise.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-dispatch-tables.rst:
+ Likewise.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/the-overall-framework-of-an-assembler-file.rst:
+ Likewise.
+ * doc/gccint/target-macros/describing-relative-costs-of-operations.rst: Likewise.
+ * doc/gccint/target-macros/dividing-the-output-into-sections-texts-data.rst: Likewise.
+ * doc/gccint/target-macros/emulating-tls.rst: Likewise.
+ * doc/gccint/target-macros/implementing-the-varargs-macros.rst: Likewise.
+ * doc/gccint/target-macros/implicit-calls-to-library-routines.rst: Likewise.
+ * doc/gccint/target-macros/layout-of-source-language-data-types.rst: Likewise.
+ * doc/gccint/target-macros/miscellaneous-parameters.rst: Likewise.
+ * doc/gccint/target-macros/mode-switching-instructions.rst: Likewise.
+ * doc/gccint/target-macros/parameters-for-precompiled-header-validity-checking.rst:
+ Likewise.
+ * doc/gccint/target-macros/register-classes.rst: Likewise.
+ * doc/gccint/target-macros/register-usage.rst: Likewise.
+ * doc/gccint/target-macros/run-time-target-specification.rst: Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/basic-stack-layout.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/eliminating-frame-pointer-and-arg-pointer.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/function-entry-and-exit.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/generating-code-for-profiling.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/how-large-values-are-returned.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/how-scalar-function-values-are-returned.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/miscellaneous-register-hooks.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/passing-arguments-in-registers.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/passing-function-arguments-on-the-stack.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/permitting-tail-calls.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/registers-that-address-the-stack-frame.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/shrink-wrapping-separate-components.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/specifying-how-stack-checking-is-done.rst:
+ Likewise.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/stack-smashing-protection.rst:
+ Likewise.
+ * doc/gccint/target-macros/storage-layout.rst: Likewise.
+ * doc/gccint/target-macros/support-for-nested-functions.rst: Likewise.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * common/common-target.def: Port to RST.
+ * target.def: Port to RST.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/cpp/character-sets.rst: New file.
+ * doc/cpp/conditional-syntax.rst: New file.
+ * doc/cpp/conditional-uses.rst: New file.
+ * doc/cpp/conditionals.rst: New file.
+ * doc/cpp/conf.py: New file.
+ * doc/cpp/copyright.rst: New file.
+ * doc/cpp/deleted-code.rst: New file.
+ * doc/cpp/diagnostics.rst: New file.
+ * doc/cpp/environment-variables.rst: New file.
+ * doc/cpp/gnu-free-documentation-license.rst: New file.
+ * doc/cpp/header-files.rst: New file.
+ * doc/cpp/header-files/alternatives-to-wrapper-ifndef.rst: New file.
+ * doc/cpp/header-files/computed-includes.rst: New file.
+ * doc/cpp/header-files/include-operation.rst: New file.
+ * doc/cpp/header-files/include-syntax.rst: New file.
+ * doc/cpp/header-files/once-only-headers.rst: New file.
+ * doc/cpp/header-files/search-path.rst: New file.
+ * doc/cpp/header-files/system-headers.rst: New file.
+ * doc/cpp/header-files/wrapper-headers.rst: New file.
+ * doc/cpp/implementation-defined-behavior.rst: New file.
+ * doc/cpp/implementation-details.rst: New file.
+ * doc/cpp/implementation-limits.rst: New file.
+ * doc/cpp/index.rst: New file.
+ * doc/cpp/indices-and-tables.rst: New file.
+ * doc/cpp/initial-processing.rst: New file.
+ * doc/cpp/invocation.rst: New file.
+ * doc/cpp/line-control.rst: New file.
+ * doc/cpp/macros.rst: New file.
+ * doc/cpp/macros/concatenation.rst: New file.
+ * doc/cpp/macros/directives-within-macro-arguments.rst: New file.
+ * doc/cpp/macros/function-like-macros.rst: New file.
+ * doc/cpp/macros/macro-arguments.rst: New file.
+ * doc/cpp/macros/macro-pitfalls.rst: New file.
+ * doc/cpp/macros/object-like-macros.rst: New file.
+ * doc/cpp/macros/predefined-macros.rst: New file.
+ * doc/cpp/macros/stringizing.rst: New file.
+ * doc/cpp/macros/undefining-and-redefining-macros.rst: New file.
+ * doc/cpp/macros/variadic-macros.rst: New file.
+ * doc/cpp/obsolete-features.rst: New file.
+ * doc/cpp/other-directives.rst: New file.
+ * doc/cpp/overview.rst: New file.
+ * doc/cpp/pragmas.rst: New file.
+ * doc/cpp/preprocessor-output.rst: New file.
+ * doc/cpp/the-preprocessing-language.rst: New file.
+ * doc/cpp/tokenization.rst: New file.
+ * doc/cpp/traditional-lexical-analysis.rst: New file.
+ * doc/cpp/traditional-macros.rst: New file.
+ * doc/cpp/traditional-miscellany.rst: New file.
+ * doc/cpp/traditional-mode.rst: New file.
+ * doc/cpp/traditional-warnings.rst: New file.
+ * doc/cppinternals/conf.py: New file.
+ * doc/cppinternals/copyright.rst: New file.
+ * doc/cppinternals/cppinternals.rst: New file.
+ * doc/cppinternals/cpplib.rst: New file.
+ * doc/cppinternals/files.rst: New file.
+ * doc/cppinternals/index.rst: New file.
+ * doc/cppinternals/indices-and-tables.rst: New file.
+ * doc/cppinternals/internal-representation-of-macros.rst: New file.
+ * doc/cppinternals/just-which-line-number-anyway.rst: New file.
+ * doc/cppinternals/lexing-a-line.rst: New file.
+ * doc/cppinternals/lexing-a-token.rst: New file.
+ * doc/cppinternals/looking-for-a-function-like-macros-opening-parenthesis.rst: New file.
+ * doc/cppinternals/macro-expansion-overview.rst: New file.
+ * doc/cppinternals/marking-tokens-ineligible-for-future-expansion.rst: New file.
+ * doc/cppinternals/multiple-include-optimization.rst: New file.
+ * doc/cppinternals/overview.rst: New file.
+ * doc/cppinternals/representation-of-line-numbers.rst: New file.
+ * doc/cppinternals/scanning-the-replacement-list-for-macros-to-expand.rst: New file.
+ * doc/gcc/binary-compatibility.rst: New file.
+ * doc/gcc/c++-implementation-defined-behavior.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/architecture.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/arrays-and-pointers.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/characters.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/declarators.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/environment.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/floating-point.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/hints.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/identifiers.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/integers.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/library-functions.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/locale-specific-behavior.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/preprocessing-directives.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/qualifiers.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/statements.rst: New file.
+ * doc/gcc/c-implementation-defined-behavior/structures-unions-enumerations-and-bit-fields.rst:
+ New file.
+ * doc/gcc/c-implementation-defined-behavior/translation.rst: New file.
+ * doc/gcc/conditionally-supported-behavior.rst: New file.
+ * doc/gcc/conf.py: New file.
+ * doc/gcc/contributing-to-gcc-development.rst: New file.
+ * doc/gcc/contributors-to-gcc.rst: New file.
+ * doc/gcc/copyright.rst: New file.
+ * doc/gcc/exception-handling.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/backwards-compatibility.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/c++-concepts.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/c++-interface-and-implementation-pragmas.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c++-language/c++-specific-variable-function-and-type-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c++-language/deprecated-features.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/extracting-the-function-pointer-from-a-bound-pointer-to-member-function.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c++-language/function-multiversioning.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/restricting-pointer-aliasing.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/type-traits.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/vague-linkage.rst: New file.
+ * doc/gcc/extensions-to-the-c++-language/when-is-a-volatile-c++-object-accessed.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c++-language/wheres-the-template.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/128-bit-integers.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/additional-floating-types.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/alternate-keywords.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/an-inline-function-is-as-fast-as-a-macro.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/arithmetic-on-void-and-function-pointers.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/arrays-of-length-zero.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/arrays-of-variable-length.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/attribute-syntax.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/binary-constants-using-the-0b-prefix.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/built-in-functions-for-memory-model-aware-atomic-operations.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/built-in-functions-to-perform-arithmetic-with-overflow-checking.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/c++-style-comments.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/case-ranges.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/cast-to-a-union-type.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/complex-numbers.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/compound-literals.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/conditionals-with-omitted-operands.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/constructing-function-calls.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/decimal-floating-types.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/aarch64-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/amd-gcn-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/arc-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/arm-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/avr-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/blackfin-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/bpf-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/c-sky-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/common-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/epiphany-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/h8-300-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/ia-64-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/m32c-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/m32r-d-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/m68k-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/mcore-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/mep-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/microblaze-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/microsoft-windows-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/mips-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/msp430-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/nds32-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/nios-ii-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/nvidia-ptx-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/powerpc-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/risc-v-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/rl78-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/rx-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/s-390-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/sh-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/symbian-os-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/v850-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/visium-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/x86-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/declaring-attributes-of-functions/xstormy16-function-attributes.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/designated-initializers.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/determining-the-alignment-of-functions-types-or-variables.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/dollar-signs-in-identifier-names.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/double-word-integers.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/enumerator-attributes.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/fixed-point-types.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/format-checks-specific-to-particular-target-machines.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/function-names-as-strings.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/getting-the-return-or-frame-address-of-a-function.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/half-precision-floating-point.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/hex-floats.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/how-to-use-inline-assembly-language-in-c-code.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/incomplete-enum-types.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/label-attributes.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/labels-as-values.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/legacy-sync-built-in-functions-for-atomic-memory-access.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/locally-declared-labels.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/macros-with-a-variable-number-of-arguments.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/mixed-declarations-labels-and-code.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/named-address-spaces.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/nested-functions.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/non-constant-initializers.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/non-lvalue-arrays-may-have-subscripts.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/nonlocal-gotos.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/object-size-checking-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/other-built-in-functions-provided-by-gcc.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/pointer-arguments-in-variadic-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/pointers-to-arrays-with-qualifiers-work-as-expected.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/pragmas-accepted-by-gcc.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/prototypes-and-old-style-function-definitions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/referring-to-a-type-with-typeof.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/slightly-looser-rules-for-escaped-newlines.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/specifying-attributes-of-types.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/specifying-attributes-of-variables.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/statement-attributes.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/statements-and-declarations-in-expressions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/structures-with-no-members.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/support-for-offsetof.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/aarch64-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/alpha-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/altera-nios-ii-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arc-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arc-simd-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-armv8-m-security-extensions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-c-language-extensions-acle.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-floating-point-status-and-control-intrinsics.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/arm-iwmmxt-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/avr-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/basic-powerpc-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/blackfin-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/bpf-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/fr-v-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-dsp-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-loongson-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-paired-single-support.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/mips-simd-architecture-msa-support.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/msp430-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/nds32-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/other-mips-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/picochip-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-altivec-vsx-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-atomic-memory-operation-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-hardware-transactional-memory-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/powerpc-matrix-multiply-assist-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/pru-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/risc-v-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/rx-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/s-390-system-z-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/sh-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/sparc-vis-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/ti-c6x-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/x86-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/x86-control-flow-protection-intrinsics.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/target-builtins/x86-transactional-memory-intrinsics.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/the-character-esc-in-constants.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/thread-local-storage.rst: New file.
+ * doc/gcc/extensions-to-the-c-language-family/unnamed-structure-and-union-fields.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/using-vector-instructions-through-built-in-functions.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/when-is-a-volatile-object-accessed.rst:
+ New file.
+ * doc/gcc/extensions-to-the-c-language-family/x86-specific-memory-model-extensions-for-transactional-memory.rst:
+ New file.
+ * doc/gcc/funding.rst: New file.
+ * doc/gcc/gcc-command-options.rst: New file.
+ * doc/gcc/gcc-command-options/c++-modules.rst: New file.
+ * doc/gcc/gcc-command-options/compiling-c++-programs.rst: New file.
+ * doc/gcc/gcc-command-options/description.rst: New file.
+ * doc/gcc/gcc-command-options/environment-variables-affecting-gcc.rst: New file.
+ * doc/gcc/gcc-command-options/gcc-developer-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/aarch64-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/adapteva-epiphany-options.rst:
+ New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/amd-gcn-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/arc-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/arm-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/avr-mmcu.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/avr-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/blackfin-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/c-sky-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/c6x-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/cris-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/darwin-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/dec-alpha-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ebpf-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/fr30-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/frv-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ft32-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/gnu-linux-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/h8-300-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/hppa-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ia-64-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/ibm-rs-6000-and-powerpc-options.rst:
+ New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/lm32-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/loongarch-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/m32c-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/m32r-d-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/m680x0-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mcore-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mep-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/microblaze-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mips-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mmix-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/mn10300-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/moxie-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/msp430-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/nds32-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/nios-ii-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/nvidia-ptx-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/openrisc-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/options-for-system-v.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/pdp-11-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/picochip-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/powerpc-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/pru-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/risc-v-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/rl78-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/rx-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/s-390-and-zseries-options.rst:
+ New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/score-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/sh-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/solaris-2-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/sparc-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/v850-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/vax-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/visium-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/vms-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/vxworks-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/x86-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/x86-windows-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/xstormy16-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/xtensa-options.rst: New file.
+ * doc/gcc/gcc-command-options/machine-dependent-options/zseries-options.rst: New file.
+ * doc/gcc/gcc-command-options/option-summary.rst: New file.
+ * doc/gcc/gcc-command-options/options-controlling-c++-dialect.rst: New file.
+ * doc/gcc/gcc-command-options/options-controlling-c-dialect.rst: New file.
+ * doc/gcc/gcc-command-options/options-controlling-objective-c-and-objective-c++-dialects.rst:
+ New file.
+ * doc/gcc/gcc-command-options/options-controlling-the-kind-of-output.rst: New file.
+ * doc/gcc/gcc-command-options/options-controlling-the-preprocessor.rst: New file.
+ * doc/gcc/gcc-command-options/options-for-code-generation-conventions.rst: New file.
+ * doc/gcc/gcc-command-options/options-for-debugging-your-program.rst: New file.
+ * doc/gcc/gcc-command-options/options-for-directory-search.rst: New file.
+ * doc/gcc/gcc-command-options/options-for-linking.rst: New file.
+ * doc/gcc/gcc-command-options/options-that-control-optimization.rst: New file.
+ * doc/gcc/gcc-command-options/options-that-control-static-analysis.rst: New file.
+ * doc/gcc/gcc-command-options/options-to-control-diagnostic-messages-formatting.rst:
+ New file.
+ * doc/gcc/gcc-command-options/options-to-request-or-suppress-warnings.rst: New file.
+ * doc/gcc/gcc-command-options/passing-options-to-the-assembler.rst: New file.
+ * doc/gcc/gcc-command-options/program-instrumentation-options.rst: New file.
+ * doc/gcc/gcc-command-options/specifying-subprocesses-and-the-switches-to-pass-to-them.rst:
+ New file.
+ * doc/gcc/gcc-command-options/using-precompiled-headers.rst: New file.
+ * doc/gcc/gcc.rst: New file.
+ * doc/gcc/gcov-dump.rst: New file.
+ * doc/gcc/gcov-tool.rst: New file.
+ * doc/gcc/gcov.rst: New file.
+ * doc/gcc/gcov/brief-description-of-gcov-data-files.rst: New file.
+ * doc/gcc/gcov/data-file-relocation-to-support-cross-profiling.rst: New file.
+ * doc/gcc/gcov/introduction-to-gcov.rst: New file.
+ * doc/gcc/gcov/invoking-gcov.rst: New file.
+ * doc/gcc/gcov/profiling-and-test-coverage-in-freestanding-environments.rst: New file.
+ * doc/gcc/gcov/using-gcov-with-gcc-optimization.rst: New file.
+ * doc/gcc/general-public-license-3.rst: New file.
+ * doc/gcc/gnu-free-documentation-license.rst: New file.
+ * doc/gcc/gnu-objective-c-features.rst: New file.
+ * doc/gcc/gnu-objective-c-features/compatibilityalias.rst: New file.
+ * doc/gcc/gnu-objective-c-features/constant-string-objects.rst: New file.
+ * doc/gcc/gnu-objective-c-features/exceptions.rst: New file.
+ * doc/gcc/gnu-objective-c-features/fast-enumeration.rst: New file.
+ * doc/gcc/gnu-objective-c-features/garbage-collection.rst: New file.
+ * doc/gcc/gnu-objective-c-features/gnu-objective-c-runtime-api.rst: New file.
+ * doc/gcc/gnu-objective-c-features/load-executing-code-before-main.rst: New file.
+ * doc/gcc/gnu-objective-c-features/messaging-with-the-gnu-objective-c-runtime.rst: New file.
+ * doc/gcc/gnu-objective-c-features/synchronization.rst: New file.
+ * doc/gcc/gnu-objective-c-features/type-encoding.rst: New file.
+ * doc/gcc/gnu.rst: New file.
+ * doc/gcc/have-you-found-a-bug.rst: New file.
+ * doc/gcc/how-and-where-to-report-bugs.rst: New file.
+ * doc/gcc/how-to-get-help-with-gcc.rst: New file.
+ * doc/gcc/index.rst: New file.
+ * doc/gcc/indices-and-tables.rst: New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc.rst: New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/actual-bugs-we-havent-fixed-yet.rst: New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/certain-changes-we-dont-want-to-make.rst:
+ New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/common-misunderstandings-with-gnu-c.rst:
+ New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/disappointments-and-misunderstandings.rst:
+ New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/fixed-header-files.rst: New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/incompatibilities-of-gcc.rst: New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/interoperation.rst: New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/standard-libraries.rst: New file.
+ * doc/gcc/known-causes-of-trouble-with-gcc/warning-messages-and-error-messages.rst:
+ New file.
+ * doc/gcc/language-standards-supported-by-gcc.rst: New file.
+ * doc/gcc/language-standards-supported-by-gcc/c++-language.rst: New file.
+ * doc/gcc/language-standards-supported-by-gcc/c-language.rst: New file.
+ * doc/gcc/language-standards-supported-by-gcc/d-language.rst: New file.
+ * doc/gcc/language-standards-supported-by-gcc/go-language.rst: New file.
+ * doc/gcc/language-standards-supported-by-gcc/objective-c-and-objective-c++-languages.rst:
+ New file.
+ * doc/gcc/language-standards-supported-by-gcc/references-for-other-languages.rst: New file.
+ * doc/gcc/lto-dump.rst: New file.
+ * doc/gcc/programming-languages-supported-by-gcc.rst: New file.
+ * doc/gcc/reporting-bugs.rst: New file.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples.rst: New file.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/alias-analysis.rst: New file.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/annotations.rst: New file.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/memory-model.rst: New file.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/ssa-operands.rst: New file.
+ * doc/gccint/analysis-and-optimization-of-gimple-tuples/static-single-assignment.rst:
+ New file.
+ * doc/gccint/analysis-and-representation-of-loops.rst: New file.
+ * doc/gccint/analysis-and-representation-of-loops/data-dependency-analysis.rst: New file.
+ * doc/gccint/analysis-and-representation-of-loops/iv-analysis-on-rtl.rst: New file.
+ * doc/gccint/analysis-and-representation-of-loops/loop-closed-ssa-form.rst: New file.
+ * doc/gccint/analysis-and-representation-of-loops/loop-manipulation.rst: New file.
+ * doc/gccint/analysis-and-representation-of-loops/loop-querying.rst: New file.
+ * doc/gccint/analysis-and-representation-of-loops/loop-representation.rst: New file.
+ * doc/gccint/analysis-and-representation-of-loops/number-of-iterations-analysis.rst:
+ New file.
+ * doc/gccint/analysis-and-representation-of-loops/scalar-evolutions.rst: New file.
+ * doc/gccint/analyzer-internals.rst: New file.
+ * doc/gccint/collect2.rst: New file.
+ * doc/gccint/conf.py: New file.
+ * doc/gccint/contributing-to-gcc-development.rst: New file.
+ * doc/gccint/contributors-to-gcc.rst: New file.
+ * doc/gccint/control-flow-graph.rst: New file.
+ * doc/gccint/control-flow-graph/basic-blocks.rst: New file.
+ * doc/gccint/control-flow-graph/edges.rst: New file.
+ * doc/gccint/control-flow-graph/liveness-information.rst: New file.
+ * doc/gccint/control-flow-graph/maintaining-the-cfg.rst: New file.
+ * doc/gccint/control-flow-graph/profile-information.rst: New file.
+ * doc/gccint/copyright.rst: New file.
+ * doc/gccint/debugging-the-analyzer.rst: New file.
+ * doc/gccint/funding.rst: New file.
+ * doc/gccint/gcc-and-portability.rst: New file.
+ * doc/gccint/general-public-license-3.rst: New file.
+ * doc/gccint/generic.rst: New file.
+ * doc/gccint/generic/attributes-in-trees.rst: New file.
+ * doc/gccint/generic/c-and-c++-trees.rst: New file.
+ * doc/gccint/generic/declarations.rst: New file.
+ * doc/gccint/generic/deficiencies.rst: New file.
+ * doc/gccint/generic/expressions.rst: New file.
+ * doc/gccint/generic/functions.rst: New file.
+ * doc/gccint/generic/language-dependent-trees.rst: New file.
+ * doc/gccint/generic/overview.rst: New file.
+ * doc/gccint/generic/statements.rst: New file.
+ * doc/gccint/generic/types.rst: New file.
+ * doc/gccint/gimple-api.rst: New file.
+ * doc/gccint/gimple.rst: New file.
+ * doc/gccint/gimple/adding-a-new-gimple-statement-code.rst: New file.
+ * doc/gccint/gimple/class-hierarchy-of-gimple-statements.rst: New file.
+ * doc/gccint/gimple/exception-handling.rst: New file.
+ * doc/gccint/gimple/gimple-instruction-set.rst: New file.
+ * doc/gccint/gimple/gimple-sequences.rst: New file.
+ * doc/gccint/gimple/manipulating-gimple-statements.rst: New file.
+ * doc/gccint/gimple/operands.rst: New file.
+ * doc/gccint/gimple/sequence-iterators.rst: New file.
+ * doc/gccint/gimple/statement-and-operand-traversals.rst: New file.
+ * doc/gccint/gimple/temporaries.rst: New file.
+ * doc/gccint/gimple/tuple-representation.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleasm.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleassign.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplebind.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplecall.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplecatch.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplecond.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpledebug.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleehfilter.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplegoto.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplelabel.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplenop.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompatomicload.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompatomicstore.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompcontinue.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompcritical.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompfor.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompmaster.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompordered.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompparallel.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompreturn.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompsection.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompsections.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleompsingle.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplephi.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleresx.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplereturn.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpleswitch.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimpletry.rst: New file.
+ * doc/gccint/gimple/tuple-specific-accessors/gimplewithcleanupexpr.rst: New file.
+ * doc/gccint/gnu-free-documentation-license.rst: New file.
+ * doc/gccint/guidelines-for-diagnostics.rst: New file.
+ * doc/gccint/guidelines-for-options.rst: New file.
+ * doc/gccint/host-common.rst: New file.
+ * doc/gccint/host-configuration.rst: New file.
+ * doc/gccint/host-filesystem.rst: New file.
+ * doc/gccint/host-makefile-fragments.rst: New file.
+ * doc/gccint/host-misc.rst: New file.
+ * doc/gccint/index.rst: New file.
+ * doc/gccint/indices-and-tables.rst: New file.
+ * doc/gccint/interfacing-to-gcc-output.rst: New file.
+ * doc/gccint/introduction.rst: New file.
+ * doc/gccint/language-front-ends-in-gcc.rst: New file.
+ * doc/gccint/link-time-optimization.rst: New file.
+ * doc/gccint/link-time-optimization/design-overview.rst: New file.
+ * doc/gccint/link-time-optimization/internal-flags-controlling-lto1.rst: New file.
+ * doc/gccint/link-time-optimization/lto-file-sections.rst: New file.
+ * doc/gccint/link-time-optimization/using-summary-information-in-ipa-passes.rst: New file.
+ * doc/gccint/link-time-optimization/whole-program-assumptions-linker-plugin-and-symbol-visibilities.rst:
+ New file.
+ * doc/gccint/machine-descriptions.rst: New file.
+ * doc/gccint/machine-descriptions/c-statements-for-assembler-output.rst: New file.
+ * doc/gccint/machine-descriptions/canonicalization-of-instructions.rst: New file.
+ * doc/gccint/machine-descriptions/conditional-execution.rst: New file.
+ * doc/gccint/machine-descriptions/constant-definitions.rst: New file.
+ * doc/gccint/machine-descriptions/defining-how-to-split-instructions.rst: New file.
+ * doc/gccint/machine-descriptions/defining-jump-instruction-patterns.rst: New file.
+ * doc/gccint/machine-descriptions/defining-looping-instruction-patterns.rst: New file.
+ * doc/gccint/machine-descriptions/defining-rtl-sequences-for-code-generation.rst: New file.
+ * doc/gccint/machine-descriptions/everything-about-instruction-patterns.rst: New file.
+ * doc/gccint/machine-descriptions/example-of-defineinsn.rst: New file.
+ * doc/gccint/machine-descriptions/including-patterns-in-machine-descriptions.rst: New file.
+ * doc/gccint/machine-descriptions/instruction-attributes.rst: New file.
+ * doc/gccint/machine-descriptions/interdependence-of-patterns.rst: New file.
+ * doc/gccint/machine-descriptions/iterators.rst: New file.
+ * doc/gccint/machine-descriptions/machine-specific-peephole-optimizers.rst: New file.
+ * doc/gccint/machine-descriptions/operand-constraints.rst: New file.
+ * doc/gccint/machine-descriptions/output-templates-and-operand-substitution.rst: New file.
+ * doc/gccint/machine-descriptions/overview-of-how-the-machine-description-is-used.rst:
+ New file.
+ * doc/gccint/machine-descriptions/predicates.rst: New file.
+ * doc/gccint/machine-descriptions/rtl-template.rst: New file.
+ * doc/gccint/machine-descriptions/rtl-templates-transformations.rst: New file.
+ * doc/gccint/machine-descriptions/standard-pattern-names-for-generation.rst: New file.
+ * doc/gccint/machine-descriptions/when-the-order-of-patterns-matters.rst: New file.
+ * doc/gccint/makefile-fragments.rst: New file.
+ * doc/gccint/match-and-simplify.rst: New file.
+ * doc/gccint/memory-management-and-type-information.rst: New file.
+ * doc/gccint/memory-management-and-type-information/how-to-invoke-the-garbage-collector.rst:
+ New file.
+ * doc/gccint/memory-management-and-type-information/marking-roots-for-the-garbage-collector.rst:
+ New file.
+ * doc/gccint/memory-management-and-type-information/source-files-containing-type-information.rst:
+ New file.
+ * doc/gccint/memory-management-and-type-information/support-for-inheritance.rst: New file.
+ * doc/gccint/memory-management-and-type-information/support-for-user-provided-gc-marking-routines.rst:
+ New file.
+ * doc/gccint/memory-management-and-type-information/the-inside-of-a-gty.rst: New file.
+ * doc/gccint/memory-management-and-type-information/troubleshooting-the-garbage-collector.rst:
+ New file.
+ * doc/gccint/option-file-format.rst: New file.
+ * doc/gccint/option-properties.rst: New file.
+ * doc/gccint/option-specification-files.rst: New file.
+ * doc/gccint/passes-and-files-of-the-compiler.rst: New file.
+ * doc/gccint/passes-and-files-of-the-compiler/gimplification-pass.rst: New file.
+ * doc/gccint/passes-and-files-of-the-compiler/inter-procedural-optimization-passes.rst:
+ New file.
+ * doc/gccint/passes-and-files-of-the-compiler/optimization-info.rst: New file.
+ * doc/gccint/passes-and-files-of-the-compiler/parsing-pass.rst: New file.
+ * doc/gccint/passes-and-files-of-the-compiler/pass-manager.rst: New file.
+ * doc/gccint/passes-and-files-of-the-compiler/rtl-passes.rst: New file.
+ * doc/gccint/passes-and-files-of-the-compiler/tree-ssa-passes.rst: New file.
+ * doc/gccint/plugins.rst: New file.
+ * doc/gccint/plugins/building-gcc-plugins.rst: New file.
+ * doc/gccint/plugins/controlling-which-passes-are-being-run.rst: New file.
+ * doc/gccint/plugins/giving-information-about-a-plugin.rst: New file.
+ * doc/gccint/plugins/interacting-with-the-gcc-garbage-collector.rst: New file.
+ * doc/gccint/plugins/interacting-with-the-pass-manager.rst: New file.
+ * doc/gccint/plugins/keeping-track-of-available-passes.rst: New file.
+ * doc/gccint/plugins/loading-plugins.rst: New file.
+ * doc/gccint/plugins/plugin-api.rst: New file.
+ * doc/gccint/plugins/recording-information-about-pass-execution.rst: New file.
+ * doc/gccint/plugins/registering-custom-attributes-or-pragmas.rst: New file.
+ * doc/gccint/rtl-representation.rst: New file.
+ * doc/gccint/rtl-representation/access-to-operands.rst: New file.
+ * doc/gccint/rtl-representation/access-to-special-operands.rst: New file.
+ * doc/gccint/rtl-representation/assembler-instructions-as-expressions.rst: New file.
+ * doc/gccint/rtl-representation/bit-fields.rst: New file.
+ * doc/gccint/rtl-representation/comparison-operations.rst: New file.
+ * doc/gccint/rtl-representation/constant-expression-types.rst: New file.
+ * doc/gccint/rtl-representation/conversions.rst: New file.
+ * doc/gccint/rtl-representation/declarations.rst: New file.
+ * doc/gccint/rtl-representation/embedded-side-effects-on-addresses.rst: New file.
+ * doc/gccint/rtl-representation/flags-in-an-rtl-expression.rst: New file.
+ * doc/gccint/rtl-representation/insns.rst: New file.
+ * doc/gccint/rtl-representation/machine-modes.rst: New file.
+ * doc/gccint/rtl-representation/on-the-side-ssa-form-for-rtl.rst: New file.
+ * doc/gccint/rtl-representation/reading-rtl.rst: New file.
+ * doc/gccint/rtl-representation/registers-and-memory.rst: New file.
+ * doc/gccint/rtl-representation/rtl-classes-and-formats.rst: New file.
+ * doc/gccint/rtl-representation/rtl-expressions-for-arithmetic.rst: New file.
+ * doc/gccint/rtl-representation/rtl-object-types.rst: New file.
+ * doc/gccint/rtl-representation/rtl-representation-of-function-call-insns.rst: New file.
+ * doc/gccint/rtl-representation/side-effect-expressions.rst: New file.
+ * doc/gccint/rtl-representation/structure-sharing-assumptions.rst: New file.
+ * doc/gccint/rtl-representation/variable-location-debug-information-in-rtl.rst: New file.
+ * doc/gccint/rtl-representation/vector-operations.rst: New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants.rst: New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/alignment-of-polyints.rst: New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/arithmetic-on-polyints.rst: New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/comparisons-involving-polyint.rst:
+ New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/computing-bounds-on-polyints.rst:
+ New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/consequences-of-using-polyint.rst:
+ New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/converting-polyints.rst: New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/guidelines-for-using-polyint.rst:
+ New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/miscellaneous-polyint-routines.rst:
+ New file.
+ * doc/gccint/sizes-and-offsets-as-runtime-invariants/overview-of-polyint.rst: New file.
+ * doc/gccint/source-tree-structure-and-build-system.rst: New file.
+ * doc/gccint/source-tree-structure-and-build-system/configure-terms-and-history.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory.rst: New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/anatomy-of-a-language-front-end.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/anatomy-of-a-target-back-end.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/build-system-in-the-gcc-directory.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/building-documentation.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/configuration-in-the-gcc-directory.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/headers-installed-by-gcc.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/library-source-files-and-headers-under-the-gcc-directory.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/makefile-targets.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/the-gcc-subdirectory/subdirectories-of-gcc.rst:
+ New file.
+ * doc/gccint/source-tree-structure-and-build-system/top-level-source-directory.rst:
+ New file.
+ * doc/gccint/standard-header-file-directories.rst: New file.
+ * doc/gccint/static-analyzer.rst: New file.
+ * doc/gccint/target-macros.rst: New file.
+ * doc/gccint/target-macros/adding-support-for-named-address-spaces.rst: New file.
+ * doc/gccint/target-macros/addressing-modes.rst: New file.
+ * doc/gccint/target-macros/adjusting-the-instruction-scheduler.rst: New file.
+ * doc/gccint/target-macros/anchored-addresses.rst: New file.
+ * doc/gccint/target-macros/c++-abi-parameters.rst: New file.
+ * doc/gccint/target-macros/condition-code-status.rst: New file.
+ * doc/gccint/target-macros/controlling-debugging-information-format.rst: New file.
+ * doc/gccint/target-macros/controlling-the-compilation-driver-gcc.rst: New file.
+ * doc/gccint/target-macros/cross-compilation-and-floating-point.rst: New file.
+ * doc/gccint/target-macros/d-abi-parameters.rst: New file.
+ * doc/gccint/target-macros/defining-coprocessor-specifics-for-mips-targets.rst: New file.
+ * doc/gccint/target-macros/defining-data-structures-for-per-function-information.rst:
+ New file.
+ * doc/gccint/target-macros/defining-target-specific-uses-of-attribute.rst: New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language.rst: New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/assembler-commands-for-alignment.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/assembler-commands-for-exception-regions.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/how-initialization-functions-are-handled.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/macros-controlling-initialization-routines.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-and-generation-of-labels.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-assembler-instructions.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-data.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-dispatch-tables.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/output-of-uninitialized-variables.rst:
+ New file.
+ * doc/gccint/target-macros/defining-the-output-assembler-language/the-overall-framework-of-an-assembler-file.rst:
+ New file.
+ * doc/gccint/target-macros/describing-relative-costs-of-operations.rst: New file.
+ * doc/gccint/target-macros/dividing-the-output-into-sections-texts-data.rst: New file.
+ * doc/gccint/target-macros/emulating-tls.rst: New file.
+ * doc/gccint/target-macros/implementing-the-varargs-macros.rst: New file.
+ * doc/gccint/target-macros/implicit-calls-to-library-routines.rst: New file.
+ * doc/gccint/target-macros/layout-of-source-language-data-types.rst: New file.
+ * doc/gccint/target-macros/miscellaneous-parameters.rst: New file.
+ * doc/gccint/target-macros/mode-switching-instructions.rst: New file.
+ * doc/gccint/target-macros/parameters-for-precompiled-header-validity-checking.rst:
+ New file.
+ * doc/gccint/target-macros/position-independent-code.rst: New file.
+ * doc/gccint/target-macros/register-classes.rst: New file.
+ * doc/gccint/target-macros/register-usage.rst: New file.
+ * doc/gccint/target-macros/run-time-target-specification.rst: New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions.rst: New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/basic-stack-layout.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/caller-saves-register-allocation.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/eliminating-frame-pointer-and-arg-pointer.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/exception-handling-support.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/function-entry-and-exit.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/generating-code-for-profiling.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/how-large-values-are-returned.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/how-scalar-function-values-are-returned.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/miscellaneous-register-hooks.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/passing-arguments-in-registers.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/passing-function-arguments-on-the-stack.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/permitting-tail-calls.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/registers-that-address-the-stack-frame.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/shrink-wrapping-separate-components.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/specifying-how-stack-checking-is-done.rst:
+ New file.
+ * doc/gccint/target-macros/stack-layout-and-calling-conventions/stack-smashing-protection.rst:
+ New file.
+ * doc/gccint/target-macros/storage-layout.rst: New file.
+ * doc/gccint/target-macros/support-for-nested-functions.rst: New file.
+ * doc/gccint/target-macros/the-global-targetm-variable.rst: New file.
+ * doc/gccint/target-makefile-fragments.rst: New file.
+ * doc/gccint/testsuites.rst: New test.
+ * doc/gccint/testsuites/ada-language-testsuites.rst: New test.
+ * doc/gccint/testsuites/c-language-testsuites.rst: New test.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests.rst: New test.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/commands-for-use-in-dg-final.rst:
+ New test.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/features-for-dg-add-options.rst:
+ New test.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/keywords-describing-target-attributes.rst:
+ New test.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/selecting-targets-to-which-a-test-applies.rst:
+ New test.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/syntax-and-descriptions-of-test-directives.rst:
+ New test.
+ * doc/gccint/testsuites/directives-used-within-dejagnu-tests/variants-of-dg-require-support.rst:
+ New test.
+ * doc/gccint/testsuites/idioms-used-in-testsuite-code.rst: New test.
+ * doc/gccint/testsuites/support-for-testing-binary-compatibility.rst: New test.
+ * doc/gccint/testsuites/support-for-testing-gcov.rst: New test.
+ * doc/gccint/testsuites/support-for-testing-gimple-passes.rst: New test.
+ * doc/gccint/testsuites/support-for-testing-link-time-optimizations.rst: New test.
+ * doc/gccint/testsuites/support-for-testing-profile-directed-optimizations.rst: New test.
+ * doc/gccint/testsuites/support-for-testing-rtl-passes.rst: New test.
+ * doc/gccint/testsuites/support-for-torture-testing-using-multiple-options.rst: New test.
+ * doc/gccint/the-gcc-low-level-runtime-library.rst: New file.
+ * doc/gccint/the-gcc-low-level-runtime-library/language-independent-routines-for-exception-handling.rst:
+ New file.
+ * doc/gccint/the-gcc-low-level-runtime-library/miscellaneous-runtime-library-routines.rst:
+ New file.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-decimal-floating-point-emulation.rst:
+ New file.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-fixed-point-fractional-emulation.rst:
+ New file.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-floating-point-emulation.rst:
+ New file.
+ * doc/gccint/the-gcc-low-level-runtime-library/routines-for-integer-arithmetic.rst:
+ New file.
+ * doc/gccint/the-language.rst: New file.
+ * doc/gccint/user-experience-guidelines.rst: New file.
+ * doc/install/binaries.rst: New file.
+ * doc/install/building.rst: New file.
+ * doc/install/building/building-a-cross-compiler.rst: New file.
+ * doc/install/building/building-a-native-compiler.rst: New file.
+ * doc/install/building/building-in-parallel.rst: New file.
+ * doc/install/building/building-the-ada-compiler.rst: New file.
+ * doc/install/building/building-the-d-compiler.rst: New file.
+ * doc/install/building/building-with-profile-feedback.rst: New file.
+ * doc/install/conf.py: New file.
+ * doc/install/configuration.rst: New file.
+ * doc/install/copyright.rst: New file.
+ * doc/install/downloading-gcc.rst: New file.
+ * doc/install/final-installation.rst: New file.
+ * doc/install/gnu-free-documentation-license.rst: New file.
+ * doc/install/host-target-specific-installation-notes-for-gcc.rst: New file.
+ * doc/install/how-can-you-run-the-testsuite-on-selected-tests.rst: New test.
+ * doc/install/how-to-interpret-test-results.rst: New file.
+ * doc/install/index.rst: New file.
+ * doc/install/indices-and-tables.rst: New file.
+ * doc/install/installing-gcc.rst: New file.
+ * doc/install/passing-options-and-running-multiple-testsuites.rst: New test.
+ * doc/install/prerequisites.rst: New file.
+ * doc/install/submitting-test-results.rst: New file.
+ * doc/install/testing.rst: New file.
+
+2022-11-09 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op-float.cc (class foperator_minus): New.
+ (floating_op_table::floating_op_table): Add MINUS_EXPR entry.
+
+2022-11-09 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op-float.cc (range_operator_float::fold_range): Abstract
+ out from foperator_plus.
+ (range_operator_float::rv_fold): New.
+ (foperator_plus::fold_range): Remove.
+ (foperator_plus::rv_fold): New.
+ (propagate_nans): Remove.
+ * range-op.h (class range_operator_float): Add rv_fold.
+
+2022-11-09 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op-float.cc (foperator_plus::fold_range): Set NAN for
+ addition of different signed infinities.
+ (range_op_float_tests): New test.
+
+2022-11-09 liuhongt <hongtao.liu@intel.com>
+
+ PR target/107540
+ * config/i386/sse.md (avx512f_movddup512<mask_name>): Change
+ type from sselog to sselog1.
+ (avx_movddup256<mask_name>): Ditto.
+
+2022-11-08 David Faust <david.faust@oracle.com>
+
+ * config/bpf/bpf.cc (struct core_walk_data): Add field `which'...
+ (bpf_resolve_overloaded_builtin): ... set it here. Use values of enum
+ bpf_builtins for error checks.
+ (bpf_core_walk): Use values of enum bpf_builtins.
+ (bpf_core_newdecl): Likewise.
+ (bpf_expand_builtin): Likewise.
+
+2022-11-08 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/24021
+ * range-op-float.cc (propagate_nans): New.
+ (frange_nextafter): New.
+ (frange_arithmetic): New.
+ (class foperator_plus): New.
+ (floating_op_table::floating_op_table): Add PLUS_EXPR entry.
+
+2022-11-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * real.cc (real_isdenormal): New.
+ (encode_ieee_single): Call real_isdenormal.
+ (encode_ieee_double): Same.
+ (encode_ieee_extended): Same.
+ (encode_ieee_quad): Same.
+ (encode_ieee_half): Same.
+ (encode_arm_bfloat_half): Same.
+ * real.h (real_isdenormal): Add mode argument. Rewrite for
+ normalized values.
+ * value-range.cc (frange::flush_denormals_to_zero): Pass mode to
+ real_isdenormal.
+
+2022-11-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107389
+ * gimple-low.cc (lower_builtin_assume_aligned): New.
+ (lower_stmt): Call it.
+
+2022-11-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op.cc (operator_div::fold_range): Call
+ update_known_bitmask.
+ * tree-ssa-ccp.cc (bit_value_binop): Handle divisions by powers of
+ 2 as a right shift.
+
+2022-11-08 Kwok Cheung Yeung <kcy@codesourcery.com>
+
+ * config/gcn/gcn.cc (gcn_expand_builtin_1): Expand first argument
+ of GCN_BUILTIN_LDEXPV to V64DFmode.
+
+2022-11-08 Kwok Cheung Yeung <kcy@codesourcery.com>
+
+ * config/gcn/gcn-builtins.def (FABSV, FLOORVF, FLOORV): New builtins.
+ * config/gcn/gcn.cc (gcn_expand_builtin_1): Expand GCN_BUILTIN_FABSV,
+ GCN_BUILTIN_FLOORVF and GCN_BUILTIN_FLOORV.
+
+2022-11-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op.cc (irange_to_masked_value): New.
+ (update_known_bitmask): New.
+ (operator_mult::fold_range): Call update_known_bitmask.
+
+2022-11-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107547
+ * tree-call-cdce.cc (get_no_error_domain): Handle CASE_FLT_FN_FLOATN_NX
+ of BUILT_IN_{ACOS,ASIN,ACOSH,ATANH,LOG,LOG2,LOG10,LOG1P}. Handle
+ BUILT_IN_{COSH,SINH,EXP,EXPM1,EXP2}F{16,32,64,128}.
+
+2022-11-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/107546
+ * config/i386/predicates.md (vector_or_const_vector_operand): New
+ predicate.
+ * config/i386/sse.md (vec_cmp<mode><sseintvecmodelower>,
+ vec_cmpv2div2di, vec_cmpu<mode><sseintvecmodelower>,
+ vec_cmpuv2div2di): Use nonimmediate_or_const_vector_operand
+ predicate instead of nonimmediate_operand and
+ vector_or_const_vector_operand instead of vector_operand.
+ * config/i386/i386-expand.cc (ix86_expand_int_sse_cmp): For
+ LE/LEU or GE/GEU with CONST_VECTOR cop1 try to transform those
+ into LE/LEU or GT/GTU with larger or smaller by one cop1 if
+ there is no wrap-around. Force CONST_VECTOR cop0 or cop1 into
+ REG. Formatting fix.
+
+2022-11-08 Max Filippov <jcmvbkbc@gmail.com>
+
+ PR rtl-optimization/107482
+ * ira-color.cc (assign_hard_reg): Only call
+ update_costs_from_copies when retry_p is false.
+
+2022-11-08 konglin1 <lingling.kong@intel.com>
+
+ Revert:
+ 2022-11-07 konglin1 <lingling.kong@intel.com>
+
+ * config/i386/i386.opt:Add -mprefer-remote-atomic.
+ * config/i386/sync.md (atomic_<plus_logic><mode>):
+ New define_expand.
+ (atomic_add<mode>): Rename to below one.
+ (atomic_add<mode>_1): To this.
+ (atomic_<logic><mode>): Ditto.
+ (atomic_<logic><mode>_1): Ditto.
+ * doc/invoke.texi: Add -mprefer-remote-atomic.
+
+2022-11-08 Haochen Jiang <haochen.jiang@intel.com>
+
+ * config/i386/i386-options.cc (m_CORE_ATOM): New.
+ * config/i386/x86-tune.def
+ (X86_TUNE_SCHEDULE): Initial tune for CORE_ATOM.
+ (X86_TUNE_PARTIAL_REG_DEPENDENCY): Ditto.
+ (X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY): Ditto.
+ (X86_TUNE_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY): Ditto.
+ (X86_TUNE_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY): Ditto.
+ (X86_TUNE_DEST_FALSE_DEP_FOR_GLC): Ditto.
+ (X86_TUNE_MEMORY_MISMATCH_STALL): Ditto.
+ (X86_TUNE_USE_LEAVE): Ditto.
+ (X86_TUNE_PUSH_MEMORY): Ditto.
+ (X86_TUNE_USE_INCDEC): Ditto.
+ (X86_TUNE_INTEGER_DFMODE_MOVES): Ditto.
+ (X86_TUNE_PREFER_KNOWN_REP_MOVSB_STOSB): Ditto.
+ (X86_TUNE_MISALIGNED_MOVE_STRING_PRO_EPILOGUES): Ditto.
+ (X86_TUNE_USE_SAHF): Ditto.
+ (X86_TUNE_USE_BT): Ditto.
+ (X86_TUNE_AVOID_FALSE_DEP_FOR_BMI): Ditto.
+ (X86_TUNE_ONE_IF_CONV_INSN): Ditto.
+ (X86_TUNE_AVOID_MFENCE): Ditto.
+ (X86_TUNE_USE_SIMODE_FIOP): Ditto.
+ (X86_TUNE_EXT_80387_CONSTANTS): Ditto.
+ (X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL): Ditto.
+ (X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL): Ditto.
+ (X86_TUNE_SSE_TYPELESS_STORES): Ditto.
+ (X86_TUNE_SSE_LOAD0_BY_PXOR): Ditto.
+ (X86_TUNE_AVOID_4BYTE_PREFIXES): Ditto.
+ (X86_TUNE_USE_GATHER_2PARTS): Ditto.
+ (X86_TUNE_USE_GATHER_4PARTS): Ditto.
+ (X86_TUNE_USE_GATHER): Ditto.
+
+2022-11-08 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/104530
+ * gimple-range-cache.cc (ranger_cache::register_inferred_value):
+ New. Split from:
+ (ranger_cache::apply_inferred_ranges): Move setting cache to
+ separate function.
+ * gimple-range-cache.h (register_inferred_value): New prototype.
+ * gimple-range-infer.cc (infer_range_manager::has_range_p): New.
+ * gimple-range-infer.h (has_range_p): New prototype.
+ * gimple-range.cc (register_transitive_inferred_ranges): New.
+ * gimple-range.h (register_transitive_inferred_ranges): New proto.
+ * tree-vrp.cc (rvrp_folder::fold_stmt): Check for transitive inferred
+ ranges at the end of the block before folding final stmt.
+
+2022-11-07 David Faust <david.faust@oracle.com>
+
+ * config/bpf/bpf.cc (handle_attr_preserve): Use maybe_make_core_relo().
+
+2022-11-07 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/55157
+ * range-op.cc (operator_mult::wi_fold): Optimize multiplications
+ by powers of 2.
+
+2022-11-07 H.J. Lu <hjl.tools@gmail.com>
+
+ PR middle-end/102566
+ * tree-ssa-ccp.cc (optimize_atomic_bit_test_and): Also handle
+ if (_5 < 0) and if (_5 >= 0).
+
+2022-11-07 Richard Purdie <richard.purdie@linuxfoundation.org>
+
+ * file-prefix-map.cc (remap_filename): Handle NULL filenames.
+
+2022-11-07 Alexander Monakov <amonakov@ispras.ru>
+
+ PR tree-optimization/107505
+ * tree-ssa-sink.cc (statement_sink_location): Additionally
+ reject ECF_RETURNS_TWICE calls.
+
+2022-11-07 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/107541
+ * range-op.cc (operator_div::fold_range): Restrict power of 2
+ optimization to positive numbers.
+
+2022-11-07 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-loop-unswitch.cc (unswitch_predicate::count): New.
+ (unswitch_predicate::unswitch_predicate): Initialize count.
+ (init_loop_unswitch_info): First collect candidates and
+ determine the outermost loop to unswitch.
+ (tree_ssa_unswitch_loops): First perform all guard hoisting,
+ then perform unswitching on innermost loop predicates.
+ (find_unswitching_predicates_for_bb): Keep track of the
+ most profitable predicate to unswitch on.
+ (tree_unswitch_single_loop): Unswitch given predicate if
+ not NULL.
+
+2022-11-07 Martin Liska <mliska@suse.cz>
+ Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/invoke.texi: Improve wording.
+
+2022-11-07 Martin Liska <mliska@suse.cz>
+
+ * range-op.cc: Add final override keywords.
+
+2022-11-07 Kewen Lin <linkw@linux.ibm.com>
+
+ PR tree-optimization/107412
+ * gimple-fold.cc (gimple_fold_mask_load_store_mem_ref): Rename to ...
+ (gimple_fold_partial_load_store_mem_ref): ... this, add one parameter
+ mask_p indicating it's for mask or length, and add some handlings for
+ IFN LEN_{LOAD,STORE}.
+ (gimple_fold_mask_load): Rename to ...
+ (gimple_fold_partial_load): ... this, add one parameter mask_p.
+ (gimple_fold_mask_store): Rename to ...
+ (gimple_fold_partial_store): ... this, add one parameter mask_p.
+ (gimple_fold_call): Add the handlings for IFN LEN_{LOAD,STORE},
+ and adjust calls on gimple_fold_mask_load_store_mem_ref to
+ gimple_fold_partial_load_store_mem_ref.
+
+2022-11-07 Hu, Lin1 <lin1.hu@intel.com>
+
+ * common/config/i386/cpuinfo.h
+ (get_intel_cpu): Handle Grand Ridge.
+ * common/config/i386/i386-common.cc
+ (processor_names): Add grandridge.
+ (processor_alias_table): Ditto.
+ * common/config/i386/i386-cpuinfo.h:
+ (enum processor_types): Add INTEL_GRANDRIDGE.
+ * config.gcc: Add -march=grandridge.
+ * config/i386/driver-i386.cc (host_detect_local_cpu):
+ Handle grandridge.
+ * config/i386/i386-c.cc (ix86_target_macros_internal):
+ Ditto.
+ * config/i386/i386-options.cc (m_GRANDRIDGE): New define.
+ (processor_cost_table): Add grandridge.
+ * config/i386/i386.h (enum processor_type):
+ Add PROCESSOR_GRANDRIDGE.
+ (PTA_GRANDRIDGE): Ditto.
+ * doc/extend.texi: Add grandridge.
+ * doc/invoke.texi: Ditto.
+
+2022-11-07 konglin1 <lingling.kong@intel.com>
+
+ * config/i386/i386.opt:Add -mprefer-remote-atomic.
+ * config/i386/sync.md (atomic_<plus_logic><mode>):
+ New define_expand.
+ (atomic_add<mode>): Rename to below one.
+ (atomic_add<mode>_1): To this.
+ (atomic_<logic><mode>): Ditto.
+ (atomic_<logic><mode>_1): Ditto.
+ * doc/invoke.texi: Add -mprefer-remote-atomic.
+
+2022-11-07 konglin1 <lingling.kong@intel.com>
+
+ * common/config/i386/cpuinfo.h (get_available_features):
+ Detect raoint.
+ * common/config/i386/i386-common.cc (OPTION_MASK_ISA2_RAOINT_SET,
+ OPTION_MASK_ISA2_RAOINT_UNSET): New.
+ (ix86_handle_option): Handle -mraoint.
+ * common/config/i386/i386-cpuinfo.h (enum processor_features):
+ Add FEATURE_RAOINT.
+ * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for
+ raoint.
+ * config.gcc: Add raointintrin.h
+ * config/i386/cpuid.h (bit_RAOINT): New.
+ * config/i386/i386-builtin.def (BDESC): Add new builtins.
+ * config/i386/i386-c.cc (ix86_target_macros_internal): Define
+ __RAOINT__.
+ * config/i386/i386-isa.def (RAOINT): Add DEF_PTA(RAOINT).
+ * config/i386/i386-options.cc (ix86_valid_target_attribute_inner_p):
+ Add -mraoint.
+ * config/i386/sync.md (rao_a<raointop><mode>): New define insn.
+ * config/i386/i386.opt: Add option -mraoint.
+ * config/i386/x86gprintrin.h: Include raointintrin.h.
+ * doc/extend.texi: Document raoint.
+ * doc/invoke.texi: Document -mraoint.
+ * doc/sourcebuild.texi: Document target raoint.
+ * config/i386/raointintrin.h: New file.
+
+2022-11-07 Haochen Jiang <haochen.jiang@intel.com>
+
+ * common/config/i386/cpuinfo.h
+ (get_intel_cpu): Handle Granite Rapids.
+ * common/config/i386/i386-common.cc:
+ (processor_names): Add graniterapids.
+ (processor_alias_table): Ditto.
+ * common/config/i386/i386-cpuinfo.h
+ (enum processor_subtypes): Add INTEL_GRANTIERAPIDS.
+ * config.gcc: Add -march=graniterapids.
+ * config/i386/driver-i386.cc (host_detect_local_cpu):
+ Handle graniterapids.
+ * config/i386/i386-c.cc (ix86_target_macros_internal):
+ Ditto.
+ * config/i386/i386-options.cc (m_GRANITERAPIDS): New.
+ (processor_cost_table): Add graniterapids.
+ * config/i386/i386.h (enum processor_type):
+ Add PROCESSOR_GRANITERAPIDS.
+ (PTA_GRANITERAPIDS): Ditto.
+ * doc/extend.texi: Add graniterapids.
+ * doc/invoke.texi: Ditto.
+
+2022-11-07 Haochen Jiang <haochen.jiang@intel.com>
+ Hongtao Liu <hongtao.liu@intel.com>
+
+ * common/config/i386/cpuinfo.h (get_available_features):
+ Detect PREFETCHI.
+ * common/config/i386/i386-common.cc
+ (OPTION_MASK_ISA2_PREFETCHI_SET,
+ OPTION_MASK_ISA2_PREFETCHI_UNSET): New.
+ (ix86_handle_option): Handle -mprefetchi.
+ * common/config/i386/i386-cpuinfo.h
+ (enum processor_features): Add FEATURE_PREFETCHI.
+ * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY
+ for prefetchi.
+ * config.gcc: Add prfchiintrin.h.
+ * config/i386/cpuid.h (bit_PREFETCHI): New.
+ * config/i386/i386-builtin-types.def:
+ Add DEF_FUNCTION_TYPE (VOID, PCVOID, INT)
+ and DEF_FUNCTION_TYPE (VOID, PCVOID, INT, INT, INT).
+ * config/i386/i386-builtin.def (BDESC): Add new builtins.
+ * config/i386/i386-c.cc (ix86_target_macros_internal):
+ Define __PREFETCHI__.
+ * config/i386/i386-expand.cc: Handle new builtins.
+ * config/i386/i386-isa.def (PREFETCHI):
+ Add DEF_PTA(PREFETCHI).
+ * config/i386/i386-options.cc
+ (ix86_valid_target_attribute_inner_p): Handle prefetchi.
+ * config/i386/i386.md (prefetchi): New define_insn.
+ * config/i386/i386.opt: Add option -mprefetchi.
+ * config/i386/predicates.md (local_func_symbolic_operand):
+ New predicates.
+ * config/i386/x86gprintrin.h: Include prfchiintrin.h.
+ * config/i386/xmmintrin.h (enum _mm_hint): New enum for
+ prefetchi.
+ (_mm_prefetch): Handle the highest bit of enum.
+ * doc/extend.texi: Document prefetchi.
+ * doc/invoke.texi: Document -mprefetchi.
+ * doc/sourcebuild.texi: Document target prefetchi.
+ * config/i386/prfchiintrin.h: New file.
+
+2022-11-06 Uroš Bizjak <ubizjak@gmail.com>
+
+ * optabs.cc (can_vec_set_var_idx_p): Use operand[2]
+ mode when checking vec_set_optab.
+
+2022-11-06 Xi Ruoyao <xry111@xry111.site>
+
+ * config/loongarch/loongarch.md (UNSPEC_FCOPYSIGN): New unspec.
+ (type): Add fcopysign.
+ (copysign<mode>3): New instruction template.
+
+2022-11-06 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
+
+ * multiple_target.cc (expand_target_clones): Free memory.
+
+2022-11-06 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
+
+ * cgraph.cc (cgraph_node::make_local): Remove redundant set_section.
+ * multiple_target.cc (create_dispatcher_calls): Likewise.
+
+2022-11-05 Jonathan Wakely <jwakely@redhat.com>
+
+ PR c/41041
+ * doc/cppopts.texi: Document -fwide-exec-charset defaults
+ correctly.
+
+2022-11-05 Alexandre Oliva <oliva@adacore.com>
+
+ * common.opt (fmultiflags): New.
+ * doc/invoke.texi: Document it.
+ * gcc.cc (driver_self_specs): Discard it.
+ * opts.cc (common_handle_option): Ignore it in the driver.
+
+2022-11-04 Jeff Chapman II <jchapman@lock3software.com>
+ Jason Merrill <jason@redhat.com>
+
+ * input.cc (get_source_text_between): New fn.
+ * input.h (get_source_text_between): Declare.
+
+2022-11-04 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/107342
+ * range-op.cc (operator_mult::fold_range): New.
+ (operator_div::fold_range): New.
+
+2022-11-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * fold-const.cc (operand_compare::operand_equal_p) <COMPONENT_REF>:
+ Do not take into account operand 2.
+ (operand_compare::hash_operand) <COMPONENT_REF>: Likewise.
+
+2022-11-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * expr.cc (emit_group_store): Do not use subword paradoxical subregs
+
+2022-11-04 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64-sve2.md: Fix typo in Cryptographic
+ extensions comment.
+
+2022-11-04 Thomas Schwinge <thomas@codesourcery.com>
+
+ * config.gcc [target *-intelmic-* | *-intelmicemul-*]: Remove.
+ * config/i386/i386-options.cc (ix86_omp_device_kind_arch_isa)
+ [ACCEL_COMPILER]: Remove.
+ * config/i386/intelmic-mkoffload.cc: Remove.
+ * config/i386/intelmic-offload.h: Likewise.
+ * config/i386/t-intelmic: Likewise.
+ * config/i386/t-omp-device: Likewise.
+ * configure.ac [target *-intelmic-* | *-intelmicemul-*]: Remove.
+ * configure: Regenerate.
+ * doc/install.texi (--enable-offload-targets=[...]): Update.
+ * doc/sourcebuild.texi: Remove 'liboffloadmic' documentation.
+
+2022-11-04 Thomas Schwinge <thomas@codesourcery.com>
+
+ * Makefile.in (OBJS): Remove 'dbxout.o'.
+ * config/nvptx/nvptx.cc: Don't '#include "dbxout.h"'.
+ * dbxout.cc: Remove.
+ * dbxout.h: Likewise.
+ * target-def.h (TARGET_ASM_CONSTRUCTOR, TARGET_ASM_DESTRUCTOR):
+ Default to 'default_asm_out_constructor',
+ 'default_asm_out_destructor'.
+ * targhooks.cc (default_asm_out_constructor)
+ (default_asm_out_destructor): New.
+ * targhooks.h (default_asm_out_constructor)
+ (default_asm_out_destructor): Declare.
+
+2022-11-04 Thomas Schwinge <thomas@codesourcery.com>
+
+ * Makefile.in (OBJS): Add 'dbxout.o'.
+ * config/nvptx/nvptx.cc: '#include "dbxout.h"'.
+ * dbxout.cc: New.
+ * dbxout.h: Likewise.
+ * target-def.h (TARGET_ASM_CONSTRUCTOR, TARGET_ASM_DESTRUCTOR):
+ Default to 'default_stabs_asm_out_constructor',
+ 'default_stabs_asm_out_destructor'.
+
+2022-11-04 Hongyu Wang <hongyu.wang@intel.com>
+ Haochen Jiang <haochen.jiang@intel.com>
+
+ * common/config/i386/cpuinfo.h (get_available_features): Detect
+ amx-fp16.
+ * common/config/i386/i386-common.cc (OPTION_MASK_ISA2_AMX_FP16_SET,
+ OPTION_MASK_ISA2_AMX_FP16_UNSET): New macros.
+ (ix86_handle_option): Handle -mamx-fp16.
+ * common/config/i386/i386-cpuinfo.h (enum processor_features):
+ Add FEATURE_AMX_FP16.
+ * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for
+ amx-fp16.
+ * config.gcc: Add amxfp16intrin.h.
+ * config/i386/cpuid.h (bit_AMX_FP16): New.
+ * config/i386/i386-c.cc (ix86_target_macros_internal): Define
+ __AMX_FP16__.
+ * config/i386/i386-isa.def: Add DEF_PTA for AMX_FP16.
+ * config/i386/i386-options.cc (isa2_opts): Add -mamx-fp16.
+ (ix86_valid_target_attribute_inner_p): Add new ATTR.
+ (ix86_option_override_internal): Handle AMX-FP16.
+ * config/i386/i386.opt: Add -mamx-fp16.
+ * config/i386/immintrin.h: Include amxfp16intrin.h.
+ * doc/extend.texi: Document -mamx-fp16.
+ * doc/invoke.texi: Document amx-fp16.
+ * doc/sourcebuild.texi: Document amx_fp16.
+ * config/i386/amxfp16intrin.h: New file.
+
+2022-11-04 Haochen Jiang <haochen.jiang@intel.com>
+
+ * common/config/i386/cpuinfo.h (get_intel_cpu):
+ Add Sierra Forest.
+ * common/config/i386/i386-common.cc
+ (processor_names): Add Sierra Forest.
+ (processor_alias_table): Ditto.
+ * common/config/i386/i386-cpuinfo.h
+ (enum processor_types): Add INTEL_SIERRAFOREST.
+ * config.gcc: Add -march=sierraforest.
+ * config/i386/driver-i386.cc (host_detect_local_cpu):
+ Handle Sierra Forest.
+ * config/i386/i386-c.cc (ix86_target_macros_internal):
+ Ditto.
+ * config/i386/i386-options.cc (m_SIERRAFOREST): New define.
+ (processor_cost_table): Add sierra forest.
+ * config/i386/i386.h (enum processor_type):
+ Add PROCESSOR_SIERRA_FOREST.
+ (PTA_SIERRAFOREST): Ditto.
+ * doc/extend.texi: Add sierra forest.
+ * doc/invoke.texi: Ditto.
+
+2022-11-04 Haochen Jiang <haochen.jiang@intel.com>
+
+ * common/config/i386/cpuinfo.h (get_available_features):
+ Detect cmpccxadd.
+ * common/config/i386/i386-common.cc
+ (OPTION_MASK_ISA2_CMPCCXADD_SET,
+ OPTION_MASK_ISA2_CMPCCXADD_UNSET): New.
+ (ix86_handle_option): Handle -mcmpccxadd.
+ * common/config/i386/i386-cpuinfo.h (enum processor_features):
+ Add FEATURE_CMPCCXADD.
+ * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for
+ cmpccxadd.
+ * config.gcc: Add cmpccxaddintrin.h.
+ * config/i386/cpuid.h (bit_CMPCCXADD): New.
+ * config/i386/i386-builtin-types.def:
+ Add DEF_FUNCTION_TYPE(INT, PINT, INT, INT, INT)
+ and DEF_FUNCTION_TYPE(LONGLONG, PLONGLONG, LONGLONG, LONGLONG, INT).
+ * config/i386/i386-builtin.def (BDESC): Add new builtins.
+ * config/i386/i386-c.cc (ix86_target_macros_internal): Define
+ __CMPCCXADD__.
+ * config/i386/i386-expand.cc (ix86_expand_special_args_builtin):
+ Add new parameter to indicate constant position.
+ Handle INT_FTYPE_PINT_INT_INT_INT
+ and LONGLONG_FTYPE_PLONGLONG_LONGLONG_LONGLONG_INT.
+ * config/i386/i386-isa.def (CMPCCXADD): Add DEF_PTA(CMPCCXADD).
+ * config/i386/i386-options.cc (isa2_opts): Add -mcmpccxadd.
+ (ix86_valid_target_attribute_inner_p): Handle cmpccxadd.
+ * config/i386/i386.opt: Add option -mcmpccxadd.
+ * config/i386/sync.md (cmpccxadd_<mode>): New define insn.
+ * config/i386/x86gprintrin.h: Include cmpccxaddintrin.h.
+ * doc/extend.texi: Document cmpccxadd.
+ * doc/invoke.texi: Document -mcmpccxadd.
+ * doc/sourcebuild.texi: Document target cmpccxadd.
+ * config/i386/cmpccxaddintrin.h: New file.
+
+2022-11-03 Jason Merrill <jason@redhat.com>
+
+ * doc/invoke.texi: -fconcepts no longer implies
+ -fconcepts-ts before C++20.
+
+2022-11-03 Kwok Cheung Yeung <kcy@codesourcery.com>
+
+ * config/gcn/gcn-valu.md (math_unop_insn): New attribute.
+ (<math_unop><mode>2, <math_unop><mode>2<exec>, <math_unop><mode>2,
+ <math_unop><mode>2<exec>, *<math_unop><mode>2_insn,
+ *<math_unop><mode>2<exec>_insn): Use math_unop_insn to generate
+ assembler output.
+
+2022-11-03 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range.cc (gimple_ranger::update_stmt): New.
+ * gimple-range.h (gimple_ranger::update_stmt): New prototype.
+ * tree-ssa-operands.cc (update_stmt_operands): Notify range
+ query that stmt has changed.
+ * value-query.h (range_query::update_stmt): New.
+
+2022-11-03 David Malcolm <dmalcolm@redhat.com>
+
+ * make-unique.h: New file.
+
+2022-11-03 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/107404
+ * config/i386/i386.md (eliminate reg-reg move by inverting the
+ condition of a cmove #2 peephole2): Check if eliminated move
+ initialized a register, used in the moved instruction.
+
+2022-11-03 Andrew Stubbs <ams@codesourcery.com>
+
+ PR target/107510
+ * config/gcn/gcn.cc (gcn_expand_reduc_scalar): Remove duplicate
+ UNSPEC_SMIN_DPP_SHR conditionals.
+
+2022-11-02 Christoph Müllner <christoph.muellner@vrull.eu>
+
+ * common/config/riscv/riscv-common.cc: Add zawrs extension.
+ * config/riscv/riscv-opts.h (MASK_ZAWRS): New.
+ (TARGET_ZAWRS): New.
+ * config/riscv/riscv.opt: New.
+
+2022-11-02 Rasmus Villemoes <rv@rasmusvillemoes.dk>
+
+ PR driver/93371
+ * gcc.cc (ASM_MAP): Honour -ffile-prefix-map.
+
+2022-11-02 Aldy Hernandez <aldyh@redhat.com>
+
+ * value-range.cc (frange::contains_p): Fix signed zero handling.
+ (range_tests_signed_zeros): New test.
+
+2022-11-02 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * builtins.cc (mathfn_built_in_2): #undef HUGE_VAL, NAN.
+
+2022-11-02 Xionghu Luo <xionghuluo@tencent.com>
+
+ PR target/100866
+ * config/rs6000/altivec.md: (*altivec_vrl<VI_char>): Named to...
+ (altivec_vrl<VI_char>): ...this.
+ * config/rs6000/vsx.md (revb_<mode>): Call vspltish and vrlh when
+ target is Power8 and mode is V8HI.
+
+2022-11-01 David Seifert <soap@gentoo.org>
+
+ * configure.ac: Add AC_CACHE_CHECK(..., gcc_cv_sys_sdt_h).
+ * configure: Regenerate.
+
+2022-11-01 Richard Purdie <richard.purdie@linuxfoundation.org>
+
+ * file-prefix-map.cc (remap_filename): Allow remapping of relative paths.
+
+2022-11-01 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/107490
+ * range-op-float.cc (foperator_unordered_lt::op1_range): Handle
+ NANs.
+ (foperator_unordered_lt::op2_range): Same.
+ (foperator_unordered_le::op1_range): Same.
+ (foperator_unordered_le::op2_range): Same.
+ (foperator_unordered_gt::op1_range): Same.
+ (foperator_unordered_gt::op2_range): Same.
+ (foperator_unordered_ge::op1_range): Same.
+ (foperator_unordered_ge::op2_range): Same.
+
+2022-11-01 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/107497
+ * tree-vrp.cc (remove_unreachable::remove_and_update_globals):
+ Check that ssa-name still exists before accessing it.
+
+2022-11-01 Andrew MacLeod <amacleod@redhat.com>
+
+ * params.opt (param_vrp1_mode): Make ranger default.
+
+2022-11-01 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-vrp.cc (class remove_unreachable): New.
+ (remove_unreachable::maybe_register_block): New.
+ (remove_unreachable::remove_and_update_globals): New.
+ (rvrp_folder::rvrp_folder): Initialize m_unreachable.
+ (rvrp_folder::post_fold_bb): Maybe register unreachable block.
+ (rvrp_folder::m_unreachable): New member.
+ (execute_ranger_vrp): Add final_pass flag, remove unreachables.
+
+2022-11-01 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range-cache.cc (ranger_cache::fill_block_cache): Allow
+ exit block to be specified.
+ (ranger_cache::range_from_dom): If exit block is specified, use
+ the immediate predecessor instead of the dominator to start.
+ * gimple-range.cc (gimple_ranger::range_on_exit): Allow query
+ for exit block.
+
+2022-11-01 Andrew MacLeod <amacleod@redhat.com>
+
+ * value-range.cc (irange::intersect_nonzero_bits): If new
+ non-zero mask is the same as original, flag no change.
+
+2022-11-01 Alexander Monakov <amonakov@ispras.ru>
+
+ PR target/87832
+ * config/i386/znver.md (znver1_idiv): New automaton.
+ (znver1-idiv): New unit.
+ (znver1_idiv_DI): Correct unit and cycles in the reservation.
+ (znver1_idiv_SI): Ditto.
+ (znver1_idiv_HI): Ditto.
+ (znver1_idiv_QI): Ditto.
+ (znver1_idiv_mem_DI): Ditto.
+ (znver1_idiv_mem_SI): Ditto.
+ (znver1_idiv_mem_HI): Ditto.
+ (znver1_idiv_mem_QI): Ditto.
+ (znver3_idiv_DI): Ditto.
+ (znver3_idiv_SI): Ditto.
+ (znver3_idiv_HI): Ditto.
+ (znver3_idiv_QI): Ditto.
+ (znver3_idiv_mem_DI): Ditto.
+ (znver3_idiv_mem_SI): Ditto.
+ (znver3_idiv_mem_HI): Ditto.
+ (znver3_idiv_mem_QI): Ditto.
+
+2022-11-01 liuhongt <hongtao.liu@intel.com>
+
+ PR target/107057
+ * config/i386/sse.md (*vec_interleave_highv2df): Remove
+ constraint 1.
+ (*vec_interleave_lowv2df): Ditto.
+ (vec_concatv2df): Ditto.
+ (*avx512f_unpcklpd512<mask_name>): Ditto and renamed to ..
+ (avx512f_unpcklpd512<mask_name>): .. this.
+ (avx512f_movddup512<mask_name>): Change to define_insn.
+ (avx_movddup256<mask_name>): Ditto.
+ (*avx_unpcklpd256<mask_name>): Remove constraint 1 and renamed
+ to ..
+ (avx_unpcklpd256<mask_name>): .. this.
+ * config/i386/i386.cc (ix86_vec_interleave_v2df_operator_ok):
+ Disallow MEM_P (op1) && MEM_P (op2).
+
+2022-11-01 liuhongt <hongtao.liu@intel.com>
+
+ PR target/55583
+ * config/i386/i386.md (*x86_64_shld_1): Rename to ..
+ (x86_64_shld_1): .. this.
+ (*x86_shld_1): Rename to ..
+ (x86_shld_1): .. this.
+ (*x86_64_shrd_1): Rename to ..
+ (x86_64_shrd_1): .. this.
+ (*x86_shrd_1): Rename to ..
+ (x86_shrd_1): .. this.
+ (*x86_64_shld_shrd_1_nozext): New pre_reload splitter.
+ (*x86_shld_shrd_1_nozext): Ditto.
+ (*x86_64_shrd_shld_1_nozext): Ditto.
+ (*x86_shrd_shld_1_nozext): Ditto.
+
+2022-11-01 Cui,Lili <lili.cui@intel.com>
+
+ * ipa-inline-analysis.cc (do_estimate_edge_time): Add function attribute
+ judgement for INLINE_HINT_known_hot hint.
+
2022-10-31 Guillermo E. Martinez <guillermo.e.martinez@oracle.com>
* btfout.cc (btf_calc_num_vbytes): Compute enumeration size depending of
@@ -802,9 +9163,9 @@
* configure: Regenerated.
* config.in: Regenerated.
* config/mips/mips.h: don't define STANDARD_STARTFILE_PREFIX_1
- if ENABLE_MULTIARCH is defined.
+ if ENABLE_MULTIARCH is defined.
* config/mips/t-linux64: define correct multiarch path when
- multiarch is enabled.
+ multiarch is enabled.
2022-10-25 Richard Biener <rguenther@suse.de>
@@ -821,7 +9182,7 @@
2022-10-25 Martin Liska <mliska@suse.cz>
* common/config/riscv/riscv-common.cc
- (riscv_get_valid_option_values): Get out of ifdef.
+ (riscv_get_valid_option_values): Get out of ifdef.
2022-10-25 Martin Liska <mliska@suse.cz>
@@ -856,8 +9217,8 @@
PR target/107364
* common/config/i386/i386-cpuinfo.h (enum processor_vendor):
- Reorder enum values as BUILTIN_VENDOR_MAX should not point
- in the middle of the valid enum values.
+ Reorder enum values as BUILTIN_VENDOR_MAX should not point
+ in the middle of the valid enum values.
2022-10-24 Marek Polacek <polacek@redhat.com>
@@ -1275,13 +9636,13 @@
* config/i386/avxifmaintrin.h: New header.
* config/i386/cpuid.h (bit_AVXIFMA): New.
* config/i386/i386-builtin.def: Add new builtins, and correct
- pattern names for AVX512IFMA.
+ pattern names for AVX512IFMA.
* config/i386/i386-builtins.cc (def_builtin): Handle AVX-IFMA
- builtins like AVX-VNNI.
+ builtins like AVX-VNNI.
* config/i386/i386-c.cc (ix86_target_macros_internal): Define
__AVXIFMA__.
* config/i386/i386-expand.cc (ix86_check_builtin_isa_match):
- Relax ISA masks for AVXIFMA.
+ Relax ISA masks for AVXIFMA.
* config/i386/i386-isa.def: Add AVXIFMA.
* config/i386/i386-options.cc (isa2_opts): Add -mavxifma.
(ix86_valid_target_attribute_inner_p): Handle avxifma.
@@ -1316,7 +9677,7 @@
(foperator_unordered_lt::op2_range): New.
2022-10-20 Artem Klimov <jakmobius@gmail.com>
- Alexander Monakov <amonakov@gcc.gnu.org>
+ Alexander Monakov <amonakov@gcc.gnu.org>
PR middle-end/99619
* ipa-visibility.cc (function_and_variable_visibility): Promote
@@ -1490,7 +9851,7 @@
2022-10-19 Andrew MacLeod <amacleod@redhat.com>
* gimple-range-cache.cc (ranger_cache::range_from_dom): Use
- Value_Range not int_range_max.
+ Value_Range not int_range_max.
2022-10-19 Aldy Hernandez <aldyh@redhat.com>
@@ -1555,8 +9916,8 @@
Use !xtensa_split1_finished_p() instead of can_create_pseudo_p().
* config/xtensa/predicates.md (move_operand): Ditto.
* config/xtensa/xtensa.md: Add two new split patterns:
- - splits DImode immediate load into two SImode ones
- - puts out-of-constraint SImode constants into the constant pool
+ - splits DImode immediate load into two SImode ones
+ - puts out-of-constraint SImode constants into the constant pool
* config/xtensa/xtensa.opt (-mlra): New target-specific option
for testing purpose.
@@ -2147,7 +10508,7 @@
* gimple-range-cache.cc (ranger_cache::fill_block_cache): Use
iterator.
* value-relation.cc
- (equiv_relation_iterator::equiv_relation_iterator): New.
+ (equiv_relation_iterator::equiv_relation_iterator): New.
(equiv_relation_iterator::next): New.
(equiv_relation_iterator::get_name): New.
* value-relation.h (class relation_oracle): Privatize some methods.
@@ -2532,7 +10893,6 @@
to [0,0] when nonzero mask is 0.
2022-10-11 Olivier Hainque <hainque@adacore.com>
- Olivier Hainque <hainque@adacore.com>
* configure: Regenerate.
@@ -2748,8 +11108,8 @@
* config.gcc: set with_arch to default_mips_arch if no defined.
* config/mips/driver-native.cc (host_detect_local_cpu):
- try getauxval(AT_BASE_PLATFORM) and _MIPS_ARCH, too.
- pass -mnan=2008 if __mips_nan2008__ is defined.
+ try getauxval(AT_BASE_PLATFORM) and _MIPS_ARCH, too.
+ pass -mnan=2008 if __mips_nan2008__ is defined.
* config.in: define HAVE_SYS_AUXV_H and HAVE_GETAUXVAL.
* configure.ac: detect sys/auxv.h and getauxval.
* configure: regenerated.
@@ -2837,7 +11197,7 @@
2022-10-07 Martin Liska <mliska@suse.cz>
* config/i386/i386-protos.h (ix86_binary_operator_ok): Add array
- size to function parameter.
+ size to function parameter.
(ix86_unary_operator_ok): Likewise.
2022-10-07 Martin Liska <mliska@suse.cz>
@@ -3921,7 +12281,7 @@
2022-09-26 Martin Liska <mliska@suse.cz>
* doc/invoke.texi: Add missing dash for
- Wanalyzer-exposure-through-uninit-copy.
+ Wanalyzer-exposure-through-uninit-copy.
2022-09-26 Aldy Hernandez <aldyh@redhat.com>
@@ -4145,7 +12505,7 @@
* common.opt: Update -flto-compression-level documentation.
* opts.cc (print_filtered_help): Do not append range to an
- option that uses \t syntax.
+ option that uses \t syntax.
2022-09-23 Jakub Jelinek <jakub@redhat.com>
@@ -4266,14 +12626,14 @@
2022-09-22 Andrew MacLeod <amacleod@redhat.com>
* range-op-float.cc (range_operator_float::fold_range): New base
- method for "int = float op int".
+ method for "int = float op int".
* range-op.cc (range_op_handler::fold_range): New case.
* range-op.h: Update prototypes.
2022-09-22 Andrew MacLeod <amacleod@redhat.com>
* gimple-range-op.cc (gimple_range_op_handler::calc_op1): Use
- operand 1 for second range if there is no operand 2.
+ operand 1 for second range if there is no operand 2.
2022-09-22 Andrew MacLeod <amacleod@redhat.com>
@@ -4327,8 +12687,8 @@
2022-09-22 Andrew MacLeod <amacleod@redhat.com>
* tree-ssa-threadbackward.cc
- (back_threader::find_paths_to_names): Replace sequence with
- a call to gimple_range_ssa_names.
+ (back_threader::find_paths_to_names): Replace sequence with
+ a call to gimple_range_ssa_names.
2022-09-22 Martin Liska <mliska@suse.cz>
Fangrui Song <i@maskray.me>
@@ -4338,7 +12698,7 @@
and gcc_cv_as_compress_debug={0,1}.
* doc/invoke.texi: Document the removal.
* gcc.cc (LINK_COMPRESS_DEBUG_SPEC): Simplify and ignore
- zlib-gnu.
+ zlib-gnu.
(ASM_COMPRESS_DEBUG_SPEC): Likewise.
2022-09-22 Richard Biener <rguenther@suse.de>
@@ -5306,10 +13666,10 @@
PR bootstrap/106855
* collect2.cc (scan_prog_file): Restore if XCOFF_DEBUGGING_INFO.
* config/rs6000/rs6000.cc (rs6000_option_override_internal):
- Restore usage of XCOFF_DEBUGGING_INFO.
+ Restore usage of XCOFF_DEBUGGING_INFO.
* config/rs6000/xcoff.h (XCOFF_DEBUGGING_INFO): Restore.
* dwarf2asm.cc (XCOFF_DEBUGGING_INFO): Restore support for
- XCOFF_DEBUGGING_INFO.
+ XCOFF_DEBUGGING_INFO.
(dw2_asm_output_nstring): Likewise.
(USE_LINKONCE_INDIRECT): Likewise.
* dwarf2out.cc (XCOFF_DEBUGGING_INFO): Likewise.
@@ -5623,7 +13983,7 @@
2022-09-05 Martin Liska <mliska@suse.cz>
* doc/tm.texi.in: Rename DEBUGGER_REGISTER_NUMBER to
- DEBUGGER_REGNO.
+ DEBUGGER_REGNO.
* doc/tm.texi: Regenerate.
2022-09-05 Martin Liska <mliska@suse.cz>
@@ -6086,7 +14446,7 @@
2022-09-02 Martin Liska <mliska@suse.cz>
* Makefile.in: Remove -gstabs option support, DBX-related
- macros and DBX debugging info support.
+ macros and DBX debugging info support.
* collect2.cc (scan_prog_file): Likewise.
* common.opt: Likewise.
* config.gcc: Likewise.
@@ -6437,7 +14797,7 @@
PR tree-optimization/106789
* range-op-float.cc (default_frelop_fold_range): Remove the
- function.
+ function.
2022-08-31 Martin Liska <mliska@suse.cz>
@@ -6688,7 +15048,7 @@
2022-08-30 Martin Liska <mliska@suse.cz>
* config/s390/s390.cc (s390_rtx_costs): Use proper type as
- argument.
+ argument.
2022-08-30 Richard Biener <rguenther@suse.de>
@@ -7367,9 +15727,9 @@
* config.in: Regenerate.
* configure: Regenerate.
* opts-common.cc (jobserver_info::connect): Set is_connected
- properly based on O_NONBLOCK.
+ properly based on O_NONBLOCK.
* opts-jobserver.h (struct jobserver_info): Add is_connected
- member variable.
+ member variable.
2022-08-22 zhongjuzhe <juzhe.zhong@rivai.ai>
@@ -7522,7 +15882,7 @@
PR gcov-profile/106659
* gcov-dump.cc (INCLUDE_VECTOR): Include vector.h with
- INCLUDE_VECTOR.
+ INCLUDE_VECTOR.
2022-08-18 konglin1 <lingling.kong@intel.com>
@@ -7783,7 +16143,7 @@
* gimple-range-fold.cc (gimple_range_ssa_names): New.
* gimple-range-fold.h (gimple_range_ssa_names): New prototype.
* gimple-range-gori.cc (range_def_chain::get_def_chain): Move
- code to new routine.
+ code to new routine.
2022-08-16 Martin Liska <mliska@suse.cz>
@@ -7874,13 +16234,13 @@
2022-08-16 Martin Liska <mliska@suse.cz>
* value-range-storage.h (class obstack_vrange_allocator): Mark
- the class as final.
+ the class as final.
(class ggc_vrange_allocator): Likewise.
2022-08-16 Martin Liska <mliska@suse.cz>
* value-range-equiv.h (class value_range_equiv): Add virtual
- destructor.
+ destructor.
* value-range.h: Likewise.
2022-08-16 Richard Biener <rguenther@suse.de>
@@ -7896,7 +16256,7 @@
2022-08-16 Martin Liska <mliska@suse.cz>
* config/i386/i386-features.h (class general_scalar_chain): Add
- final override for a method.
+ final override for a method.
(class timode_scalar_chain): Likewise.
2022-08-16 Richard Biener <rguenther@suse.de>
@@ -8257,7 +16617,7 @@
PR tree-optimization/106556
* gimple-range-gori.cc (gori_compute::condexpr_adjust): Use the
- type of the cond_expr operands being evaluted.
+ type of the cond_expr operands being evaluted.
2022-08-08 Tom Honermann <tom@honermann.net>
@@ -8376,7 +16736,7 @@
PR tree-optimization/106514
* value-relation.cc (path_oracle::killing_def) Do not walk the
- equivalence set clearing bits.
+ equivalence set clearing bits.
2022-08-03 Tamar Christina <tamar.christina@arm.com>
@@ -8455,7 +16815,7 @@
PR tree-optimization/106510
* gimple-range-fold.cc (fur_source::register_outgoing_edges):
- Check for unsupported statements early.
+ Check for unsupported statements early.
2022-08-02 Andrew MacLeod <amacleod@redhat.com>
@@ -9505,7 +17865,7 @@
2022-07-19 Andrew MacLeod <amacleod@redhat.com>
* gimple-range-cache.cc (ranger_cache::range_from_dom): Check
- for incoming ranges on join nodes and add to worklist.
+ for incoming ranges on join nodes and add to worklist.
2022-07-19 Andrew MacLeod <amacleod@redhat.com>
@@ -13717,7 +22077,7 @@
2022-05-24 Vineet Gupta <vineetg@rivosinc.com>
* config/riscv/riscv.cc: (struct riscv_tune_param): Add
- fmv_cost.
+ fmv_cost.
(rocket_tune_info): Add default fmv_cost 8.
(sifive_7_tune_info): Ditto.
(thead_c906_tune_info): Ditto.
@@ -15901,7 +24261,7 @@
PR target/103069
* config/i386/i386-expand.cc (ix86_expand_cmpxchg_loop):
- Add missing set to target_val at pause label.
+ Add missing set to target_val at pause label.
2022-04-13 Jakub Jelinek <jakub@redhat.com>
@@ -16565,7 +24925,7 @@
2022-04-01 YunQiang Su <yunqiang.su@cipunited.com>
* config/mips/mips.cc (mips_expand_prologue):
- IPL is 8bit for MCU ASE.
+ IPL is 8bit for MCU ASE.
2022-03-31 Bill Schmidt <wschmidt@linux.ibm.com>
@@ -16688,8 +25048,8 @@
Tobias Burnus <tobias@codesourcery.com>
* doc/invoke.texi (march): Document __PTX_SM__.
- (mptx): Document __PTX_ISA_VERSION_MAJOR__ and
- __PTX_ISA_VERSION_MINOR__.
+ (mptx): Document __PTX_ISA_VERSION_MAJOR__ and
+ __PTX_ISA_VERSION_MINOR__.
2022-03-30 Jakub Jelinek <jakub@redhat.com>
@@ -17187,7 +25547,7 @@
PR target/104898
* config/i386/i386-options.cc (ix86_option_override_internal):
- Use '%qs' instead of '(%qs)'.
+ Use '%qs' instead of '(%qs)'.
2022-03-22 Martin Liska <mliska@suse.cz>
@@ -18383,7 +26743,7 @@
PR target/104664
* config/i386/i386-expand.cc (ix86_expand_vector_init_duplicate):
- Use vec_setv8hf_0 for HF to V8HFmode move instead of subreg.
+ Use vec_setv8hf_0 for HF to V8HFmode move instead of subreg.
2022-02-28 Roger Sayle <roger@nextmovesoftware.com>
@@ -20682,7 +29042,7 @@
PR middle-end/95115
* fold-const.cc (const_binop): Do not fold NaN result from
- non-NaN operands.
+ non-NaN operands.
2022-02-01 Tom de Vries <tdevries@suse.de>
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 3950253..349ad3e 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20221101
+20221213
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index fb1fd4b..69af6e9 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -272,6 +272,7 @@ COMPILER += $(CET_HOST_FLAGS)
NO_PIE_CFLAGS = @NO_PIE_CFLAGS@
NO_PIE_FLAG = @NO_PIE_FLAG@
+DO_LINK_MUTEX = @DO_LINK_MUTEX@
# We don't want to compile the compilers with -fPIE, it make PCH fail.
COMPILER += $(NO_PIE_CFLAGS)
@@ -1257,13 +1258,17 @@ C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
ANALYZER_OBJS = \
analyzer/analysis-plan.o \
analyzer/analyzer.o \
+ analyzer/analyzer-language.o \
analyzer/analyzer-logging.o \
analyzer/analyzer-pass.o \
analyzer/analyzer-selftests.o \
analyzer/bar-chart.o \
+ analyzer/bounds-checking.o \
+ analyzer/call-details.o \
analyzer/call-info.o \
analyzer/call-string.o \
analyzer/call-summary.o \
+ analyzer/checker-event.o \
analyzer/checker-path.o \
analyzer/complexity.o \
analyzer/constraint-manager.o \
@@ -1271,6 +1276,10 @@ ANALYZER_OBJS = \
analyzer/engine.o \
analyzer/feasible-graph.o \
analyzer/function-set.o \
+ analyzer/infinite-recursion.o \
+ analyzer/kf.o \
+ analyzer/kf-analyzer.o \
+ analyzer/kf-lang-cp.o \
analyzer/known-function-manager.o \
analyzer/pending-diagnostic.o \
analyzer/program-point.o \
@@ -1278,7 +1287,6 @@ ANALYZER_OBJS = \
analyzer/region.o \
analyzer/region-model.o \
analyzer/region-model-asm.o \
- analyzer/region-model-impl-calls.o \
analyzer/region-model-manager.o \
analyzer/region-model-reachability.o \
analyzer/sm.o \
@@ -1721,7 +1729,6 @@ OBJS = \
value-pointer-equiv.o \
value-query.o \
value-range.o \
- value-range-equiv.o \
value-range-pretty-print.o \
value-range-storage.o \
value-relation.o \
@@ -2771,6 +2778,7 @@ GTFILES = $(CPPLIB_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
$(srcdir)/internal-fn.h \
$(srcdir)/calls.cc \
$(srcdir)/omp-general.h \
+ $(srcdir)/analyzer/analyzer-language.cc \
@all_gtfiles@
# Compute the list of GT header files from the corresponding C sources,
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index e13486a..7ecefd8 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,1380 @@
+2022-12-06 Yannick Moy <moy@adacore.com>
+
+ * contracts.adb (Add_Contract_Item): Allow No_Caching on types.
+ (Check_Type_Or_Object_External_Properties): Check No_Caching.
+ Check that non-effectively volatile types does not contain an
+ effectively volatile component (instead of just a volatile
+ component).
+ (Analyze_Object_Contract): Remove shared checking of No_Caching.
+ * sem_prag.adb (Analyze_External_Property_In_Decl_Part): Adapt checking
+ of No_Caching for types.
+ (Analyze_Pragma): Allow No_Caching on types.
+ * sem_util.adb (Has_Effectively_Volatile_Component): New query function.
+ (Is_Effectively_Volatile): Type with Volatile and No_Caching is not
+ effectively volatile.
+ (No_Caching_Enabled): Remove assertion to apply to all entities.
+ * sem_util.ads: Same.
+
+2022-12-06 Javier Miranda <miranda@adacore.com>
+
+ * exp_ch6.adb
+ (Build_Static_Check_Helper_Call): Perform implicit type conversion
+ to ensure matching types and avoid reporting spurious errors.
+
+2022-12-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_warn.adb (Warn_On_Constant_Valid_Condition): Bail out for a
+ membership test with a mark for a subtype that is predicated.
+
+2022-12-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_elab.adb (Processing_In_State): Add Within_Freezing_Actions
+ component.
+ (Process_Conditional_ABE_Call): Compute its value.
+ (Process_Conditional_ABE_Call_SPARK): For a call and a target in
+ the main unit, do not emit any ABE diagnostics if the call occurs
+ in a freezing actions context.
+
+2022-12-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * einfo.ads (Actual_Subtype): Document additional usage.
+ * exp_aggr.adb (Expand_Array_Aggregate): Replace test on
+ Is_Build_In_Place_Return_Object with Is_Special_Return_Object.
+ * exp_ch3.adb (Expand_N_Object_Declaration): Factor out parts of the
+ processing done for build-in-place return objects and reuse them to
+ implement a similar processing for specific return objects.
+ * exp_ch4.adb (Expand_Allocator_Expression): Do not generate a tag
+ assignment or an adjustment if the allocator was made for a special
+ return object.
+ (Expand_Concatenate): If the result is allocated on the secondary
+ stack, use an unconstrained allocation.
+ * exp_ch6.ads (Apply_CW_Accessibility_Check): New declaration.
+ (Is_By_Reference_Return_Object): Likewise.
+ (Is_Secondary_Stack_Return_Object): Likewise.
+ (Is_Special_Return_Object): Likewise.
+ * exp_ch6.adb (Expand_Ctrl_Function_Call): Do not bail out for the
+ expression in the declaration of a special return object.
+ (Expand_N_Extended_Return_Statement): Add missing guard and move
+ the class-wide accessibility check to Expand_N_Object_Declaration.
+ (Expand_Simple_Function_Return): Delete obsolete commentary.
+ Skip the special processing for types that require finalization or
+ are returned on the secondary stack if the return originally comes
+ from an extended return statement. Add missing Constant_Present.
+ (Is_By_Reference_Return_Object): New predicate.
+ (Is_Secondary_Stack_Return_Object): Likewise.
+ (Is_Special_Return_Object): Likewise.
+ * exp_util.adb (Is_Related_To_Func_Return): Also return true if the
+ parent of the expression is the renaming declaration generated for
+ the expansion of a return object.
+ * gen_il-fields.ads (Opt_Field_Enum): Replace Alloc_For_BIP_Return
+ with For_Special_Return_Object.
+ * gen_il-gen-gen_nodes.adb (N_Allocator): Likewise.
+ * gen_il-internals.adb (Image): Remove Alloc_For_BIP_Return.
+ * sem_ch3.adb (Check_Return_Subtype_Indication): New procedure
+ moved from sem_ch6.adb.
+ (Analyze_Object_Declaration): Call it on a return object.
+ * sem_ch4.adb: Add with and use clauses for Rtsfind.
+ (Analyze_Allocator): Test For_Special_Return_Object to skip checks
+ for allocators made for special return objects.
+ Do not report restriction violations for the return stack pool.
+ * sem_ch5.adb (Analyze_Assignment.Set_Assignment_Type): Return the
+ Actual_Subtype for return objects that live on the secondary stack.
+ * sem_ch6.adb (Check_Return_Subtype_Indication): Move procedure to
+ sem_ch3.adb.
+ (Analyze_Function_Return): Do not call above procedure.
+ * sem_res.adb (Resolve_Allocator): Replace Alloc_For_BIP_Return
+ with For_Special_Return_Object.
+ * sinfo.ads: Likewise.
+ * treepr.adb (Image): Remove Alloc_For_BIP_Return.
+ * gcc-interface/trans.cc (gnat_to_gnu): Do not convert to the result
+ type in the unconstrained array type case if the parent is a simple
+ return statement.
+
+2022-12-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_res.adb (Resolve_Membership_Op): Adjust latest change.
+
+2022-12-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch4.adb (Expand_N_In) <Substitute_Valid_Check>: Rename to...
+ <Substitute_Valid_Test>: ...this.
+ Use Is_Entity_Name to test for the presence of entity references.
+ Do not warn or substitute a valid test for a test with a mark for
+ a subtype that is predicated.
+ Apply the same transformation for a test with a mark for a subtype
+ that is predicated as for a subtype that is not.
+ Remove useless return statement.
+ * sem_res.adb (Resolve_Membership_Op): Perform a special resolution
+ if the left operand is of a universal numeric type.
+
+2022-12-06 Justin Squirek <squirek@adacore.com>
+
+ * accessibility.adb, accessibility.ads
+ (Accessibility_Message): Moved from sem_attr.
+ (Apply_Accessibility_Check): Moved from checks.
+ (Apply_Accessibility_Check_For_Allocator): Moved from exp_ch4 and
+ renamed
+ (Check_Return_Construct_Accessibility): Moved from sem_ch6.
+ (Innermost_Master_Scope_Depth): Moved from sem_util. Add condition
+ to detect expanded iterators.
+ (Prefix_With_Safe_Accessibility_Level): Moved from sem_attr.
+ (Static_Accessibility_Level): Moved from sem_util.
+ (Has_Unconstrained_Access_Discriminants): Likewise.
+ (Has_Anonymous_Access_Discriminant): Likewise.
+ (Is_Anonymous_Access_Actual): Likewise.
+ (Is_Special_Aliased_Formal_Access): Likewise.
+ (Needs_Result_Accessibility_Level): Likewise.
+ (Subprogram_Access_Level): Likewise.
+ (Type_Access_Level): Likewise.
+ (Deepest_Type_Access_Level): Likewise.
+ (Effective_Extra_Accessibility): Likewise.
+ (Get_Dynamic_Accessibility): Likewise.
+ (Has_Access_Values): Likewise.
+ (Accessibility_Level): Likewise.
+ * exp_attr.adb (Access_Cases): Obtain the proper enclosing object
+ which applies to a given 'Access by looking through type
+ conversions.
+ * exp_ch4.adb (Apply_Accessibility_Check): Moved to accessibility.
+ * exp_ch5.adb: Likewise.
+ * exp_ch6.adb: Likewise.
+ * exp_ch9.adb: Likewise.
+ * exp_disp.adb: Likewise.
+ * gen_il-fields.ads: Add new flag Comes_From_Iterator.
+ * gen_il-gen-gen_nodes.adb: Add new flag Comes_From_Iterator for
+ N_Object_Renaming_Declaration.
+ * sem_ch5.adb (Analyze_Iterator_Specification): Mark object
+ renamings resulting from iterator expansion with the new flag
+ Comes_From_Iterator.
+ * sem_aggr.adb (Resolve_Container_Aggregate): Refine test.
+ * sem_ch13.adb: Add dependence on the accessibility package.
+ * sem_ch3.adb: Likewise.
+ * sem_ch4.adb: Likewise.
+ * sem_ch9.adb: Likewise.
+ * sem_res.adb: Likewise.
+ * sem_warn.adb: Likewise.
+ * exp_ch3.adb: Likewise.
+ * sem_attr.adb (Accessibility_Message): Moved to accessibility.
+ (Prefix_With_Safe_Accessibility_Level): Likewise.
+ * checks.adb, checks.ads (Apply_Accessibility_Check): Likewise.
+ * sem_ch6.adb (Check_Return_Construct_Accessibility): Likewise.
+ * sem_util.adb, sem_util.ads
+ (Accessibility_Level): Likewise.
+ (Deepest_Type_Access_Level): Likewise.
+ (Effective_Extra_Accessibility): Likewise.
+ (Get_Dynamic_Accessibility): Likewise.
+ (Has_Access_Values): Likewise.
+ (Has_Anonymous_Access_Discriminant): Likewise.
+ (Static_Accessibility_Level): Likewise.
+ (Has_Unconstrained_Access_Discriminants): Likewise.
+ (Is_Anonymous_Access_Actual): Likewise.
+ (Is_Special_Aliased_Formal_Access): Likewise.
+ (Needs_Result_Accessibility_Level): Likewise.
+ (Subprogram_Access_Level): Likewise.
+ (Type_Access_Level): Likewise.
+ * sinfo.ads: Document new flag Comes_From_Iterator.
+ * gcc-interface/Make-lang.in: Add entry for new Accessibility package.
+
+2022-12-06 Liaiss Merzougue <merzougue@adacore.com>
+
+ * libgnat/i-c.adb (To_C): Simplify code for having a single
+ exception raise. Add pragma annotate about uninitialized value
+ which happen only on exception raising.
+
+2022-12-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/trans.cc (get_storage_model_access): Strip any type
+ conversion around the node before looking into it.
+
+2022-12-01 Steve Baird <baird@adacore.com>
+
+ * sem_ch13.adb
+ (Validate_Aspect_Aggregate): Reject illegal case where none of
+ Add_Named, Add_Unnamed, and Assign_Indexed are specified.
+
+2022-12-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * doc/gnat_ugn/gnat_and_program_execution.rst (Non-Symbolic
+ Traceback): Add compilation line.
+ (Symbolic Traceback): Remove obsolete stuff.
+ * doc/gnat_ugn/gnat_utility_programs.rst (gnatsymbolize): Adjust.
+ * gnat_ugn.texi: Regenerate.
+
+2022-12-01 Ronan Desplanques <desplanques@adacore.com>
+
+ * lib-xref.adb (Generate_Reference): Fix misphrasing in comment.
+
+2022-12-01 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_attr.adb (Analyze_Attribute, Attribute_Address): In the case
+ where the attribute's prefix is a dereference of a value of an
+ access type that has aspect Designated_Storage_Model (or a
+ renaming of such a dereference), set the attribute's type to the
+ corresponding Storage_Model_Type's associated address type rather
+ than System.Address.
+
+2022-12-01 Ronan Desplanques <desplanques@adacore.com>
+
+ * doc/gnat_rm/the_gnat_library.rst: Fix minor issues.
+ * gnat_rm.texi: Regenerate.
+
+2022-12-01 Josue Nava Bello <nava@adacore.com>
+
+ * doc/share/conf.py: minor updates
+
+2022-11-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnat/g-traceb.ads: Minor tweaks in the commentary.
+ (Executable_Load_Address): New function.
+ * doc/gnat_ugn/gnat_and_program_execution.rst (Non-Symbolic
+ Traceback): Adjust to PIE default on Linux.
+ (Symbolic Traceback): Likewise.
+ * doc/gnat_ugn/gnat_utility_programs.rst (gnatsymbolize): Likewise.
+ * gnat_ugn.texi: Regenerate.
+
+2022-11-28 Joel Brobecker <brobecker@adacore.com>
+
+ * doc/share/conf.py (extensions): Add 'sphinx_rtd_theme'.
+ (html_theme): Set to 'sphinx_rtd_theme'.
+
+2022-11-28 Claire Dross <dross@adacore.com>
+
+ * libgnat/g-souinf.ads (Source_Code_Information): Add a new
+ volatile abstract state and add it in the global contract of all
+ functions defined in Source_Info.
+
+2022-11-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch6.adb (Expand_Actuals.Add_Call_By_Copy_Code): Deal with a
+ reference to a validation variable in the actual.
+ (Expand_Actuals.Add_Validation_Call_By_Copy_Code): Minor tweak.
+ (Expand_Actuals): Call Add_Validation_Call_By_Copy_Code directly
+ only if Add_Call_By_Copy_Code is not to be invoked.
+
+2022-11-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * adaint.c [Linux]: Include <link.h>.
+ (__gnat_get_executable_load_address) [Linux]: Enable.
+
+2022-11-28 Yannick Moy <moy@adacore.com>
+
+ * sem_prag.adb (Check_Part_Of_Abstract_State): Add verification
+ related to use of Part_Of, so that constituents in private childs
+ that refer to state in a sibling or parent unit force that unit to
+ have a body.
+ * sem_util.adb (Check_State_Refinements): Drop the requirement to
+ have always a package body for state refinement, when the package
+ state is mentioned in no Part_Of specification.
+ * sem_ch3.adb (Analyze_Declarations): Refresh SPARK refs in comment.
+ * sem_ch7.adb (Analyze_Package_Declaration): Likewise.
+
+2022-11-24 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/trans.cc (gnat_to_gnu) <N_Assignment_Statement>: Add
+ assertion that memset is not supposed to be used when the target has
+ a storage model with Copy_To routine.
+
+2022-11-24 Justin Squirek <squirek@adacore.com>
+
+ * sem_ch8.adb
+ (Find_Direct_Name): Remove bypass to reanalyze incorrectly
+ analyzed discriminals.
+ (Set_Entity_Or_Discriminal): Avoid resetting the entity field of a
+ discriminant reference to be the internally generated renaming
+ when we are in strict preanalysis mode.
+
+2022-11-22 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_prag.adb (Analyze_Depends_Global): Accept aspects on
+ abstract subprograms.
+
+2022-11-22 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * frontend.adb (Frontend): Re-enable Validate_Subprogram_Calls.
+ * exp_ch6.adb (Check_BIP_Actuals): When in CodePeer mode, do not
+ attempt to validate procedures coming from an
+ Elab_Spec/Elab_Body/Elab_Subp_Body procedure.
+
+2022-11-22 Piotr Trojanek <trojanek@adacore.com>
+
+ * errout.adb (To_Be_Removed): Decrease total number of errors when
+ removing a warning that has been escalated into error.
+ * erroutc.adb (dmsg): Print Warn_Runtime_Raise flag.
+
+2022-11-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch3.adb (Make_Tag_Assignment): Fix formatting glitches.
+
+2022-11-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * contracts.adb (Build_Subprogram_Contract_Wrapper): Do not fiddle
+ with the Was_Expression_Function flag. Move a few lines around.
+
+2022-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Constant>: Revert
+ latest change.
+ * gcc-interface/trans.cc (gnat_to_gnu) <N_Object_Declaration>:
+ Tweak latest change.
+
+2022-11-21 Marc Poulhiès <poulhies@adacore.com>
+
+ * exp_pakd.adb (Create_Packed_Array_Impl_Type): Do not share PAT
+ if sizes of types differ.
+
+2022-11-21 Ronan Desplanques <desplanques@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_pragmas.rst: Restore
+ alphabetical ordering.
+ * gnat_rm.texi: Regenerate.
+ * gnat_ugn.texi: Regenerate.
+
+2022-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_util.adb (Needs_Secondary_Stack): Test Is_Constrained
+ directly instead of Is_Definite_Subtype for an array subtype.
+
+2022-11-21 Steve Baird <baird@adacore.com>
+
+ * libgnat/s-rident.ads: Define a new restriction,
+ No_Task_Hierarchy_Implicit. This is like the No_Task_Hierarchy
+ restriction, but with the difference that setting this restriction
+ does not mean the H.6(6) post-compilation check is satisified.
+ * exp_ch6.adb (Add_Task_Actuals_To_Build_In_Place_Call): If it is
+ known that the function result cannot have tasks, then pass in a
+ null literal for the activation chain actual parameter. This
+ avoids generating a reference to an entity that
+ Build_Activation_Chain_Entity may have chosen not to generate a
+ declaration for.
+ * gnatbind.adb (List_Applicable_Restrictions): Do not list the
+ No_Task_Hierarchy_Implicit restriction.
+ * restrict.adb: Special treatment for the
+ No_Task_Hierarchy_Implicit restriction in functions
+ Get_Restriction_Id and Restriction_Active. The former is needed to
+ disallow the (unlikely) case that a user tries to explicitly
+ reference the No_Task_Hierarchy_Implicit restriction.
+ * sem_prag.adb (Analyze_Pragma): If a Sequential
+ Partition_Elaboration_Policy is specified (and the
+ No_Task_Hierarchy restriction is not already enabled), then enable
+ the No_Task_Hierarchy_Implicit restriction.
+
+2022-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch3.adb (Expand_N_Object_Declaration): Use Typ local
+ constant throughout, remove Ret_Obj_Typ local constant, rename
+ Ref_Type into Acc_Typ in a couple of places, remove a useless call
+ to Set_Etype, use a consistent checks suppression scheme, adjust
+ comments for the sake of consistencty and alphabetize some local
+ declarations.
+ * exp_ch6.adb (Expand_Simple_Function_Return): Remove a couple of
+ redundant local constants.
+
+2022-11-21 Steve Baird <baird@adacore.com>
+
+ * libgnat/a-sttebu.adb (Put): Add missing call to Encode.
+ * libgnat/a-strsup.ads: Declare new Put_Image procedure and add
+ Put_Image aspect specification for type Super_String.
+ * libgnat/a-strsup.adb (Put_Image): New procedure.
+ * libgnat/a-stwisu.ads: Declare new Put_Image procedure and add
+ Put_Image aspect specification for type Super_String.
+ * libgnat/a-stwisu.adb (Put_Image): New procedure.
+ * libgnat/a-stzsup.ads: Declare new Put_Image procedure and add
+ Put_Image aspect specification for type Super_String.
+ * libgnat/a-stzsup.adb (Put_Image): New procedure.
+
+2022-11-21 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * frontend.adb (Frontend): Disable subprogram call validation.
+
+2022-11-21 Bob Duff <duff@adacore.com>
+
+ * warnsw.ads, warnsw.adb: Move warning flags here from package
+ Opt. Rename Warning_Record to be Warnings_State. Use an array
+ instead of a record; this simplifies the code. Add renamings of
+ all the array components for easy reference outside this package.
+ Pass the "Family" to Set_Warning_Switch. Use more table-driven
+ code. Misc cleanup and comment fixes.
+ * opt.ads: Move warning switches to Warnsw.
+ * gnat1drv.adb
+ (Adjust_Global_Switches): Expanded names needed.
+ * inline.ads: Rename Warning_Record to be Warnings_State.
+ * sem_ch12.adb: Likewise.
+ * sem_prag.adb: Use new Set_Warning_Switch.
+ * contracts.adb, errout.adb, exp_aggr.adb, exp_ch11.adb: Adjust
+ imports for move to Warnsw.
+ * exp_ch5.adb, exp_prag.adb, exp_util.adb, frontend.adb: Likewise.
+ * layout.adb, lib-xref.adb, restrict.adb, scn.adb, sem_aggr.adb:
+ Likewise.
+ * sem_attr.adb, sem_case.adb, sem_ch10.adb, sem_ch11.adb:
+ Likewise.
+ * sem_ch13.adb, sem_ch3.adb, sem_ch4.adb, sem_ch5.adb: Likewise.
+ * sem_ch6.adb, sem_ch7.adb, sem_ch8.adb, sem_elab.adb: Likewise.
+ * sem_eval.adb, sem_res.adb, sem_util.adb, sem_warn.adb: Likewise.
+ * switch-c.adb: Likewise.
+
+2022-11-21 Steve Baird <baird@adacore.com>
+
+ * doc/gnat_ugn/building_executable_programs_with_gnat.rst: Improve
+ the description of how the -gnatw.h switch interacts with
+ "partial" record layout specifications (i.e., specifications where
+ the locations of some components are left unspecified).
+ * gnat_ugn.texi: Regenerate.
+
+2022-11-21 Marc Poulhiès <poulhies@adacore.com>
+
+ * sem_ch13.adb (Check_One_Attr): produce error when Size attribute
+ used on aliased object of elementary types with nonconfirming
+ value.
+
+2022-11-21 Ronan Desplanques <desplanques@adacore.com>
+
+ * sfn_scan.adb (Scan_SFN_Pragmas): Improve handling of comments.
+
+2022-11-21 Ronan Desplanques <desplanques@adacore.com>
+
+ * par-ch3.adb (P_Declarative_Item): Tweak handling of with keyword.
+
+2022-11-14 Boris Yakobowski <yakobowski@adacore.com>
+
+ * sem_case.adb: silence false positive warning emitted by CodePeer
+ on predefined equality for type Choice_Range_Info.
+
+2022-11-14 Bob Duff <duff@adacore.com>
+
+ * atree.ads: Remove some comments.
+ * err_vars.ads: Likewise.
+ * scans.ads: Likewise.
+ * sinput.ads: Likewise.
+ * checks.ads: Likewise. Also add a "???" comment indicating an
+ obsolete comment that is too difficult to correct at this time.
+ * sem_attr.adb: Minor comment rewrite.
+
+2022-11-14 Javier Miranda <miranda@adacore.com>
+
+ * exp_intr.adb
+ (Expand_Dispatching_Constructor_Call): Improve warning message.
+ * freeze.adb
+ (Check_No_Parts_Violations): Improve error message.
+
+2022-11-14 Alexandre Oliva <oliva@adacore.com>
+
+ * doc/gnat_rm/security_hardening_features.rst: Document optional
+ hardcfr checkpoints.
+ * gnat_rm.texi: Regenerate.
+ * gnat_ugn.texi: Regenerate.
+
+2022-11-14 Gary Dismukes <dismukes@adacore.com>
+
+ * checks.adb
+ (Apply_Type_Conversion_Checks): Apply Root_Type to the type of the
+ prefix of a Pos attribute when checking whether the type is a
+ formal discrete type.
+
+2022-11-14 Ronan Desplanques <desplanques@adacore.com>
+
+ * libgnat/s-regpat.adb
+ (Parse): Fix handling of non-capturing parentheses.
+
+2022-11-14 Yannick Moy <moy@adacore.com>
+
+ * sem_prag.adb (Analyze_Pragma): Add special case for the special
+ local subprogram created for contracts.
+
+2022-11-14 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch12.adb (Build_Subprogram_Wrappers): Adjust slocs of the
+ copied aspects, just like we do in Build_Class_Wide_Expression for
+ inherited class-wide contracts.
+
+2022-11-14 Piotr Trojanek <trojanek@adacore.com>
+
+ * inline.adb (Replace_Formal): Tune whitespace.
+ * sem_ch12.adb (Check_Overloaded_Formal_Subprogram): Refine type
+ of a formal parameter and local variable; this routine operates on
+ nodes and not entities.
+ * sem_ch12.ads: Tune whitespace.
+
+2022-11-14 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch12.adb (Analyze_Associations): Expand wrappers for
+ GNATprove.
+
+2022-11-14 Patrick Bernardi <bernardi@adacore.com>
+
+ * libgnat/system-qnx-arm.ads: Set Support_Atomic_Primitives to
+ True.
+ * libgnat/system-rtems.ads: Add Support_Atomic_Primitives.
+
+2022-11-14 Yannick Moy <moy@adacore.com>
+
+ * errout.adb (Error_Msg_Internal): Store span for Optr field, and
+ adapt to new type of Optr.
+ (Finalize. Output_JSON_Message, Remove_Warning_Messages): Adapt to
+ new type of Optr.
+ (Output_Messages): Use Optr instead of Sptr to display code
+ snippet closer to error.
+ * erroutc.adb (dmsg): Adapt to new type of Optr.
+ * erroutc.ads (Error_Msg_Object): Make Optr a span like Sptr.
+ * errutil.adb (Error_Msg): Likewise.
+
+2022-11-14 Arnaud Charlet <charlet@adacore.com>
+
+ * doc/gnat_ugn/gnat_utility_programs.rst: Remove gnatcheck
+ reference.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gnat-style.rst: Moved to...
+ * doc/gnat-style/index.rst: ...here.
+ * doc/gnat_rm.rst: Moved to...
+ * doc/gnat_rm/index.rst: ...here.
+ * doc/gnat_ugn.rst: Moved to...
+ * doc/gnat_ugn/index.rst: ...here.
+ * doc/share/latex_elements.py: Moved to...
+ * doc/share/ada_latex_elements.py: ...here.
+ * gcc-interface/Make-lang.in:
+ * doc/Makefile: Removed.
+ * doc/share/conf.py: Removed.
+ * doc/share/gnu_free_documentation_license.rst: Removed.
+ * gnat-style.texi: Removed.
+ * gnat_rm.texi: Removed.
+ * gnat_ugn.texi: Removed.
+ * doc/gnat-style/conf.py: New file.
+ * doc/gnat-style/gnu_free_documentation_license.rst: New file.
+ * doc/gnat_rm/conf.py: New file.
+ * doc/gnat_rm/gnu_free_documentation_license.rst: New file.
+ * doc/gnat_ugn/conf.py: New file.
+ * doc/gnat_ugn/gnu_free_documentation_license.rst: New file.
+ * doc/share/adabaseconf.py: New file.
+ * doc/gnat_rm/security_hardening_features.rst: Add role.
+ * doc/gnat_ugn/platform_specific_information.rst: Remove
+ duplicate definition of |nbsp|.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * gcc-interface/Make-lang.in: Support --with-sphinx-build.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gnat_rm/index.rst: Fix cross manual refs.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * gcc-interface/Make-lang.in:
+ Support installation if sphinx-build is missing.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * gcc-interface/Make-lang.in:
+ Support installation if sphinx-build is missing.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gnat_rm/index.rst: Fix cross manual refs.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * gcc-interface/Make-lang.in: Support --with-sphinx-build.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gnat-style.rst: Moved to...
+ * doc/gnat-style/index.rst: ...here.
+ * doc/gnat_rm.rst: Moved to...
+ * doc/gnat_rm/index.rst: ...here.
+ * doc/gnat_ugn.rst: Moved to...
+ * doc/gnat_ugn/index.rst: ...here.
+ * doc/share/latex_elements.py: Moved to...
+ * doc/share/ada_latex_elements.py: ...here.
+ * gcc-interface/Make-lang.in:
+ * doc/Makefile: Removed.
+ * doc/share/conf.py: Removed.
+ * doc/share/gnu_free_documentation_license.rst: Removed.
+ * gnat-style.texi: Removed.
+ * gnat_rm.texi: Removed.
+ * gnat_ugn.texi: Removed.
+ * doc/gnat-style/conf.py: New file.
+ * doc/gnat-style/gnu_free_documentation_license.rst: New file.
+ * doc/gnat_rm/conf.py: New file.
+ * doc/gnat_rm/gnu_free_documentation_license.rst: New file.
+ * doc/gnat_ugn/conf.py: New file.
+ * doc/gnat_ugn/gnu_free_documentation_license.rst: New file.
+ * doc/share/adabaseconf.py: New file.
+ * doc/gnat_rm/security_hardening_features.rst: Add role.
+ * doc/gnat_ugn/platform_specific_information.rst: Remove
+ duplicate definition of |nbsp|.
+
+2022-11-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/utils2.cc (build_allocator): For unconstrained
+ array types with a storage model and an initializing expression,
+ copy the initialization expression separately from the bounds. In
+ all cases with a storage model, pass the locally computed size for
+ the store.
+
+2022-11-08 Steve Baird <baird@adacore.com>
+
+ * sem_attr.adb
+ (Eval_Attribute): Don't simplify 'Image call if Put_Image has been
+ specified.
+
+2022-11-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_ch6.adb, exp_put_image.adb, sem_aggr.adb, sem_attr.adb,
+ sem_ch5.adb, sem_type.adb, sem_util.adb: Replace
+ "Present (Find_Aspect (...))" with "Has_Aspect".
+
+2022-11-08 Ronan Desplanques <desplanques@adacore.com>
+
+ * contracts.adb
+ (Preanalyze_Class_Conditions): New procedure.
+ (Preanalyze_Condition): Moved out from Merge_Class_Conditions in
+ order to be spec-visible.
+ * contracts.ads
+ (Preanalyze_Class_Conditions): New procedure.
+ * sem_prag.adb
+ (Analyze_Pre_Post_Condition_In_Decl_Part): Call
+ Preanalyze_Class_Conditions when necessary.
+
+2022-11-08 Johannes Kliemann <kliemann@adacore.com>
+
+ * libgnat/system-vxworks7-aarch64-rtp-smp.ads: Set
+ Support_Atomic_Primitives to True.
+ * libgnat/system-vxworks7-aarch64.ads: Set
+ Support_Atomic_Primitives to True.
+ * libgnat/system-vxworks7-arm-rtp-smp.ads: Set
+ Support_Atomic_Primitives to True.
+ * libgnat/system-vxworks7-arm.ads: Set Support_Atomic_Primitives
+ to True.
+ * libgnat/system-vxworks7-ppc-kernel.ads: Set
+ Support_Atomic_Primitives to False.
+ * libgnat/system-vxworks7-ppc-rtp-smp.ads: Set
+ Support_Atomic_Primitives to False.
+ * libgnat/system-vxworks7-ppc64-kernel.ads: Set
+ Support_Atomic_Primitives to True.
+ * libgnat/system-vxworks7-ppc64-rtp-smp.ads: Set
+ Support_Atomic_Primitives to True.
+ * libgnat/system-vxworks7-x86-kernel.ads: Set
+ Support_Atomic_Primitives to True.
+ * libgnat/system-vxworks7-x86-rtp-smp.ads: Set
+ Support_Atomic_Primitives to True.
+ * libgnat/system-vxworks7-x86_64-kernel.ads: Set
+ Support_Atomic_Primitives to True.
+ * libgnat/system-vxworks7-x86_64-rtp-smp.ads: Set
+ Support_Atomic_Primitives to True.
+
+2022-11-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * fe.h (Get_Warn_On_Questionable_Layout): Add void parameter.
+
+2022-11-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch12.adb (Instantiate_Formal_Subprogram): Copy aspect Ghost
+ from formal subprogram declaration to the internally generated
+ procedure.
+
+2022-11-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch4.adb (Analyze_Case_Expression): Compute the
+ interpretations of the expression only at the end of the analysis,
+ but skip doing it if it is the operand of a type conversion.
+ (Analyze_If_Expression): Likewise.
+ * sem_res.adb (Resolve): Deal specially with conditional
+ expression that is the operand of a type conversion.
+ (Resolve_Dependent_Expression): New procedure.
+ (Resolve_Case_Expression): Call Resolve_Dependent_Expression.
+ (Resolve_If_Expression): Likewise.
+ (Resolve_If_Expression.Apply_Check): Take result type as
+ parameter.
+ (Resolve_Type_Conversion): Do not warn about a redundant
+ conversion when the operand is a conditional expression.
+
+2022-11-08 Javier Miranda <miranda@adacore.com>
+
+ * debug.adb
+ (Debug_Flag_Underscore_XX): Switch -gnatd_X used temporarily to allow
+ disabling extra formal checks.
+ * exp_attr.adb
+ (Expand_N_Attribute_Reference [access types]): Add extra formals
+ to the subprogram referenced in the prefix of 'Unchecked_Access,
+ 'Unrestricted_Access or 'Access; required to check that its extra
+ formals match the extra formals of the corresponding subprogram type.
+ * exp_ch3.adb
+ (Stream_Operation_OK): Declaration moved to the public part of the
+ package.
+ (Validate_Tagged_Type_Extra_Formals): New subprogram.
+ (Expand_Freeze_Record_Type): Improve the code that takes care of
+ adding the extra formals of dispatching primitives; extended to
+ add also the extra formals to renamings of dispatching primitives.
+ * exp_ch3.ads
+ (Stream_Operation_OK): Declaration moved from the package body.
+ * exp_ch6.adb
+ (Check_BIP_Actuals): Complete documentation.
+ (Has_BIP_Extra_Formal): Subprogram declaration moved to the public
+ part of the package. In addition, a parameter has been added to
+ disable an assertion that requires its use with frozen entities.
+ (Duplicate_Params_Without_Extra_Actuals): New subprogram.
+ (Check_Subprogram_Variant): Emit the call without duplicating the
+ extra formals since they will be added when the call is analyzed.
+ (Expand_Call_Helper): Ensure that the called subprogram has all its
+ extra formals, enforce assertion checking extra formals on thunks,
+ and mark calls from thunks as processed-BIP-calls to avoid adding
+ their extra formals twice.
+ (Is_Build_In_Place_Function): Return False for entities with foreign
+ convention.
+ (Is_Build_In_Place_Function_Call): Return True also for not BIP functions
+ that have BIP formals since the extra actuals are required.
+ (Make_Build_In_Place_Call_In_Object_Declaration): Occurrences of
+ Is_Return_Object replaced by the local variable Is_OK_Return_Object
+ that evaluates to False for scopes with foreign convention.
+ (Might_Have_Tasks): Fix check of class-wide limited record types.
+ (Needs_BIP_Task_Actuals): Remove assertion to allow calling this
+ function in more contexts; in addition it returns False for functions
+ returning objects with foreign convention.
+ (Needs_BIP_Finalization_Master): Likewise.
+ (Needs_BIP_Alloc_Form): Likewise.
+ (Validate_Subprogram_Calls): Check that the number of actuals (including
+ extra actuals) of calls in the subtree N match their corresponding
+ formals.
+ * exp_ch6.ads
+ (Has_BIP_Extra_Formal): Subprogram declaration moved to the public
+ part of the package. In addition, a parameter has been added to
+ disable an assertion that requires its use with frozen entities.
+ (Is_Build_In_Place_Function_Call): Complete documentation.
+ (Validate_Subprogram_Calls): Check that the number of actuals (including
+ extra actuals) of calls in the subtree N match their corresponding
+ formals.
+ * freeze.adb
+ (Check_Itype): Add extra formals to anonymous access subprogram itypes.
+ (Freeze_Expression): Improve code that disables the addition of extra
+ formals to functions with foreign convention.
+ (Check_Extra_Formals): Moved to package Sem_Ch6 as Extra_Formals_OK.
+ (Freeze_Subprogram): Add extra formals to non-dispatching subprograms.
+ * frontend.adb
+ (Frontend): Validate all the subprogram calls; it can be disabled using
+ switch -gnatd_X
+ * sem_ch3.adb
+ (Access_Subprogram_Declaration): Defer the addition of extra formals to
+ the freezing point so that we know the convention.
+ (Check_Anonymous_Access_Component): Likewise.
+ (Derive_Subprogram): Fix documentation.
+ * sem_ch6.adb
+ (Has_Reliable_Extra_Formals): New subprogram.
+ (Check_Anonymous_Return): Fix check of access to class-wide limited
+ record types.
+ (Check_Untagged_Equality): Placed in alphabetical order.
+ (Extra_Formals_OK): Subprogram moved from freeze.adb.
+ (Extra_Formals_Match_OK): New subprogram.
+ (Has_BIP_Formals): New subprogram.
+ (Has_Extra_Formals): New subprograms.
+ (Needs_Accessibility_Check_Extra): New subprogram.
+ (Parent_Subprogram): New subprogram.
+ (Add_Extra_Formal): Minor code cleanup.
+ (Create_Extra_Formals): Enforce matching extra formals on overridden
+ and aliased entities.
+ * sem_ch6.ads
+ (Extra_Formals_Match_OK): New subprogram.
+ (Extra_Formals_OK): Subprogram moved from freeze.adb.
+ * sem_eval.adb
+ (Compile_Time_Known_Value): Improve predicate to avoid assertion
+ failure; found working on this ticket; this change does not
+ affect the behavior of the compiler because this subprogram
+ has an exception handler that returns False when the assertion
+ fails.
+ * sem_util.adb
+ (Needs_Result_Accessibility_Level): Do not return False for dispatching
+ operations compiled with Ada_Version < 2012 since they they may be
+ overridden by primitives compiled with Ada_Version >= Ada_2012.
+
+2022-11-08 Bob Duff <duff@adacore.com>
+
+ * warnsw.ads, warnsw.adb, fe.h, err_vars.ads, errout.ads: Move
+ Warning_Doc_Switch from Err_Vars to Warnsw. Access
+ Warn_On_Questionable_Layout on the C side via a function rather
+ than a variable, because we plan to turn the variables into
+ renamings, and you can't Export renamings.
+ * erroutc.adb, switch-c.adb, errout.adb: Likewise.
+ * gcc-interface/decl.cc: Use Get_Warn_On_Questionable_Layout
+ instead of Warn_On_Questionable_Layout.
+ * gcc-interface/Makefile.in (GNATMAKE_OBJS): Add warnsw.o, because
+ it is indirectly imported via Errout.
+ * gcc-interface/Make-lang.in (GNATBIND_OBJS): Likewise and remove
+ restrict.o (not needed).
+
+2022-11-08 Ronan Desplanques <desplanques@adacore.com>
+
+ * doc/gnat_ugn/building_executable_programs_with_gnat.rst
+ (-gnatwc): Fix flag documentation.
+ * gnat_ugn.texi: Regenerate.
+
+2022-11-08 Steve Baird <baird@adacore.com>
+
+ * sem_ch3.adb
+ (Analyze_Object_Declaration): Do not perform expansion actions if
+ In_Spec_Expression is true.
+
+2022-11-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch4.adb (Analyze_Qualified_Expression): Analyze the
+ expression only after setting the type.
+ (Analyze_Unchecked_Type_Conversion): Likewise.
+ (Analyze_Short_Circuit): Likewise for the operands.
+ (Analyze_Type_Conversion): Minor tweaks.
+ (Analyze_Unchecked_Expression): Likewise.
+
+2022-11-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch4.adb (Analyze_Qualified_Expression): Remove redundant
+ line.
+
+2022-11-08 Ronan Desplanques <desplanques@adacore.com>
+
+ * contracts.adb (Preanalyze_Condition): Use
+ Preanalyze_Spec_Expression.
+
+2022-11-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_imgv.adb
+ (Expand_Wide_Image_Attribute): Handle just like attribute Image.
+ (Expand_Wide_Wide_Image_Attribute): Likewise.
+ * exp_put_image.adb
+ (Build_Image_Call): Adapt to also work for Wide and Wide_Wide
+ attributes.
+ * exp_put_image.ads
+ (Build_Image_Call): Update comment.
+ * rtsfind.ads
+ (RE_Id): Support wide variants of Get.
+ (RE_Unit_Table): Likewise.
+
+2022-11-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * libgnat/a-ngcoar.ads, libgnat/a-ngcoar.adb: Remove extra spaces.
+
+2022-11-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch12.adb (Validate_Formal_Type_Default): Remove call to
+ Collect_Interfaces, which had no effect apart from populating a
+ list that was not used; fix style.
+
+2022-11-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_spark.adb (SPARK_Freeze_Type): Refine type of a local
+ object.
+ * sem_ch3.adb (Derive_Subprograms): Remove initial value for
+ New_Subp, which is in only written as an out parameter and never
+ read.
+
+2022-11-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_res.adb (Resolve_If_Expression): Remove obsolete special
+ case.
+
+2022-11-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_aggr.adb (Resolve_Delta_Aggregate): Implement rules related
+ to limited objects appearing as the base expression.
+
+2022-11-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch3.adb (OK_For_Limited_Init_In_05): Handle delta aggregates
+ just like other aggregates.
+
+2022-11-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_aggr.adb (Resolve_Delta_Record_Aggregate): Reject
+ expressions of a limited types.
+
+2022-11-08 Javier Miranda <miranda@adacore.com>
+
+ * exp_ch9.adb
+ (Build_Master_Entity): Handle missing case: when the context of
+ the master is a BIP function whose result type has tasks.
+
+2022-11-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * libgnat/a-tags.adb
+ (Interface_Ancestor_Tags): Raise Tag_Error on No_Tag.
+ (Is_Descendant_At_Same_Level): Likewise.
+
+2022-11-08 Bob Duff <duff@adacore.com>
+
+ * usage.adb: Add -gnatw_q and -gnatw_Q.
+
+2022-11-07 Cedric Landet <landet@adacore.com>
+
+ * doc/gnat_ugn/gnat_and_program_execution.rst: Mention the needed
+ -no-pie for windows to use gprof.
+ * gnat_ugn.texi: Regenerate.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * lib-xref.adb (Hash): Tune hash function.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_prag.adb (Non_Significant_Pragma_Reference): Detect
+ references with aggregates; only assign local variables Id and C
+ when necessary.
+
+2022-11-07 Bob Duff <duff@adacore.com>
+
+ * exp_ch4.adb
+ (Component_Equality, Expand_Array_Equality)
+ (Expand_Record_Equality): Use named notation.
+
+2022-11-07 Bob Duff <duff@adacore.com>
+
+ * exp_ch4.adb
+ (Expand_Array_Equality): Do not test Ltyp = Rtyp here, because
+ that is necessarily true. Move assertion thereof to more general
+ place.
+ (Expand_Composite_Equality): Pass in Outer_Type, for use in
+ warnings. Rename Typ to be Comp_Type, to more clearly distinguish
+ it from Outer_Type. Print warning when appropriate.
+ * exp_ch4.ads: Minor comment fix.
+ * errout.ads: There is no such pragma as Warning_As_Pragma --
+ Warning_As_Error must have been intended. Improve comment for ?x?.
+ * exp_ch3.adb
+ (Build_Untagged_Equality): Update comment to be accurate for more
+ recent versions of Ada.
+ * sem_case.adb
+ (Choice_Analysis): Declare user-defined "=" functions as abstract.
+ * sem_util.ads
+ (Is_Bounded_String): Give RM reference in comment.
+ * warnsw.ads, warnsw.adb
+ (Warn_On_Ignored_Equality): Implement new warning switch -gnatw_q.
+ * doc/gnat_ugn/building_executable_programs_with_gnat.rst:
+ Document new warning switch.
+ * gnat_ugn.texi: Regenerate.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_aux.ads (Is_Body): Annotate with Inline.
+ * sem_util.ads (Is_Body_Or_Package_Declaration): Likewise.
+
+2022-11-07 Bob Duff <duff@adacore.com>
+
+ * freeze.adb
+ (Build_Inherited_Condition_Pragmas): Do nothing if A_Post is
+ empty.
+
+2022-11-07 Quentin Ochem <ochem@adacore.com>
+ Steve Baird <baird@adacore.com>
+
+ * bindgen.adb: fixed the way the device init and final symbols are
+ computed, re-using the normal way these symbols would be computed
+ with a __device_ prefix. Also fixed the "is null;" procedure on
+ the host side which are not Ada 95, replaced with a procedure
+ raising an exception as it should never be called. Remove the
+ unused function Device_Ada_Final_Link_Name.
+
+2022-11-07 Steve Baird <baird@adacore.com>
+
+ * opt.ads: Declare new string pointer variable, CUDA_Device_Library_Name.
+ Modify comments for existing Boolean variable Enable_CUDA_Device_Expansion.
+ * switch-b.adb: When "-d_c" switch is encountered, check that the next
+ character is an "'='; use the remaining characters to initialize
+ Opt.CUDA_Device_Library_Name.
+ * bindgen.adb: Remove (for now) most support for host-side invocation of
+ device-side finalization. Make use of the new CUDA_Device_Library_Name
+ in determining the string used to refer (on the host side) to the
+ device-side initialization procedure. Declare the placeholder routine
+ that is named in the CUDA_Execute pragma (and the CUDA_Register_Function
+ call) as an exported null procedure, rather than as an imported procedure.
+ It is not clear whether it is really necessary to specify the link-name
+ for this should-never-be-called subprogram on the host side, but for now it
+ shouldn't hurt to do so.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_ch6.adb (Expand_Protected_Subprogram_Call): Examine scope
+ tree and not the scope stack.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * mdll.ads (Build_Import_Library): Fix grammar in comment.
+ * mdll.adb (Build_Import_Library): Directly execute code of a
+ nested routine; rename No_Lib_Prefix to Strip_Lib_Prefix.
+
+2022-11-07 Bob Duff <duff@adacore.com>
+
+ * sem_warn.adb
+ (Check_For_Warnings): Remove unnecessary exception handler.
+ (Warn_On_Known_Condition): Suppress warning when we detect a True
+ or False that has been turned into a more complex expression
+ because True is represented as "nonzero". (Note that the complex
+ expression will subsequently be constant-folded to a Boolean True
+ or False). Also simplify to always print "condition is always ..."
+ instead of special-casing object names. The special case was
+ unhelpful, and indeed wrong when the expression is a literal.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * checks.adb (Safe_To_Capture_In_Parameter_Value): Remove.
+ * sem_util.adb (Safe_To_Capture_Value): Stop search at the current
+ body.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_warn.adb (Warn_On_In_Out): Remove No_ prefix; flip return
+ values between True and False; adapt caller.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch13.adb (Add_Call): Just look at Instantiation_Depth.
+ * sem_ch3.adb (Derive_Subprograms): Likewise.
+ * sem_warn.adb (Check_References): Remove redundant filtering with
+ Instantiation_Depth that follows filtering with
+ Instantiation_Location.
+ * sinput.adb (Instantiation_Depth): Reuse Instantiation_Location.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_warn.adb
+ (No_Warn_On_In_Out): For subprograms we can simply call
+ Warnings_Off.
+ (Output_Non_Modified_In_Out_Warnings): Remove repeated
+ suppression.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_aggr.adb (Resolve_Delta_Array_Aggregate): Reject boxes in
+ delta array aggregates.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_res.adb (Enclosing_Declaration_Or_Statement): Moved to
+ Sem_Util.
+ * sem_util.ads (Enclosing_Declaration_Or_Statement): Moved from
+ Sem_Res.
+ * sem_util.adb (Enclosing_Declaration_Or_Statement): Likewise.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_res.adb (Resolve): Only call Comes_From_Predefined_Lib_Unit
+ when its result might be needed.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch12.adb (Check_Generic_Actuals): Remove redundant parens;
+ refactor an excessive if-statement; remove repeated call to Node.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * inline.adb (Establish_Actual_Mapping_For_Inlined_Call): Move
+ comment next to a condition that it describes.
+
+2022-11-07 Steve Baird <baird@adacore.com>
+
+ * exp_put_image.adb
+ (Image_Should_Call_Put_Image): Correctly handle the case of an
+ inherited Put_Image aspect specification for a scalar type.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * libgnarl/s-interr.adb: Tune whitespace.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * libgnarl/s-interr.adb: Reorder context items and pragmas.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_ch4.adb
+ (Expand_Modular_Addition): Rewrite using Make_XXX calls.
+ (Expand_Modular_Op): Likewise.
+ (Expand_Modular_Subtraction): Likewise.
+ * exp_imgv.adb
+ (Expand_User_Defined_Enumeration_Image): Likewise.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * checks.adb (Apply_Arithmetic_Overflow_Strict): Rewrite using a
+ newly created operator node.
+ * exp_ch4.adb (Expand_Array_Comparison): Likewise.
+ * exp_ch6.adb (Add_Call_By_Copy_Code): Rewriting actual parameter
+ using its own location and not the location of the subprogram
+ call.
+ * sem_warn.adb (Check_References): Looping with Original_Node is
+ no longer needed.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_prag.adb (Is_In_Context_Clause): Rewrite without negations
+ and inequalities.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_prag.adb (Analyze_Pragma [Pragma_Obsolescent]): Reject
+ misplaced pragma.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_warn.adb (Output_Obsolescent_Entity_Warnings): Tag warnings
+ about obsolescent functions just like we tag similar warnings for
+ packages and procedures.
+
+2022-11-07 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_attr.adb (Expand_N_Attribute_Reference): Remove useless
+ skipping for attribute Input.
+
+2022-11-04 Justin Squirek <squirek@adacore.com>
+
+ * exp_attr.adb (Expand_N_Attribute_Reference): Skip operand
+ validity checks for attributes Has_Same_Storage and
+ Overlaps_Storage.
+
+2022-11-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * errout.adb (Remove_Warning_Messages.Check_For_Warning): Do not
+ reinstate the Original_Node in the tree.
+ * exp_aggr.adb (Build_Array_Aggr_Code.Gen_Loop): Copy the bounds
+ on all paths.
+
+2022-11-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * libgnat/g-excact.ads
+ (Register_Global_Action): Refill comment.
+ (Name_To_Id): Change pragma Restriction from singular to plural.
+
+2022-11-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_warn.adb (Check_References): Remove redundant guard, as it
+ is implied by a preceding call to Referenced_Check_Spec.
+
+2022-11-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_warn.adb (Check_References): Remove useless query for "spec"
+ of a variable; refactor nested if-statements into a single
+ condition.
+
+2022-11-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_util.adb
+ (In_Pragma_Expression): Add standard guard against searching too
+ far.
+ (In_Quantified_Expression): Likewise.
+ * sem_warn.adb
+ (May_Need_Initialized_Actual): Remove redundant parens.
+ (Check_References): Remove guard that duplicates a condition from
+ the enclosing if-statement; only assign E1T variable when
+ necessary.
+ (Within_Postcondition): Fix layout.
+ (No_Warn_On_In_Out): Balance parens in comment.
+
+2022-11-04 Steve Baird <baird@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_pragmas.rst: Add the standard
+ '... "On" enables this extension.' sentence to the description of
+ static intrinsic functions.
+ * sem_ch13.adb
+ (Analyze_Aspect_Spec): In the call to Error_Msg_GNAT_Extension for
+ a Static aspect specification for an intrinsic function, specify
+ Is_Core_Extension => True.
+ * sem_eval.adb
+ (Eval_Intrinsic_Call): Test Core_Extensions_Allowed instead of
+ testing All_Extensions_Allowed.
+ * gnat_rm.texi: Regenerate.
+
+2022-11-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * aspects.adb (Relocate_Aspect): Remove call to Set_Has_Aspects.
+ * sem_ch12.adb (Analyze_Formal_Package_Declaration): Likewise.
+ * sem_util.adb (Copy_Ghost_Aspect, Copy_SPARK_Mode_Aspect):
+ Likewise.
+
+2022-11-04 Javier Miranda <miranda@adacore.com>
+
+ * exp_intr.adb
+ (Expand_Dispatching_Constructor_Call): Report an error on
+ unsupported dispatching constructor calls and report a warning on
+ calls that may fail at run time.
+
+2022-11-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_util.adb
+ (Check_Components): Iterate using
+ First/Next_Component_Or_Discriminant.
+ (Has_Preelaborable_Initialization): Avoid repeated iteration with
+ calls to Check_Components with First_Entity and
+ First_Private_Entity.
+ (Is_Independent_Object_Entity): Tune indentation.
+
+2022-11-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch7.adb (Clear_Constants): Only iterate from First_Entity
+ through Next_Entity; only examine variables because packages have
+ no assignable formal parameters.
+
+2022-11-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * doc/gnat_ugn/building_executable_programs_with_gnat.rst: Fix
+ typos.
+ * doc/gnat_ugn/elaboration_order_handling_in_gnat.rst: Fix typos
+ and refill as necessary; remove trailing whitespace.
+ * doc/gnat_ugn/gnat_and_program_execution.rst: Fix typos.
+ * gnat_ugn.texi: Regenerate.
+
+2022-11-04 Marc Poulhiès <poulhies@adacore.com>
+
+ * sem_util.ads (Add_Block_Identifier): Add new extra Scope
+ argument.
+ * sem_util.adb (Add_Block_Identifier): Likewise and use this scope
+ variable instead of Current_Scope.
+ * exp_util.adb (Wrap_Statements_In_Block): Add new scope argument
+ to Add_Block_Identifier call.
+
+2022-11-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_util.adb (Kill_Current_Values): Only iterate from
+ First_Entity through Next_Entity.
+
+2022-11-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch6.adb (Controlling_Formal): Iterate with First/Next_Formal
+ and not with First/Next_Entity.
+
+2022-11-04 Javier Miranda <miranda@adacore.com>
+
+ * exp_disp.adb
+ (Expand_Interface_Conversion): Fix typo in comment.
+
+2022-11-04 Javier Miranda <miranda@adacore.com>
+
+ * exp_disp.adb
+ (Expand_Interface_Conversion): Under configurable runtime, when
+ the target type is an interface that is an ancestor of the operand
+ type, skip generating code to displace the pointer to reference
+ the target dispatch table.
+ * sem_disp.adb
+ (Propagate_Tag): Handle class-wide types when checking for the
+ addition of an implicit interface conversion.
+
+2022-11-04 Ronan Desplanques <desplanques@adacore.com>
+
+ * doc/gnat_rm/standard_library_routines.rst: Fix typo.
+ * gnat_rm.texi: Regenerate.
+
+2022-11-04 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * sa_messages.ads, sa_messages.adb: Remove files.
+
+2022-11-04 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * checks.adb, exp_atag.adb, exp_attr.adb, exp_ch4.adb, exp_ch6.adb,
+ exp_ch7.adb, exp_dbug.adb, exp_disp.adb, exp_unst.adb, exp_util.adb,
+ freeze.adb, layout.adb, pprint.adb, rtsfind.adb, sem_aggr.adb,
+ sem_attr.adb, sem_case.adb, sem_ch12.adb, sem_ch13.adb, sem_ch3.adb,
+ sem_ch5.adb, sem_ch6.adb, sem_ch8.adb, sem_dim.adb, sem_prag.adb,
+ sem_util.adb, sem_warn.adb:
+ Replace uses of `not Present (X)` with `No (X)`.
+
+2022-11-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * einfo.ads: Fix typos in comments; refill as necessary.
+ * sinfo.ads: Likewise.
+
+2022-11-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_aspects.rst: Fix typos.
+ * doc/gnat_rm/implementation_defined_attributes.rst: Likewise
+ * doc/gnat_rm/implementation_defined_characteristics.rst: Likewise
+ * doc/gnat_rm/implementation_defined_pragmas.rst: Likewise
+ * doc/gnat_rm/standard_library_routines.rst: Likewise.
+ * gnat_rm.texi: Regenerate.
+
+2022-11-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch8.adb (Restore_Scope_Stack): Remove elements from the head
+ and not the tail of an element list.
+
+2022-11-04 Ronan Desplanques <desplanques@adacore.com>
+
+ * sinfo.ads: Small editorial changes.
+
+2022-11-04 Steve Baird <baird@adacore.com>
+
+ * opt.ads: Replace Ada_Version_Type enumeration literal
+ Ada_With_Extensions with two literals, Ada_With_Core_Extensions
+ and Ada_With_All_Extensions. Update uses of the deleted literal.
+ Replace Extensions_Allowed function with two functions:
+ All_Extensions_Allowed and Core_Extensions_Allowed.
+ * errout.ads, errout.adb: Add Boolean parameter to
+ Error_Msg_GNAT_Extension to indicate whether the construct in
+ question belongs to the curated subset.
+ * exp_ch5.adb, par-ch4.adb, sem_case.adb, sem_ch3.adb:
+ * sem_ch4.adb, sem_ch5.adb, sem_ch8.adb: Replace calls to
+ Extensions_Allowed with calls to Core_Extensions_Allowed for
+ constructs that are in the curated subset.
+ * sem_attr.adb, sem_ch13.adb, sem_eval.adb, sem_util.adb: Replace
+ calls to Extensions_Allowed with calls to All_Extensions_Allowed
+ for constructs that are not in the curated subset.
+ * par-ch3.adb: Override default for new parameter in calls to
+ Error_Msg_GNAT_Extension for constructs in the curated subset.
+ * par-prag.adb: Add Boolean parameter to Check_Arg_Is_On_Or_Off to
+ also allow ALL. Set Opt.Ada_Version appropriately for ALL or ON
+ arguments.
+ * sem_prag.adb: Allowed ALL argument for an Extensions_Allowed
+ pragma. Set Opt.Ada_Version appropriately for ALL or ON arguments.
+ * switch-c.adb: The -gnatX switch now enables only the curated
+ subset of language extensions (formerly it enabled all of them);
+ the new -gnatX0 switch enables all of them.
+ * doc/gnat_ugn/building_executable_programs_with_gnat.rst:
+ Document new "-gnatX0" switch and update documentation for
+ "-gnatX" switch.
+ * doc/gnat_rm/implementation_defined_pragmas.rst: Document new ALL
+ argument for pragma Extensions_Allowed and update documentation
+ for the ON argument. Delete mention of Ada 2022 Reduce attribute
+ as an extension.
+ * gnat_rm.texi, gnat_ugn.texi: Regenerate.
+
+2022-11-04 Steve Baird <baird@adacore.com>
+
+ * bindgen.adb: Introduce two new string constants for the names of
+ the C-String variables that are assigned the names for adainit and
+ adafinal. Replace string literals in Gen_CUDA_Init with references
+ to these constants. In Gen_CUDA_Defs, generate C-String variable
+ declarations where these constants are the names of the variables.
+
+2022-11-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch9.adb (Satisfies_Lock_Free_Requirements): Ignore
+ references to global variables inserted due to pragma
+ Initialize_Scalars.
+
+2022-11-04 Cedric Landet <landet@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_pragmas.rst: Remove VxWorks
+ version 6.
+ * gnat_rm.texi, gnat_ugn.texi: Regenerate.
+
+2022-11-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch9.adb (Satisfies_Lock_Free_Requirements): Detect
+ references via expanded names.
+
+2022-11-04 Steve Baird <baird@adacore.com>
+
+ * bindgen.adb
+ (Gen_CUDA_Init): Move existing loop body into a new local
+ procedure, Gen_CUDA_Register_Function_Call, and replace that loop
+ body with a call to this procedure. This first part is just
+ semantics-preserving refactoring. The second part is to add
+ Gen_CUDA_Register_Function_Call calls after the loop for the
+ device-side adainit and adafinal procedures.
+
2022-10-11 Eric Botcazou <ebotcazou@adacore.com>
* libgnat/system-linux-sparc.ads (Support_Atomic_Primitives): New
@@ -1213,7 +2590,7 @@
2022-09-05 Martin Liska <mliska@suse.cz>
* sigtramp-vxworks-target.h: Rename DBX_REGISTER_NUMBER to
- DEBUGGER_REGNO.
+ DEBUGGER_REGNO.
2022-09-05 Piotr Trojanek <trojanek@adacore.com>
diff --git a/gcc/ada/accessibility.adb b/gcc/ada/accessibility.adb
new file mode 100644
index 0000000..3162806
--- /dev/null
+++ b/gcc/ada/accessibility.adb
@@ -0,0 +1,2305 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- A C C E S S I B I L I T Y --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2022-2022, 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. See the GNU General Public License --
+-- for more details. You should have received a copy of the GNU General --
+-- Public License distributed with GNAT; see file COPYING3. If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Atree; use Atree;
+with Checks; use Checks;
+with Debug; use Debug;
+with Einfo; use Einfo;
+with Einfo.Entities; use Einfo.Entities;
+with Elists; use Elists;
+with Errout; use Errout;
+with Einfo.Utils; use Einfo.Utils;
+with Exp_Atag; use Exp_Atag;
+with Exp_Ch3; use Exp_Ch3;
+with Exp_Ch7; use Exp_Ch7;
+with Exp_Tss; use Exp_Tss;
+with Exp_Util; use Exp_Util;
+with Namet; use Namet;
+with Nlists; use Nlists;
+with Nmake; use Nmake;
+with Opt; use Opt;
+with Restrict; use Restrict;
+with Rtsfind; use Rtsfind;
+with Sem; use Sem;
+with Sem_Aux; use Sem_Aux;
+with Sem_Ch8; use Sem_Ch8;
+with Sem_Res; use Sem_Res;
+with Sem_Util; use Sem_Util;
+with Sinfo; use Sinfo;
+with Sinfo.Nodes; use Sinfo.Nodes;
+with Sinfo.Utils; use Sinfo.Utils;
+with Snames; use Snames;
+with Stand; use Stand;
+with Tbuild; use Tbuild;
+
+package body Accessibility is
+
+ ---------------------------
+ -- Accessibility_Message --
+ ---------------------------
+
+ procedure Accessibility_Message (N : Node_Id; Typ : Entity_Id) is
+ Loc : constant Source_Ptr := Sloc (N);
+ P : constant Node_Id := Prefix (N);
+ Indic : Node_Id := Parent (Parent (N));
+
+ begin
+ -- In an instance, this is a runtime check, but one we know will fail,
+ -- so generate an appropriate warning.
+
+ if In_Instance_Body then
+ Error_Msg_Warn := SPARK_Mode /= On;
+ Error_Msg_F
+ ("non-local pointer cannot point to local object<<", P);
+ Error_Msg_F ("\Program_Error [<<", P);
+ Rewrite (N,
+ Make_Raise_Program_Error (Loc,
+ Reason => PE_Accessibility_Check_Failed));
+ Set_Etype (N, Typ);
+ return;
+
+ else
+ Error_Msg_F ("non-local pointer cannot point to local object", P);
+
+ -- Check for case where we have a missing access definition
+
+ if Is_Record_Type (Current_Scope)
+ and then
+ Nkind (Parent (N)) in N_Discriminant_Association
+ | N_Index_Or_Discriminant_Constraint
+ then
+ Indic := Parent (Parent (N));
+ while Present (Indic)
+ and then Nkind (Indic) /= N_Subtype_Indication
+ loop
+ Indic := Parent (Indic);
+ end loop;
+
+ if Present (Indic) then
+ Error_Msg_NE
+ ("\use an access definition for" &
+ " the access discriminant of&",
+ N, Entity (Subtype_Mark (Indic)));
+ end if;
+ end if;
+ end if;
+ end Accessibility_Message;
+
+ -------------------------
+ -- Accessibility_Level --
+ -------------------------
+
+ function Accessibility_Level
+ (Expr : Node_Id;
+ Level : Accessibility_Level_Kind;
+ In_Return_Context : Boolean := False;
+ Allow_Alt_Model : Boolean := True) return Node_Id
+ is
+ Loc : constant Source_Ptr := Sloc (Expr);
+
+ function Accessibility_Level (Expr : Node_Id) return Node_Id
+ is (Accessibility_Level (Expr, Level, In_Return_Context));
+ -- Renaming of the enclosing function to facilitate recursive calls
+
+ function Make_Level_Literal (Level : Uint) return Node_Id;
+ -- Construct an integer literal representing an accessibility level with
+ -- its type set to Natural.
+
+ function Innermost_Master_Scope_Depth (N : Node_Id) return Uint;
+ -- Returns the scope depth of the given node's innermost enclosing scope
+ -- (effectively the accessibility level of the innermost enclosing
+ -- master).
+
+ function Function_Call_Or_Allocator_Level (N : Node_Id) return Node_Id;
+ -- 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 --
+ ----------------------------------
+
+ function Innermost_Master_Scope_Depth (N : Node_Id) return Uint is
+ Encl_Scop : Entity_Id;
+ Ent : Entity_Id;
+ Node_Par : Node_Id := Parent (N);
+ Master_Lvl_Modifier : Int := 0;
+
+ begin
+ -- Locate the nearest enclosing node (by traversing Parents)
+ -- that Defining_Entity can be applied to, and return the
+ -- depth of that entity's nearest enclosing scope.
+
+ -- The RM 7.6.1(3) definition of "master" includes statements
+ -- and conditions for loops among other things. Are these cases
+ -- detected properly ???
+
+ while Present (Node_Par) loop
+ Ent := Defining_Entity_Or_Empty (Node_Par);
+
+ if Present (Ent) then
+ Encl_Scop := Find_Enclosing_Scope (Ent);
+
+ -- Ignore transient scopes made during expansion while also
+ -- taking into account certain expansions - like iterators
+ -- which get expanded into renamings and thus not marked
+ -- as coming from source.
+
+ if Comes_From_Source (Node_Par)
+ or else (Nkind (Node_Par) = N_Object_Renaming_Declaration
+ and then Comes_From_Iterator (Node_Par))
+ then
+ -- Note that in some rare cases the scope depth may not be
+ -- set, for example, when we are in the middle of analyzing
+ -- a type and the enclosing scope is said type. So, instead,
+ -- continue to move up the parent chain since the scope
+ -- depth of the type's parent is the same as that of the
+ -- type.
+
+ if not Scope_Depth_Set (Encl_Scop) then
+ pragma Assert (Nkind (Parent (Encl_Scop))
+ = N_Full_Type_Declaration);
+ else
+ return
+ Scope_Depth (Encl_Scop) + Master_Lvl_Modifier;
+ end if;
+ end if;
+
+ -- For a return statement within a function, return
+ -- the depth of the function itself. This is not just
+ -- a small optimization, but matters when analyzing
+ -- the expression in an expression function before
+ -- the body is created.
+
+ elsif Nkind (Node_Par) in N_Extended_Return_Statement
+ | N_Simple_Return_Statement
+ then
+ return Scope_Depth (Enclosing_Subprogram (Node_Par));
+
+ -- Statements are counted as masters
+
+ elsif Is_Master (Node_Par) then
+ Master_Lvl_Modifier := Master_Lvl_Modifier + 1;
+
+ end if;
+
+ Node_Par := Parent (Node_Par);
+ end loop;
+
+ -- Should never reach the following return
+
+ pragma Assert (False);
+
+ return Scope_Depth (Current_Scope) + 1;
+ end Innermost_Master_Scope_Depth;
+
+ ------------------------
+ -- Make_Level_Literal --
+ ------------------------
+
+ function Make_Level_Literal (Level : Uint) return Node_Id is
+ Result : constant Node_Id := Make_Integer_Literal (Loc, Level);
+
+ begin
+ Set_Etype (Result, Standard_Natural);
+ return Result;
+ end Make_Level_Literal;
+
+ --------------------------------------
+ -- Function_Call_Or_Allocator_Level --
+ --------------------------------------
+
+ function Function_Call_Or_Allocator_Level (N : Node_Id) return Node_Id is
+ Par : Node_Id;
+ Prev_Par : Node_Id;
+ begin
+ -- Results of functions are objects, so we either get the
+ -- accessibility of the function or, in case of a call which is
+ -- indirect, the level of the access-to-subprogram type.
+
+ -- This code looks wrong ???
+
+ if Nkind (N) = N_Function_Call
+ and then Ada_Version < Ada_2005
+ then
+ if Is_Entity_Name (Name (N)) then
+ return Make_Level_Literal
+ (Subprogram_Access_Level (Entity (Name (N))));
+ else
+ return Make_Level_Literal
+ (Typ_Access_Level (Etype (Prefix (Name (N)))));
+ end if;
+
+ -- We ignore coextensions as they cannot be implemented under the
+ -- "small-integer" model.
+
+ elsif Nkind (N) = N_Allocator
+ and then (Is_Static_Coextension (N)
+ or else Is_Dynamic_Coextension (N))
+ then
+ return Make_Level_Literal (Scope_Depth (Standard_Standard));
+ end if;
+
+ -- Named access types have a designated level
+
+ if Is_Named_Access_Type (Etype (N)) then
+ 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)));
+
+ -- For function calls the level is that of the innermost
+ -- master, otherwise (for allocators etc.) we get the level
+ -- of the corresponding anonymous access type, which is
+ -- calculated through the normal path of execution.
+
+ elsif Nkind (N) = N_Function_Call then
+ return Make_Level_Literal
+ (Innermost_Master_Scope_Depth (Expr));
+ 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 accessibility level of the
+ -- enclosing subprogram.
+
+ if In_Return_Value (N)
+ or else In_Return_Context
+ then
+ return Make_Level_Literal
+ (Subprogram_Access_Level (Current_Subprogram));
+ 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.
+
+ -- Note: The above is only relevant if the result is used "in its
+ -- entirety" as RM 3.10.2 (10.2/3) states. However, this is
+ -- accounted for in the case statement in the main body of
+ -- Accessibility_Level for N_Selected_Component.
+
+ Par := Parent (Expr);
+ Prev_Par := Empty;
+ while Present (Par) loop
+ -- Detect an expanded implicit conversion, typically this
+ -- occurs on implicitly converted actuals in calls.
+
+ -- Does this catch all implicit conversions ???
+
+ if Nkind (Par) = N_Type_Conversion
+ and then Is_Named_Access_Type (Etype (Par))
+ then
+ return Make_Level_Literal
+ (Typ_Access_Level (Etype (Par)));
+ end if;
+
+ -- Jump out when we hit an object declaration or the right-hand
+ -- side of an assignment, or a construct such as an aggregate
+ -- subtype indication which would be the result is not used
+ -- "in its entirety."
+
+ exit when Nkind (Par) in N_Object_Declaration
+ or else (Nkind (Par) = N_Assignment_Statement
+ and then Name (Par) /= Prev_Par);
+
+ Prev_Par := Par;
+ Par := Parent (Par);
+ end loop;
+
+ -- Assignment statements are handled in a similar way in
+ -- accordance to the left-hand part. However, strictly speaking,
+ -- this is illegal according to the RM, but this change is needed
+ -- to pass an ACATS C-test and is useful in general ???
+
+ case Nkind (Par) is
+ when N_Object_Declaration =>
+ return Make_Level_Literal
+ (Scope_Depth
+ (Scope (Defining_Identifier (Par))));
+
+ when N_Assignment_Statement =>
+ -- Return the accessibility level of the left-hand part
+
+ return Accessibility_Level
+ (Expr => Name (Par),
+ Level => Object_Decl_Level,
+ In_Return_Context => In_Return_Context);
+
+ when others =>
+ return Make_Level_Literal
+ (Innermost_Master_Scope_Depth (Expr));
+ end case;
+ end if;
+ end Function_Call_Or_Allocator_Level;
+
+ -- Local variables
+
+ E : Node_Id := Original_Node (Expr);
+ Pre : Node_Id;
+
+ -- Start of processing for Accessibility_Level
+
+ begin
+ -- We could be looking at a reference to a formal due to the expansion
+ -- of entries and other cases, so obtain the renaming if necessary.
+
+ if Present (Param_Entity (Expr)) then
+ E := Param_Entity (Expr);
+ end if;
+
+ -- Extract the entity
+
+ if Nkind (E) in N_Has_Entity and then Present (Entity (E)) then
+ E := Entity (E);
+
+ -- Deal with a possible renaming of a private protected component
+
+ if Ekind (E) in E_Constant | E_Variable and then Is_Prival (E) then
+ E := Prival_Link (E);
+ end if;
+ end if;
+
+ -- Perform the processing on the expression
+
+ case Nkind (E) is
+ -- The level of an aggregate is that of the innermost master that
+ -- evaluates it as defined in RM 3.10.2 (10/4).
+
+ when N_Aggregate =>
+ return Make_Level_Literal (Innermost_Master_Scope_Depth (Expr));
+
+ -- The accessibility level is that of the access type, except for an
+ -- anonymous allocators which have special rules defined in RM 3.10.2
+ -- (14/3).
+
+ when N_Allocator =>
+ return Function_Call_Or_Allocator_Level (E);
+
+ -- We could reach this point for two reasons. Either the expression
+ -- applies to a special attribute ('Loop_Entry, 'Result, or 'Old), or
+ -- we are looking at the access attributes directly ('Access,
+ -- 'Address, or 'Unchecked_Access).
+
+ when N_Attribute_Reference =>
+ Pre := Original_Node (Prefix (E));
+
+ -- Regular 'Access attribute presence means we have to look at the
+ -- prefix.
+
+ if Attribute_Name (E) = Name_Access then
+ return Accessibility_Level (Prefix (E));
+
+ -- Unchecked or unrestricted attributes have unlimited depth
+
+ elsif Attribute_Name (E) in Name_Address
+ | Name_Unchecked_Access
+ | Name_Unrestricted_Access
+ then
+ return Make_Level_Literal (Scope_Depth (Standard_Standard));
+
+ -- 'Access can be taken further against other special attributes,
+ -- so handle these cases explicitly.
+
+ elsif Attribute_Name (E)
+ in Name_Old | Name_Loop_Entry | Name_Result
+ then
+ -- Named access types
+
+ if Is_Named_Access_Type (Etype (Pre)) then
+ return Make_Level_Literal
+ (Typ_Access_Level (Etype (Pre)));
+
+ -- Anonymous access types
+
+ elsif Nkind (Pre) in N_Has_Entity
+ and then Ekind (Entity (Pre)) not in Subprogram_Kind
+ and then Present (Get_Dynamic_Accessibility (Entity (Pre)))
+ and then Level = Dynamic_Level
+ then
+ return New_Occurrence_Of
+ (Get_Dynamic_Accessibility (Entity (Pre)), Loc);
+
+ -- Otherwise the level is treated in a similar way as
+ -- aggregates according to RM 6.1.1 (35.1/4) which concerns
+ -- an implicit constant declaration - in turn defining the
+ -- accessibility level to be that of the implicit constant
+ -- declaration.
+
+ else
+ return Make_Level_Literal
+ (Innermost_Master_Scope_Depth (Expr));
+ end if;
+
+ else
+ raise Program_Error;
+ end if;
+
+ -- This is the "base case" for accessibility level calculations which
+ -- means we are near the end of our recursive traversal.
+
+ when N_Defining_Identifier =>
+ -- A dynamic check is performed on the side of the callee when we
+ -- are within a return statement, so return a library-level
+ -- accessibility level to null out checks on the side of the
+ -- caller.
+
+ if Is_Explicitly_Aliased (E)
+ and then (In_Return_Context
+ or else (Level /= Dynamic_Level
+ and then In_Return_Value (Expr)))
+ then
+ return Make_Level_Literal (Scope_Depth (Standard_Standard));
+
+ -- Something went wrong and an extra accessibility formal has not
+ -- been generated when one should have ???
+
+ elsif Is_Formal (E)
+ and then No (Get_Dynamic_Accessibility (E))
+ and then Ekind (Etype (E)) = E_Anonymous_Access_Type
+ then
+ return Make_Level_Literal (Scope_Depth (Standard_Standard));
+
+ -- Stand-alone object of an anonymous access type "SAOAAT"
+
+ elsif (Is_Formal (E)
+ or else Ekind (E) in E_Variable
+ | E_Constant)
+ and then Present (Get_Dynamic_Accessibility (E))
+ and then (Level = Dynamic_Level
+ or else Level = Zero_On_Dynamic_Level)
+ then
+ if Level = Zero_On_Dynamic_Level then
+ return Make_Level_Literal
+ (Scope_Depth (Standard_Standard));
+ end if;
+
+ -- 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 accessibility
+ -- parameter associated with the level at which the object
+ -- being initialized exists
+
+ elsif Ekind (E) = E_Record_Type
+ and then Is_Limited_Record (E)
+ and then Current_Scope = Init_Proc (E)
+ and then Present (Init_Proc_Level_Formal (Current_Scope))
+ then
+ return New_Occurrence_Of
+ (Init_Proc_Level_Formal (Current_Scope), Loc);
+
+ -- Current instance of the type is deeper than that of the type
+ -- according to RM 3.10.2 (21).
+
+ elsif Is_Type (E) then
+ -- 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 or object if it came from source
+ -- since expansion may have created a dummy renaming under
+ -- certain circumstances.
+
+ -- Note: We check if the original node of the renaming comes
+ -- from source because the node may have been rewritten.
+
+ elsif Present (Renamed_Entity_Or_Object (E))
+ and then Comes_From_Source
+ (Original_Node (Renamed_Entity_Or_Object (E)))
+ then
+ return Accessibility_Level (Renamed_Entity_Or_Object (E));
+
+ -- Named access types get their level from their associated type
+
+ elsif Is_Named_Access_Type (Etype (E)) then
+ return Make_Level_Literal
+ (Typ_Access_Level (Etype (E)));
+
+ -- Check if E is an expansion-generated renaming of an iterator
+ -- by examining Related_Expression. If so, determine the
+ -- accessibility level based on the original expression.
+
+ elsif Ekind (E) in E_Constant | E_Variable
+ and then Present (Related_Expression (E))
+ then
+ return Accessibility_Level (Related_Expression (E));
+
+ elsif Level = Dynamic_Level
+ and then Ekind (E) in E_In_Parameter | E_In_Out_Parameter
+ and then Present (Init_Proc_Level_Formal (Scope (E)))
+ then
+ return New_Occurrence_Of
+ (Init_Proc_Level_Formal (Scope (E)), Loc);
+
+ -- Normal object - get the level of the enclosing scope
+
+ else
+ return Make_Level_Literal
+ (Scope_Depth (Enclosing_Dynamic_Scope (E)));
+ end if;
+
+ -- Handle indexed and selected components including the special cases
+ -- whereby there is an implicit dereference, a component of a
+ -- composite type, or a function call in prefix notation.
+
+ -- We don't handle function calls in prefix notation correctly ???
+
+ when N_Indexed_Component | N_Selected_Component | N_Slice =>
+ Pre := Prefix (E);
+
+ -- Fetch the original node when the prefix comes from the result
+ -- of expanding a function call since we want to find the level
+ -- of the original source call.
+
+ if not Comes_From_Source (Pre)
+ and then Nkind (Original_Node (Pre)) = N_Function_Call
+ then
+ Pre := Original_Node (Pre);
+ end if;
+
+ -- When E is an indexed component or selected component and
+ -- the current Expr is a function call, we know that we are
+ -- looking at an expanded call in prefix notation.
+
+ if Nkind (Expr) = N_Function_Call then
+ return Function_Call_Or_Allocator_Level (Expr);
+
+ -- If the prefix is a named access type, then we are dealing
+ -- with an implicit deferences. In that case the level is that
+ -- of the named access type in the prefix.
+
+ elsif Is_Named_Access_Type (Etype (Pre)) then
+ return Make_Level_Literal
+ (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
+ -- named access type.
+
+ elsif Is_Named_Access_Type (Etype (E)) then
+ return Make_Level_Literal
+ (Typ_Access_Level (Etype (E)));
+
+ -- 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)
+
+ -- The alternative accessibility models both treat
+ -- discriminants as regular components.
+
+ or else (No_Dynamic_Accessibility_Checks_Enabled (E)
+ and then Allow_Alt_Model)))
+
+ -- Arrays featuring components of anonymous access components
+ -- get their corresponding level from their containing type's
+ -- declaration.
+
+ or else
+ (Nkind (E) = N_Indexed_Component
+ and then Ekind (Etype (E)) = E_Anonymous_Access_Type
+ and then Ekind (Etype (Pre)) in Array_Kind
+ 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
+ (Typ_Access_Level (Etype (Prefix (E))));
+
+ -- The accessibility calculation routine that handles function
+ -- calls (Function_Call_Level) assumes, in the case the
+ -- result is of an anonymous access type, that the result will be
+ -- used "in its entirety" when the call is present within an
+ -- assignment or object declaration.
+
+ -- To properly handle cases where the result is not used in its
+ -- entirety, we test if the prefix of the component in question is
+ -- a function call, which tells us that one of its components has
+ -- been identified and is being accessed. Therefore we can
+ -- conclude that the result is not used "in its entirety"
+ -- according to RM 3.10.2 (10.2/3).
+
+ elsif Nkind (Pre) = N_Function_Call
+ and then not Is_Named_Access_Type (Etype (Pre))
+ 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 a library accessibility level to
+ -- null out the check on the side of the caller.
+
+ if (In_Return_Value (E)
+ or else In_Return_Context)
+ and then Level /= Dynamic_Level
+ then
+ return Make_Level_Literal
+ (Scope_Depth (Standard_Standard));
+ end if;
+
+ return Make_Level_Literal
+ (Innermost_Master_Scope_Depth (Expr));
+
+ -- Otherwise, continue recursing over the expression prefixes
+
+ else
+ return Accessibility_Level (Prefix (E));
+ end if;
+
+ -- Qualified expressions
+
+ when N_Qualified_Expression =>
+ if Is_Named_Access_Type (Etype (E)) then
+ return Make_Level_Literal
+ (Typ_Access_Level (Etype (E)));
+ else
+ return Accessibility_Level (Expression (E));
+ end if;
+
+ -- Handle function calls
+
+ when N_Function_Call =>
+ return Function_Call_Or_Allocator_Level (E);
+
+ -- Explicit dereference accessibility level calculation
+
+ when N_Explicit_Dereference =>
+ Pre := Original_Node (Prefix (E));
+
+ -- The prefix is a named access type so the level is taken from
+ -- its type.
+
+ if Is_Named_Access_Type (Etype (Pre)) then
+ return Make_Level_Literal (Typ_Access_Level (Etype (Pre)));
+
+ -- Otherwise, recurse deeper
+
+ else
+ return Accessibility_Level (Prefix (E));
+ end if;
+
+ -- Type conversions
+
+ when N_Type_Conversion | N_Unchecked_Type_Conversion =>
+ -- View conversions are special in that they require use to
+ -- inspect the expression of the type conversion.
+
+ -- Allocators of anonymous access types are internally generated,
+ -- so recurse deeper in that case as well.
+
+ if Is_View_Conversion (E)
+ or else Ekind (Etype (E)) = E_Anonymous_Access_Type
+ then
+ return Accessibility_Level (Expression (E));
+
+ -- We don't care about the master if we are looking at a named
+ -- access type.
+
+ elsif Is_Named_Access_Type (Etype (E)) then
+ return Make_Level_Literal
+ (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
+ -- followed in the case of initialization of an object ???
+
+ -- Should use Innermost_Master_Scope_Depth ???
+
+ else
+ return Accessibility_Level (Current_Scope);
+ end if;
+
+ -- Default to the type accessibility level for the type of the
+ -- expression's entity.
+
+ when others =>
+ return Make_Level_Literal (Typ_Access_Level (Etype (E)));
+ end case;
+ end Accessibility_Level;
+
+ -------------------------------
+ -- Apply_Accessibility_Check --
+ -------------------------------
+
+ procedure Apply_Accessibility_Check
+ (N : Node_Id;
+ Typ : Entity_Id;
+ Insert_Node : Node_Id)
+ is
+ Loc : constant Source_Ptr := Sloc (N);
+
+ Check_Cond : Node_Id;
+ Param_Ent : Entity_Id := Param_Entity (N);
+ Param_Level : Node_Id;
+ 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 No (Param_Ent)
+ and then Is_Entity_Name (N)
+ and then Ekind (Entity (N)) in E_Constant | E_Variable
+ and then Present (Effective_Extra_Accessibility (Entity (N)))
+ then
+ Param_Ent := Entity (N);
+ while Present (Renamed_Object (Param_Ent)) loop
+ -- Renamed_Object must return an Entity_Name here
+ -- because of preceding "Present (E_E_A (...))" test.
+
+ Param_Ent := Entity (Renamed_Object (Param_Ent));
+ end loop;
+ end if;
+
+ if Inside_A_Generic then
+ return;
+
+ -- Only apply the run-time check if the access parameter has an
+ -- associated extra access level parameter and when accessibility checks
+ -- are enabled.
+
+ elsif Present (Param_Ent)
+ and then Present (Get_Dynamic_Accessibility (Param_Ent))
+ and then not Accessibility_Checks_Suppressed (Param_Ent)
+ and then not Accessibility_Checks_Suppressed (Typ)
+ then
+ -- Obtain the parameter's accessibility level
+
+ Param_Level :=
+ New_Occurrence_Of (Get_Dynamic_Accessibility (Param_Ent), Loc);
+
+ -- Use the dynamic accessibility parameter for the function's result
+ -- when one has been created instead of statically referring to the
+ -- deepest type level so as to appropriatly handle the rules for
+ -- RM 3.10.2 (10.1/3).
+
+ if Ekind (Scope (Param_Ent)) = E_Function
+ and then In_Return_Value (N)
+ and then Ekind (Typ) = E_Anonymous_Access_Type
+ then
+ -- Associate the level of the result type to the extra result
+ -- accessibility parameter belonging to the current function.
+
+ if Present (Extra_Accessibility_Of_Result (Scope (Param_Ent))) then
+ Type_Level :=
+ New_Occurrence_Of
+ (Extra_Accessibility_Of_Result (Scope (Param_Ent)), Loc);
+
+ -- In Ada 2005 and earlier modes, a result extra accessibility
+ -- parameter is not generated and no dynamic check is performed.
+
+ else
+ return;
+ end if;
+
+ -- Otherwise get the type's accessibility level normally
+
+ else
+ Type_Level :=
+ Make_Integer_Literal (Loc, Deepest_Type_Access_Level (Typ));
+ end if;
+
+ -- Raise Program_Error if the accessibility level of the access
+ -- parameter is deeper than the level of the target access type.
+
+ Check_Cond :=
+ Make_Op_Gt (Loc,
+ Left_Opnd => Param_Level,
+ Right_Opnd => Type_Level);
+
+ Insert_Action (Insert_Node,
+ Make_Raise_Program_Error (Loc,
+ Condition => Check_Cond,
+ Reason => PE_Accessibility_Check_Failed));
+
+ Analyze_And_Resolve (N);
+
+ -- If constant folding has happened on the condition for the
+ -- generated error, then warn about it being unconditional.
+
+ if Nkind (Check_Cond) = N_Identifier
+ and then Entity (Check_Cond) = Standard_True
+ then
+ Error_Msg_Warn := SPARK_Mode /= On;
+ Error_Msg_N ("accessibility check fails<<", N);
+ Error_Msg_N ("\Program_Error [<<", N);
+ end if;
+ end if;
+ end Apply_Accessibility_Check;
+
+ ---------------------------------------------
+ -- Apply_Accessibility_Check_For_Allocator --
+ ---------------------------------------------
+
+ procedure Apply_Accessibility_Check_For_Allocator
+ (N : Node_Id;
+ Exp : Node_Id;
+ Ref : Node_Id;
+ Built_In_Place : Boolean := False)
+ is
+ Loc : constant Source_Ptr := Sloc (N);
+ PtrT : constant Entity_Id := Etype (N);
+ DesigT : constant Entity_Id := Designated_Type (PtrT);
+ Pool_Id : constant Entity_Id := Associated_Storage_Pool (PtrT);
+ Cond : Node_Id;
+ Fin_Call : Node_Id;
+ Free_Stmt : Node_Id;
+ Obj_Ref : Node_Id;
+ Stmts : List_Id;
+
+ begin
+ if Ada_Version >= Ada_2005
+ 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
+ (Is_Class_Wide_Type (Etype (Exp))
+ and then Scope (PtrT) /= Current_Scope))
+ then
+ -- If the allocator was built in place, Ref is already a reference
+ -- to the access object initialized to the result of the allocator
+ -- (see Exp_Ch6.Make_Build_In_Place_Call_In_Allocator). We call
+ -- Remove_Side_Effects for cases where the build-in-place call may
+ -- still be the prefix of the reference (to avoid generating
+ -- duplicate calls). Otherwise, it is the entity associated with
+ -- the object containing the address of the allocated object.
+
+ if Built_In_Place then
+ Remove_Side_Effects (Ref);
+ Obj_Ref := New_Copy_Tree (Ref);
+ else
+ Obj_Ref := New_Occurrence_Of (Ref, Loc);
+ end if;
+
+ -- For access to interface types we must generate code to displace
+ -- the pointer to the base of the object since the subsequent code
+ -- references components located in the TSD of the object (which
+ -- is associated with the primary dispatch table --see a-tags.ads)
+ -- and also generates code invoking Free, which requires also a
+ -- reference to the base of the unallocated object.
+
+ if Is_Interface (DesigT) and then Tagged_Type_Expansion then
+ Obj_Ref :=
+ Unchecked_Convert_To (Etype (Obj_Ref),
+ Make_Function_Call (Loc,
+ Name =>
+ New_Occurrence_Of (RTE (RE_Base_Address), Loc),
+ Parameter_Associations => New_List (
+ Unchecked_Convert_To (RTE (RE_Address),
+ New_Copy_Tree (Obj_Ref)))));
+ end if;
+
+ -- Step 1: Create the object clean up code
+
+ Stmts := New_List;
+
+ -- Deallocate the object if the accessibility check fails. This is
+ -- done only on targets or profiles that support deallocation.
+
+ -- Free (Obj_Ref);
+
+ if RTE_Available (RE_Free) then
+ Free_Stmt := Make_Free_Statement (Loc, New_Copy_Tree (Obj_Ref));
+ Set_Storage_Pool (Free_Stmt, Pool_Id);
+
+ Append_To (Stmts, Free_Stmt);
+
+ -- The target or profile cannot deallocate objects
+
+ else
+ Free_Stmt := Empty;
+ end if;
+
+ -- Finalize the object if applicable. Generate:
+
+ -- [Deep_]Finalize (Obj_Ref.all);
+
+ if Needs_Finalization (DesigT)
+ and then not No_Heap_Finalization (PtrT)
+ then
+ Fin_Call :=
+ Make_Final_Call
+ (Obj_Ref =>
+ Make_Explicit_Dereference (Loc, New_Copy (Obj_Ref)),
+ Typ => DesigT);
+
+ -- Guard against a missing [Deep_]Finalize when the designated
+ -- type was not properly frozen.
+
+ if No (Fin_Call) then
+ Fin_Call := Make_Null_Statement (Loc);
+ end if;
+
+ -- When the target or profile supports deallocation, wrap the
+ -- finalization call in a block to ensure proper deallocation even
+ -- if finalization fails. Generate:
+
+ -- begin
+ -- <Fin_Call>
+ -- exception
+ -- when others =>
+ -- <Free_Stmt>
+ -- raise;
+ -- end;
+
+ if Present (Free_Stmt) then
+ Fin_Call :=
+ Make_Block_Statement (Loc,
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_List (Fin_Call),
+
+ Exception_Handlers => New_List (
+ Make_Exception_Handler (Loc,
+ Exception_Choices => New_List (
+ Make_Others_Choice (Loc)),
+ Statements => New_List (
+ New_Copy_Tree (Free_Stmt),
+ Make_Raise_Statement (Loc))))));
+ end if;
+
+ Prepend_To (Stmts, Fin_Call);
+ end if;
+
+ -- Signal the accessibility failure through a Program_Error
+
+ Append_To (Stmts,
+ Make_Raise_Program_Error (Loc,
+ Reason => PE_Accessibility_Check_Failed));
+
+ -- Step 2: Create the accessibility comparison
+
+ -- Generate:
+ -- Ref'Tag
+
+ Obj_Ref :=
+ Make_Attribute_Reference (Loc,
+ Prefix => Obj_Ref,
+ Attribute_Name => Name_Tag);
+
+ -- For tagged types, determine the accessibility level by looking at
+ -- the type specific data of the dispatch table. Generate:
+
+ -- Type_Specific_Data (Address (Ref'Tag)).Access_Level
+
+ if Tagged_Type_Expansion then
+ Cond := Build_Get_Access_Level (Loc, Obj_Ref);
+
+ -- Use a runtime call to determine the accessibility level when
+ -- compiling on virtual machine targets. Generate:
+
+ -- Get_Access_Level (Ref'Tag)
+
+ else
+ Cond :=
+ Make_Function_Call (Loc,
+ Name =>
+ New_Occurrence_Of (RTE (RE_Get_Access_Level), Loc),
+ Parameter_Associations => New_List (Obj_Ref));
+ end if;
+
+ Cond :=
+ Make_Op_Gt (Loc,
+ Left_Opnd => Cond,
+ Right_Opnd => Accessibility_Level (N, Dynamic_Level));
+
+ -- Due to the complexity and side effects of the check, utilize an if
+ -- statement instead of the regular Program_Error circuitry.
+
+ Insert_Action (N,
+ Make_Implicit_If_Statement (N,
+ Condition => Cond,
+ Then_Statements => Stmts));
+ end if;
+ end Apply_Accessibility_Check_For_Allocator;
+
+ ------------------------------------------
+ -- Check_Return_Construct_Accessibility --
+ ------------------------------------------
+
+ procedure Check_Return_Construct_Accessibility
+ (Return_Stmt : Node_Id;
+ Stm_Entity : Entity_Id)
+ is
+ Loc : constant Source_Ptr := Sloc (Return_Stmt);
+ Scope_Id : constant Entity_Id := Return_Applies_To (Stm_Entity);
+
+ R_Type : constant Entity_Id := Etype (Scope_Id);
+ -- Function result subtype
+
+ function First_Selector (Assoc : Node_Id) return Node_Id;
+ -- Obtain the first selector or choice from a given association
+
+ function Is_Formal_Of_Current_Function
+ (Assoc_Expr : Entity_Id) return Boolean;
+ -- Predicate to test if a given expression associated with a
+ -- discriminant is a formal parameter to the function in which the
+ -- return construct we checking applies to.
+
+ --------------------
+ -- First_Selector --
+ --------------------
+
+ function First_Selector (Assoc : Node_Id) return Node_Id is
+ begin
+ if Nkind (Assoc) = N_Component_Association then
+ return First (Choices (Assoc));
+
+ elsif Nkind (Assoc) = N_Discriminant_Association then
+ return (First (Selector_Names (Assoc)));
+
+ else
+ raise Program_Error;
+ end if;
+ end First_Selector;
+
+ -----------------------------------
+ -- Is_Formal_Of_Current_Function --
+ -----------------------------------
+
+ function Is_Formal_Of_Current_Function
+ (Assoc_Expr : Entity_Id) return Boolean is
+ begin
+ return Is_Entity_Name (Assoc_Expr)
+ and then Enclosing_Subprogram
+ (Entity (Assoc_Expr)) = Scope_Id
+ and then Is_Formal (Entity (Assoc_Expr));
+ end Is_Formal_Of_Current_Function;
+
+ -- Local declarations
+
+ Assoc : Node_Id := Empty;
+ -- Assoc should perhaps be renamed and declared as a
+ -- Node_Or_Entity_Id since it encompasses not only component and
+ -- discriminant associations, but also discriminant components within
+ -- a type declaration or subtype indication ???
+
+ Assoc_Expr : Node_Id;
+ Assoc_Present : Boolean := False;
+
+ Check_Cond : Node_Id;
+ Unseen_Disc_Count : Nat := 0;
+ Seen_Discs : Elist_Id;
+ Disc : Entity_Id;
+ First_Disc : Entity_Id;
+
+ Obj_Decl : Node_Id;
+ Return_Con : Node_Id;
+ Unqual : Node_Id;
+
+ -- Start of processing for Check_Return_Construct_Accessibility
+
+ begin
+ -- Only perform checks on record types with access discriminants and
+ -- non-internally generated functions.
+
+ if not Is_Record_Type (R_Type)
+ or else not Has_Anonymous_Access_Discriminant (R_Type)
+ or else not Comes_From_Source (Return_Stmt)
+ then
+ return;
+ end if;
+
+ -- We are only interested in return statements
+
+ if Nkind (Return_Stmt) not in
+ N_Extended_Return_Statement | N_Simple_Return_Statement
+ then
+ return;
+ end if;
+
+ -- Fetch the object from the return statement, in the case of a
+ -- simple return statement the expression is part of the node.
+
+ if Nkind (Return_Stmt) = N_Extended_Return_Statement then
+ -- Obtain the object definition from the expanded extended return
+
+ Return_Con := First (Return_Object_Declarations (Return_Stmt));
+ while Present (Return_Con) loop
+ -- Inspect the original node to avoid object declarations
+ -- expanded into renamings.
+
+ if Nkind (Original_Node (Return_Con)) = N_Object_Declaration
+ and then Comes_From_Source (Original_Node (Return_Con))
+ then
+ exit;
+ end if;
+
+ Nlists.Next (Return_Con);
+ end loop;
+
+ pragma Assert (Present (Return_Con));
+
+ -- Could be dealing with a renaming
+
+ Return_Con := Original_Node (Return_Con);
+ else
+ Return_Con := Expression (Return_Stmt);
+ end if;
+
+ -- Obtain the accessibility levels of the expressions associated
+ -- with all anonymous access discriminants, then generate a
+ -- dynamic check or static error when relevant.
+
+ -- Note the repeated use of Original_Node to avoid checking
+ -- expanded code.
+
+ Unqual := Original_Node (Unqualify (Original_Node (Return_Con)));
+
+ -- Get the corresponding declaration based on the return object's
+ -- identifier.
+
+ if Nkind (Unqual) = N_Identifier
+ and then Nkind (Parent (Entity (Unqual)))
+ in N_Object_Declaration
+ | N_Object_Renaming_Declaration
+ then
+ Obj_Decl := Original_Node (Parent (Entity (Unqual)));
+
+ -- We were passed the object declaration directly, so use it
+
+ elsif Nkind (Unqual) in N_Object_Declaration
+ | N_Object_Renaming_Declaration
+ then
+ Obj_Decl := Unqual;
+
+ -- Otherwise, we are looking at something else
+
+ else
+ Obj_Decl := Empty;
+
+ end if;
+
+ -- Hop up object renamings when present
+
+ if Present (Obj_Decl)
+ and then Nkind (Obj_Decl) = N_Object_Renaming_Declaration
+ then
+ while Nkind (Obj_Decl) = N_Object_Renaming_Declaration loop
+
+ if Nkind (Name (Obj_Decl)) not in N_Entity then
+ -- We may be looking at the expansion of iterators or
+ -- some other internally generated construct, so it is safe
+ -- to ignore checks ???
+
+ if not Comes_From_Source (Obj_Decl) then
+ return;
+ end if;
+
+ Obj_Decl := Original_Node
+ (Declaration_Node
+ (Ultimate_Prefix (Name (Obj_Decl))));
+
+ -- Move up to the next declaration based on the object's name
+
+ else
+ Obj_Decl := Original_Node
+ (Declaration_Node (Name (Obj_Decl)));
+ end if;
+ end loop;
+ end if;
+
+ -- Obtain the discriminant values from the return aggregate
+
+ -- Do we cover extension aggregates correctly ???
+
+ if Nkind (Unqual) = N_Aggregate then
+ if Present (Expressions (Unqual)) then
+ Assoc := First (Expressions (Unqual));
+ else
+ Assoc := First (Component_Associations (Unqual));
+ end if;
+
+ -- There is an object declaration for the return object
+
+ elsif Present (Obj_Decl) then
+ -- When a subtype indication is present in an object declaration
+ -- it must contain the object's discriminants.
+
+ if Nkind (Object_Definition (Obj_Decl)) = N_Subtype_Indication then
+ Assoc := First
+ (Constraints
+ (Constraint
+ (Object_Definition (Obj_Decl))));
+
+ -- The object declaration contains an aggregate
+
+ elsif Present (Expression (Obj_Decl)) then
+
+ if Nkind (Unqualify (Expression (Obj_Decl))) = N_Aggregate then
+ -- Grab the first associated discriminant expresion
+
+ if Present
+ (Expressions (Unqualify (Expression (Obj_Decl))))
+ then
+ Assoc := First
+ (Expressions
+ (Unqualify (Expression (Obj_Decl))));
+ else
+ Assoc := First
+ (Component_Associations
+ (Unqualify (Expression (Obj_Decl))));
+ end if;
+
+ -- Otherwise, this is something else
+
+ else
+ return;
+ end if;
+
+ -- There are no supplied discriminants in the object declaration,
+ -- so get them from the type definition since they must be default
+ -- initialized.
+
+ -- Do we handle constrained subtypes correctly ???
+
+ elsif Nkind (Unqual) = N_Object_Declaration then
+ Assoc := First_Discriminant
+ (Etype (Object_Definition (Obj_Decl)));
+
+ else
+ Assoc := First_Discriminant (Etype (Unqual));
+ end if;
+
+ -- When we are not looking at an aggregate or an identifier, return
+ -- since any other construct (like a function call) is not
+ -- applicable since checks will be performed on the side of the
+ -- callee.
+
+ else
+ return;
+ end if;
+
+ -- Obtain the discriminants so we know the actual type in case the
+ -- value of their associated expression gets implicitly converted.
+
+ if No (Obj_Decl) then
+ pragma Assert (Nkind (Unqual) = N_Aggregate);
+
+ Disc := First_Discriminant (Etype (Unqual));
+
+ else
+ Disc := First_Discriminant
+ (Etype (Defining_Identifier (Obj_Decl)));
+ end if;
+
+ -- Preserve the first discriminant for checking named associations
+
+ First_Disc := Disc;
+
+ -- Count the number of discriminants for processing an aggregate
+ -- which includes an others.
+
+ Disc := First_Disc;
+ while Present (Disc) loop
+ Unseen_Disc_Count := Unseen_Disc_Count + 1;
+
+ Next_Discriminant (Disc);
+ end loop;
+
+ Seen_Discs := New_Elmt_List;
+
+ -- Loop through each of the discriminants and check each expression
+ -- associated with an anonymous access discriminant.
+
+ -- When named associations occur in the return aggregate then
+ -- discriminants can be in any order, so we need to ensure we do
+ -- not continue to loop when all discriminants have been seen.
+
+ Disc := First_Disc;
+ while Present (Assoc)
+ and then (Present (Disc) or else Assoc_Present)
+ and then Unseen_Disc_Count > 0
+ loop
+ -- Handle named associations by searching through the names of
+ -- the relevant discriminant components.
+
+ if Nkind (Assoc)
+ in N_Component_Association | N_Discriminant_Association
+ then
+ Assoc_Expr := Expression (Assoc);
+ Assoc_Present := True;
+
+ -- We currently don't handle box initialized discriminants,
+ -- however, since default initialized anonymous access
+ -- discriminants are a corner case, this is ok for now ???
+
+ if Nkind (Assoc) = N_Component_Association
+ and then Box_Present (Assoc)
+ then
+ if Nkind (First_Selector (Assoc)) = N_Others_Choice then
+ Unseen_Disc_Count := 0;
+ end if;
+
+ -- When others is present we must identify a discriminant we
+ -- haven't already seen so as to get the appropriate type for
+ -- the static accessibility check.
+
+ -- This works because all components within an others clause
+ -- must have the same type.
+
+ elsif Nkind (First_Selector (Assoc)) = N_Others_Choice then
+
+ Disc := First_Disc;
+ Outer : while Present (Disc) loop
+ declare
+ Current_Seen_Disc : Elmt_Id;
+ begin
+ -- Move through the list of identified discriminants
+
+ Current_Seen_Disc := First_Elmt (Seen_Discs);
+ while Present (Current_Seen_Disc) loop
+ -- Exit the loop when we found a match
+
+ exit when
+ Chars (Node (Current_Seen_Disc)) = Chars (Disc);
+
+ Next_Elmt (Current_Seen_Disc);
+ end loop;
+
+ -- When we have exited the above loop without finding
+ -- a match then we know that Disc has not been seen.
+
+ exit Outer when No (Current_Seen_Disc);
+ end;
+
+ Next_Discriminant (Disc);
+ end loop Outer;
+
+ -- If we got to an others clause with a non-zero
+ -- discriminant count there must be a discriminant left to
+ -- check.
+
+ pragma Assert (Present (Disc));
+
+ -- Set the unseen discriminant count to zero because we know
+ -- an others clause sets all remaining components of an
+ -- aggregate.
+
+ Unseen_Disc_Count := 0;
+
+ -- Move through each of the selectors in the named association
+ -- and obtain a discriminant for accessibility checking if one
+ -- is referenced in the list. Also track which discriminants
+ -- are referenced for the purpose of handling an others clause.
+
+ else
+ declare
+ Assoc_Choice : Node_Id;
+ Curr_Disc : Node_Id;
+ begin
+
+ Disc := Empty;
+ Curr_Disc := First_Disc;
+ while Present (Curr_Disc) loop
+ -- Check each of the choices in the associations for a
+ -- match to the name of the current discriminant.
+
+ Assoc_Choice := First_Selector (Assoc);
+ while Present (Assoc_Choice) loop
+ -- When the name matches we track that we have seen
+ -- the discriminant, but instead of exiting the
+ -- loop we continue iterating to make sure all the
+ -- discriminants within the named association get
+ -- tracked.
+
+ if Chars (Assoc_Choice) = Chars (Curr_Disc) then
+ Append_Elmt (Curr_Disc, Seen_Discs);
+
+ Disc := Curr_Disc;
+ Unseen_Disc_Count := Unseen_Disc_Count - 1;
+ end if;
+
+ Next (Assoc_Choice);
+ end loop;
+
+ Next_Discriminant (Curr_Disc);
+ end loop;
+ end;
+ end if;
+
+ -- Unwrap the associated expression if we are looking at a default
+ -- initialized type declaration. In this case Assoc is not really
+ -- an association, but a component declaration. Should Assoc be
+ -- renamed in some way to be more clear ???
+
+ -- This occurs when the return object does not initialize
+ -- discriminant and instead relies on the type declaration for
+ -- their supplied values.
+
+ elsif Nkind (Assoc) in N_Entity
+ and then Ekind (Assoc) = E_Discriminant
+ then
+ Append_Elmt (Disc, Seen_Discs);
+
+ Assoc_Expr := Discriminant_Default_Value (Assoc);
+ Unseen_Disc_Count := Unseen_Disc_Count - 1;
+
+ -- Otherwise, there is nothing to do because Assoc is an
+ -- expression within the return aggregate itself.
+
+ else
+ Append_Elmt (Disc, Seen_Discs);
+
+ Assoc_Expr := Assoc;
+ Unseen_Disc_Count := Unseen_Disc_Count - 1;
+ end if;
+
+ -- Check the accessibility level of the expression when the
+ -- discriminant is of an anonymous access type.
+
+ if Present (Assoc_Expr)
+ and then Present (Disc)
+ and then Ekind (Etype (Disc)) = E_Anonymous_Access_Type
+
+ -- We disable the check when we have a tagged return type and
+ -- the associated expression for the discriminant is a formal
+ -- parameter since the check would require us to compare the
+ -- accessibility level of Assoc_Expr to the level of the
+ -- Extra_Accessibility_Of_Result of the function - which is
+ -- currently disabled for functions with tagged return types.
+ -- This may change in the future ???
+
+ -- See Needs_Result_Accessibility_Level for details.
+
+ and then not
+ (No (Extra_Accessibility_Of_Result (Scope_Id))
+ and then Is_Formal_Of_Current_Function (Assoc_Expr)
+ and then Is_Tagged_Type (Etype (Scope_Id)))
+ then
+ -- Generate a dynamic check based on the extra accessibility of
+ -- the result or the scope of the current function.
+
+ Check_Cond :=
+ Make_Op_Gt (Loc,
+ Left_Opnd => Accessibility_Level
+ (Expr => Assoc_Expr,
+ Level => Dynamic_Level,
+ In_Return_Context => True),
+ Right_Opnd =>
+ (if Present (Extra_Accessibility_Of_Result (Scope_Id))
+
+ -- When Assoc_Expr is a formal we have to look at the
+ -- extra accessibility-level formal associated with
+ -- the result.
+
+ and then Is_Formal_Of_Current_Function (Assoc_Expr)
+ then
+ New_Occurrence_Of
+ (Extra_Accessibility_Of_Result (Scope_Id), Loc)
+
+ -- Otherwise, we compare the level of Assoc_Expr to the
+ -- scope of the current function.
+
+ else
+ Make_Integer_Literal
+ (Loc, Scope_Depth (Scope (Scope_Id)))));
+
+ Insert_Before_And_Analyze (Return_Stmt,
+ Make_Raise_Program_Error (Loc,
+ Condition => Check_Cond,
+ Reason => PE_Accessibility_Check_Failed));
+
+ -- If constant folding has happened on the condition for the
+ -- generated error, then warn about it being unconditional when
+ -- we know an error will be raised.
+
+ if Nkind (Check_Cond) = N_Identifier
+ and then Entity (Check_Cond) = Standard_True
+ then
+ Error_Msg_N
+ ("access discriminant in return object would be a dangling"
+ & " reference", Return_Stmt);
+ end if;
+ end if;
+
+ -- Iterate over the discriminants, except when we have encountered
+ -- a named association since the discriminant order becomes
+ -- irrelevant in that case.
+
+ if not Assoc_Present then
+ Next_Discriminant (Disc);
+ end if;
+
+ -- Iterate over associations
+
+ if not Is_List_Member (Assoc) then
+ exit;
+ else
+ Nlists.Next (Assoc);
+ end if;
+ end loop;
+ end Check_Return_Construct_Accessibility;
+
+ -------------------------------
+ -- Deepest_Type_Access_Level --
+ -------------------------------
+
+ 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.
+
+ return
+ Scope_Depth (Enclosing_Dynamic_Scope
+ (Defining_Identifier
+ (Associated_Node_For_Itype (Typ))));
+
+ -- For generic formal type, return Int'Last (infinite).
+ -- See comment preceding Is_Generic_Type call in Type_Access_Level.
+
+ elsif Is_Generic_Type (Root_Type (Typ)) then
+ return UI_From_Int (Int'Last);
+
+ else
+ return Type_Access_Level (Typ, Allow_Alt_Model);
+ end if;
+ end Deepest_Type_Access_Level;
+
+ -----------------------------------
+ -- Effective_Extra_Accessibility --
+ -----------------------------------
+
+ function Effective_Extra_Accessibility (Id : Entity_Id) return Entity_Id is
+ begin
+ if Present (Renamed_Object (Id))
+ and then Is_Entity_Name (Renamed_Object (Id))
+ then
+ return Effective_Extra_Accessibility (Entity (Renamed_Object (Id)));
+ else
+ return Extra_Accessibility (Id);
+ end if;
+ end Effective_Extra_Accessibility;
+
+ -------------------------------
+ -- Get_Dynamic_Accessibility --
+ -------------------------------
+
+ function Get_Dynamic_Accessibility (E : Entity_Id) return Entity_Id is
+ begin
+ -- When minimum accessibility is set for E then we utilize it - except
+ -- in a few edge cases like the expansion of select statements where
+ -- generated subprogram may attempt to unnecessarily use a minimum
+ -- accessibility object declared outside of scope.
+
+ -- To avoid these situations where expansion may get complex we verify
+ -- that the minimum accessibility object is within scope.
+
+ if Is_Formal (E)
+ and then Present (Minimum_Accessibility (E))
+ and then In_Open_Scopes (Scope (Minimum_Accessibility (E)))
+ then
+ return Minimum_Accessibility (E);
+ end if;
+
+ return Extra_Accessibility (E);
+ end Get_Dynamic_Accessibility;
+
+ -----------------------
+ -- Has_Access_Values --
+ -----------------------
+
+ function Has_Access_Values (T : Entity_Id) return Boolean
+ is
+ Typ : constant Entity_Id := Underlying_Type (T);
+
+ begin
+ -- Case of a private type which is not completed yet. This can only
+ -- happen in the case of a generic formal type appearing directly, or
+ -- as a component of the type to which this function is being applied
+ -- at the top level. Return False in this case, since we certainly do
+ -- not know that the type contains access types.
+
+ if No (Typ) then
+ return False;
+
+ elsif Is_Access_Type (Typ) then
+ return True;
+
+ elsif Is_Array_Type (Typ) then
+ return Has_Access_Values (Component_Type (Typ));
+
+ elsif Is_Record_Type (Typ) then
+ declare
+ Comp : Entity_Id;
+
+ begin
+ -- Loop to check components
+
+ Comp := First_Component_Or_Discriminant (Typ);
+ while Present (Comp) loop
+
+ -- Check for access component, tag field does not count, even
+ -- though it is implemented internally using an access type.
+
+ if Has_Access_Values (Etype (Comp))
+ and then Chars (Comp) /= Name_uTag
+ then
+ return True;
+ end if;
+
+ Next_Component_Or_Discriminant (Comp);
+ end loop;
+ end;
+
+ return False;
+
+ else
+ return False;
+ end if;
+ end Has_Access_Values;
+
+ ---------------------------------------
+ -- Has_Anonymous_Access_Discriminant --
+ ---------------------------------------
+
+ function Has_Anonymous_Access_Discriminant (Typ : Entity_Id) return Boolean
+ is
+ Disc : Node_Id;
+
+ begin
+ if not Has_Discriminants (Typ) then
+ return False;
+ end if;
+
+ Disc := First_Discriminant (Typ);
+ while Present (Disc) loop
+ if Ekind (Etype (Disc)) = E_Anonymous_Access_Type then
+ return True;
+ end if;
+
+ Next_Discriminant (Disc);
+ end loop;
+
+ return False;
+ end Has_Anonymous_Access_Discriminant;
+
+ --------------------------------------------
+ -- Has_Unconstrained_Access_Discriminants --
+ --------------------------------------------
+
+ function Has_Unconstrained_Access_Discriminants
+ (Subtyp : Entity_Id) return Boolean
+ is
+ Discr : Entity_Id;
+
+ begin
+ if Has_Discriminants (Subtyp)
+ and then not Is_Constrained (Subtyp)
+ then
+ Discr := First_Discriminant (Subtyp);
+ while Present (Discr) loop
+ if Ekind (Etype (Discr)) = E_Anonymous_Access_Type then
+ return True;
+ end if;
+
+ Next_Discriminant (Discr);
+ end loop;
+ end if;
+
+ return False;
+ end Has_Unconstrained_Access_Discriminants;
+
+ --------------------------------
+ -- Is_Anonymous_Access_Actual --
+ --------------------------------
+
+ function Is_Anonymous_Access_Actual (N : Node_Id) return Boolean is
+ Par : Node_Id;
+ begin
+ if Ekind (Etype (N)) /= E_Anonymous_Access_Type then
+ return False;
+ end if;
+
+ Par := Parent (N);
+ while Present (Par)
+ and then Nkind (Par) in N_Case_Expression
+ | N_If_Expression
+ | N_Parameter_Association
+ loop
+ Par := Parent (Par);
+ end loop;
+ return Nkind (Par) in N_Subprogram_Call;
+ end Is_Anonymous_Access_Actual;
+
+ --------------------------------------
+ -- Is_Special_Aliased_Formal_Access --
+ --------------------------------------
+
+ function Is_Special_Aliased_Formal_Access
+ (Exp : Node_Id;
+ In_Return_Context : Boolean := False) return Boolean
+ is
+ Scop : constant Entity_Id := Current_Subprogram;
+ begin
+ -- Verify the expression is an access reference to 'Access within a
+ -- return statement as this is the only time an explicitly aliased
+ -- formal has different semantics.
+
+ if Nkind (Exp) /= N_Attribute_Reference
+ or else Get_Attribute_Id (Attribute_Name (Exp)) /= Attribute_Access
+ or else not (In_Return_Value (Exp)
+ or else In_Return_Context)
+ or else not Needs_Result_Accessibility_Level (Scop)
+ then
+ return False;
+ end if;
+
+ -- Check if the prefix of the reference is indeed an explicitly aliased
+ -- formal parameter for the function Scop. Additionally, we must check
+ -- that Scop returns an anonymous access type, otherwise the special
+ -- rules dictating a need for a dynamic check are not in effect.
+
+ return Is_Entity_Name (Prefix (Exp))
+ and then Is_Explicitly_Aliased (Entity (Prefix (Exp)));
+ end Is_Special_Aliased_Formal_Access;
+
+ --------------------------------------
+ -- Needs_Result_Accessibility_Level --
+ --------------------------------------
+
+ function Needs_Result_Accessibility_Level
+ (Func_Id : Entity_Id) return Boolean
+ is
+ Func_Typ : constant Entity_Id := Underlying_Type (Etype (Func_Id));
+
+ function Has_Unconstrained_Access_Discriminant_Component
+ (Comp_Typ : Entity_Id) return Boolean;
+ -- Returns True if any component of the type has an unconstrained access
+ -- discriminant.
+
+ -----------------------------------------------------
+ -- Has_Unconstrained_Access_Discriminant_Component --
+ -----------------------------------------------------
+
+ function Has_Unconstrained_Access_Discriminant_Component
+ (Comp_Typ : Entity_Id) return Boolean
+ is
+ begin
+ if not Is_Limited_Type (Comp_Typ) then
+ return False;
+
+ -- Only limited types can have access discriminants with
+ -- defaults.
+
+ elsif Has_Unconstrained_Access_Discriminants (Comp_Typ) then
+ return True;
+
+ elsif Is_Array_Type (Comp_Typ) then
+ return Has_Unconstrained_Access_Discriminant_Component
+ (Underlying_Type (Component_Type (Comp_Typ)));
+
+ elsif Is_Record_Type (Comp_Typ) then
+ declare
+ Comp : Entity_Id;
+
+ begin
+ Comp := First_Component (Comp_Typ);
+ while Present (Comp) loop
+ if Has_Unconstrained_Access_Discriminant_Component
+ (Underlying_Type (Etype (Comp)))
+ then
+ return True;
+ end if;
+
+ Next_Component (Comp);
+ end loop;
+ end;
+ end if;
+
+ return False;
+ end Has_Unconstrained_Access_Discriminant_Component;
+
+ Disable_Tagged_Cases : constant Boolean := True;
+ -- Flag used to temporarily disable a "True" result for tagged types.
+ -- See comments further below for details.
+
+ -- Start of processing for Needs_Result_Accessibility_Level
+
+ begin
+ -- False if completion unavailable, which can happen when we are
+ -- analyzing an abstract subprogram or if the subprogram has
+ -- delayed freezing.
+
+ if No (Func_Typ) then
+ return False;
+
+ -- False if not a function, also handle enum-lit renames case
+
+ elsif Func_Typ = Standard_Void_Type
+ or else Is_Scalar_Type (Func_Typ)
+ then
+ return False;
+
+ -- Handle a corner case, a cross-dialect subp renaming. For example,
+ -- an Ada 2012 renaming of an Ada 2005 subprogram. This can occur when
+ -- an Ada 2005 (or earlier) unit references predefined run-time units.
+
+ elsif Present (Alias (Func_Id)) then
+
+ -- Unimplemented: a cross-dialect subp renaming which does not set
+ -- the Alias attribute (e.g., a rename of a dereference of an access
+ -- to subprogram value). ???
+
+ return Present (Extra_Accessibility_Of_Result (Alias (Func_Id)));
+
+ -- Remaining cases require Ada 2012 mode, unless they are dispatching
+ -- operations, since they may be overridden by Ada_2012 primitives.
+
+ elsif Ada_Version < Ada_2012
+ and then not Is_Dispatching_Operation (Func_Id)
+ then
+ return False;
+
+ -- Handle the situation where a result is an anonymous access type
+ -- RM 3.10.2 (10.3/3).
+
+ elsif Ekind (Func_Typ) = E_Anonymous_Access_Type then
+ return True;
+
+ -- In the case of, say, a null tagged record result type, the need for
+ -- this extra parameter might not be obvious so this function returns
+ -- True for all tagged types for compatibility reasons.
+
+ -- A function with, say, a tagged null controlling result type might
+ -- be overridden by a primitive of an extension having an access
+ -- discriminant and the overrider and overridden must have compatible
+ -- calling conventions (including implicitly declared parameters).
+
+ -- Similarly, values of one access-to-subprogram type might designate
+ -- both a primitive subprogram of a given type and a function which is,
+ -- for example, not a primitive subprogram of any type. Again, this
+ -- requires calling convention compatibility. It might be possible to
+ -- solve these issues by introducing wrappers, but that is not the
+ -- approach that was chosen.
+
+ -- Note: Despite the reasoning noted above, the extra accessibility
+ -- parameter for tagged types is disabled for performance reasons.
+
+ elsif Is_Tagged_Type (Func_Typ) then
+ return not Disable_Tagged_Cases;
+
+ elsif Has_Unconstrained_Access_Discriminants (Func_Typ) then
+ return True;
+
+ elsif Has_Unconstrained_Access_Discriminant_Component (Func_Typ) then
+ return True;
+
+ -- False for all other cases
+
+ else
+ return False;
+ end if;
+ end Needs_Result_Accessibility_Level;
+
+ ------------------------------------------
+ -- Prefix_With_Safe_Accessibility_Level --
+ ------------------------------------------
+
+ function Prefix_With_Safe_Accessibility_Level
+ (N : Node_Id;
+ Typ : Entity_Id) return Boolean
+ is
+ P : constant Node_Id := Prefix (N);
+ Aname : constant Name_Id := Attribute_Name (N);
+ Attr_Id : constant Attribute_Id := Get_Attribute_Id (Aname);
+ Btyp : constant Entity_Id := Base_Type (Typ);
+
+ function Safe_Value_Conversions return Boolean;
+ -- Return False if the prefix has a value conversion of an array type
+
+ ----------------------------
+ -- Safe_Value_Conversions --
+ ----------------------------
+
+ function Safe_Value_Conversions return Boolean is
+ PP : Node_Id := P;
+
+ begin
+ loop
+ if Nkind (PP) in N_Selected_Component | N_Indexed_Component then
+ PP := Prefix (PP);
+
+ elsif Comes_From_Source (PP)
+ and then Nkind (PP) in N_Type_Conversion
+ | N_Unchecked_Type_Conversion
+ and then Is_Array_Type (Etype (PP))
+ then
+ return False;
+
+ elsif Comes_From_Source (PP)
+ and then Nkind (PP) = N_Qualified_Expression
+ and then Is_Array_Type (Etype (PP))
+ and then Nkind (Original_Node (Expression (PP))) in
+ N_Aggregate | N_Extension_Aggregate
+ then
+ return False;
+
+ else
+ exit;
+ end if;
+ end loop;
+
+ return True;
+ end Safe_Value_Conversions;
+
+ -- Start of processing for Prefix_With_Safe_Accessibility_Level
+
+ begin
+ -- No check required for unchecked and unrestricted access
+
+ if Attr_Id = Attribute_Unchecked_Access
+ or else Attr_Id = Attribute_Unrestricted_Access
+ then
+ return True;
+
+ -- Check value conversions
+
+ elsif Ekind (Btyp) = E_General_Access_Type
+ and then not Safe_Value_Conversions
+ then
+ return False;
+ end if;
+
+ return True;
+ end Prefix_With_Safe_Accessibility_Level;
+
+ -----------------------------
+ -- Subprogram_Access_Level --
+ -----------------------------
+
+ function Subprogram_Access_Level (Subp : Entity_Id) return Uint is
+ begin
+ if Present (Alias (Subp)) then
+ return Subprogram_Access_Level (Alias (Subp));
+ else
+ return Scope_Depth (Enclosing_Dynamic_Scope (Subp));
+ end if;
+ end Subprogram_Access_Level;
+
+ --------------------------------
+ -- Static_Accessibility_Level --
+ --------------------------------
+
+ function Static_Accessibility_Level
+ (Expr : Node_Id;
+ Level : Static_Accessibility_Level_Kind;
+ In_Return_Context : Boolean := False) return Uint
+ is
+ begin
+ return Intval
+ (Accessibility_Level (Expr, Level, In_Return_Context));
+ end Static_Accessibility_Level;
+
+ -----------------------
+ -- Type_Access_Level --
+ -----------------------
+
+ 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
+ -- 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
+ -- associated with components the level is the same as that of the
+ -- enclosing composite type. However, special treatment is needed for
+ -- the cases of access parameters, return objects of an anonymous access
+ -- type, and, in Ada 95, access discriminants of limited types.
+
+ 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 specified,
+ -- 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 defining entity is a subprogram then we know the
+ -- anonymous access type Typ has been generated to either
+ -- describe an anonymous access type formal or an anonymous
+ -- access result type.
+
+ -- Since we are only interested in the formal case, avoid
+ -- the anonymous access result type.
+
+ if Is_Subprogram (Def_Ent)
+ and then not (Ekind (Def_Ent) = E_Function
+ and then Etype (Def_Ent) = Typ)
+ then
+ -- When the type comes from an anonymous access
+ -- parameter, the level is that of the subprogram
+ -- declaration.
+
+ 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.
+
+ 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
+ -- the result subtype of the enclosing function. The test here is
+ -- little complicated, because we have to account for extended
+ -- return statements that have been rewritten as blocks, in which
+ -- case we have to find and the Is_Return_Object attribute of the
+ -- itype's associated object. It would be nice to find a way to
+ -- simplify this test, but it doesn't seem worthwhile to add a new
+ -- flag just for purposes of this test. ???
+
+ elsif Ekind (Scope (Btyp)) = E_Return_Statement
+ or else
+ (Is_Itype (Btyp)
+ and then Nkind (Associated_Node_For_Itype (Btyp)) =
+ N_Object_Declaration
+ and then Is_Return_Object
+ (Defining_Identifier
+ (Associated_Node_For_Itype (Btyp))))
+ then
+ declare
+ Scop : Entity_Id;
+
+ begin
+ Scop := Scope (Scope (Btyp));
+ while Present (Scop) loop
+ exit when Ekind (Scop) = E_Function;
+ Scop := Scope (Scop);
+ end loop;
+
+ -- 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), Allow_Alt_Model);
+ end;
+ end if;
+ end if;
+
+ Btyp := Root_Type (Btyp);
+
+ -- The accessibility level of anonymous access types associated with
+ -- discriminants is that of the current instance of the type, and
+ -- that's deeper than the type itself (AARM 3.10.2 (12.3.21)).
+
+ -- AI-402: access discriminants have accessibility based on the
+ -- object rather than the type in Ada 2005, so the above paragraph
+ -- doesn't apply.
+
+ -- ??? Needs completion with rules from AI-416
+
+ if Ada_Version <= Ada_95
+ and then Ekind (Typ) = E_Anonymous_Access_Type
+ and then Present (Associated_Node_For_Itype (Typ))
+ and then Nkind (Associated_Node_For_Itype (Typ)) =
+ N_Discriminant_Specification
+ then
+ return Scope_Depth (Enclosing_Dynamic_Scope (Btyp)) + 1;
+ end if;
+ end if;
+
+ -- Return library level for a generic formal type. This is done because
+ -- RM(10.3.2) says that "The statically deeper relationship does not
+ -- apply to ... a descendant of a generic formal type". Rather than
+ -- checking at each point where a static accessibility check is
+ -- performed to see if we are dealing with a formal type, this rule is
+ -- implemented by having Type_Access_Level and Deepest_Type_Access_Level
+ -- return extreme values for a formal type; Deepest_Type_Access_Level
+ -- returns Int'Last. By calling the appropriate function from among the
+ -- two, we ensure that the static accessibility check will pass if we
+ -- happen to run into a formal type. More specifically, we should call
+ -- Deepest_Type_Access_Level instead of Type_Access_Level whenever the
+ -- call occurs as part of a static accessibility check and the error
+ -- case is the case where the type's level is too shallow (as opposed
+ -- to too deep).
+
+ if Is_Generic_Type (Root_Type (Btyp)) then
+ return Scope_Depth (Standard_Standard);
+ end if;
+
+ return Scope_Depth (Enclosing_Dynamic_Scope (Btyp));
+ end Type_Access_Level;
+
+end Accessibility;
diff --git a/gcc/ada/accessibility.ads b/gcc/ada/accessibility.ads
new file mode 100644
index 0000000..454ad75
--- /dev/null
+++ b/gcc/ada/accessibility.ads
@@ -0,0 +1,222 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- A C C E S S I B I L I T Y --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2022-2022, 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. See the GNU General Public License --
+-- for more details. You should have received a copy of the GNU General --
+-- Public License distributed with GNAT; see file COPYING3. If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- Accessibility level and check generation routines
+
+with Types; use Types;
+with Uintp; use Uintp;
+
+package Accessibility is
+
+ procedure Accessibility_Message (N : Node_Id; Typ : Entity_Id);
+ -- Error, or warning within an instance, if the static accessibility
+ -- rules of 3.10.2 are violated.
+
+ type Accessibility_Level_Kind is
+ (Dynamic_Level,
+ Object_Decl_Level,
+ Zero_On_Dynamic_Level);
+ -- Accessibility_Level_Kind is an enumerated type which captures the
+ -- different modes in which an accessibility level could be obtained for
+ -- a given expression.
+
+ -- When in the context of the function Accessibility_Level,
+ -- Accessibility_Level_Kind signals what type of accessibility level to
+ -- obtain. For example, when Level is Dynamic_Level, a defining identifier
+ -- associated with a SAOOAAT may be returned or an N_Integer_Literal node.
+ -- When the level is Object_Decl_Level, an N_Integer_Literal node is
+ -- returned containing the level of the declaration of the object if
+ -- relevant (be it a SAOOAAT or otherwise). Finally, Zero_On_Dynamic_Level
+ -- returns library level for all cases where the accessibility level is
+ -- dynamic (used to bypass static accessibility checks in dynamic cases).
+
+ function Accessibility_Level
+ (Expr : Node_Id;
+ Level : Accessibility_Level_Kind;
+ 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 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.
+
+ procedure Apply_Accessibility_Check
+ (N : Node_Id;
+ Typ : Entity_Id;
+ Insert_Node : Node_Id);
+ -- Given a name N denoting an access parameter, emits a run-time
+ -- accessibility check (if necessary), checking that the level of
+ -- the object denoted by the access parameter is not deeper than the
+ -- level of the type Typ. Program_Error is raised if the check fails.
+ -- Insert_Node indicates the node where the check should be inserted.
+
+ procedure Apply_Accessibility_Check_For_Allocator
+ (N : Node_Id;
+ Exp : Node_Id;
+ Ref : Node_Id;
+ Built_In_Place : Boolean := False);
+ -- Ada 2005 (AI-344): For an allocator with a class-wide designated
+ -- type, generate an accessibility check to verify that the level of the
+ -- type of the created object is not deeper than the level of the access
+ -- type. If the type of the qualified expression is class-wide, then
+ -- always generate the check (except in the case where it is known to be
+ -- unnecessary, see comment below). Otherwise, only generate the check
+ -- if the level of the qualified expression type is statically deeper
+ -- than the access type.
+ --
+ -- Although the static accessibility will generally have been performed
+ -- as a legality check, it won't have been done in cases where the
+ -- allocator appears in generic body, so a run-time check is needed in
+ -- general. One special case is when the access type is declared in the
+ -- same scope as the class-wide allocator, in which case the check can
+ -- never fail, so it need not be generated.
+ --
+ -- As an open issue, there seem to be cases where the static level
+ -- associated with the class-wide object's underlying type is not
+ -- sufficient to perform the proper accessibility check, such as for
+ -- allocators in nested subprograms or accept statements initialized by
+ -- class-wide formals when the actual originates outside at a deeper
+ -- static level. The nested subprogram case might require passing
+ -- accessibility levels along with class-wide parameters, and the task
+ -- case seems to be an actual gap in the language rules that needs to
+ -- be fixed by the ARG. ???
+
+ procedure Check_Return_Construct_Accessibility
+ (Return_Stmt : Node_Id;
+ Stm_Entity : Entity_Id);
+ -- Apply legality rule of 6.5 (5.9) to the access discriminants of an
+ -- aggregate in a return statement.
+
+ 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
+ -- accessibility level of the object may take on values in a range. The low
+ -- bound of that range is returned by Type_Access_Level; this function
+ -- yields the high bound of that range. Also differs from Type_Access_Level
+ -- 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 Effective_Extra_Accessibility (Id : Entity_Id) return Entity_Id;
+ -- Same as Einfo.Extra_Accessibility except thtat object renames
+ -- are looked through.
+
+ function Get_Dynamic_Accessibility (E : Entity_Id) return Entity_Id;
+ -- Obtain the accessibility level for a given entity formal taking into
+ -- account both extra and minimum accessibility.
+
+ function Has_Access_Values (T : Entity_Id) return Boolean;
+ -- Returns true if the underlying type of T is an access type, or has a
+ -- component (at any recursive level) that is an access type. This is a
+ -- conservative predicate, if it is not known whether or not T contains
+ -- access values (happens for generic formals in some cases), then False is
+ -- returned. Note that tagged types return False. Even though the tag is
+ -- implemented as an access type internally, this function tests only for
+ -- access types known to the programmer. See also Has_Tagged_Component.
+
+ function Has_Anonymous_Access_Discriminant (Typ : Entity_Id) return Boolean;
+ -- Returns True if Typ has one or more anonymous access discriminants
+
+ function Prefix_With_Safe_Accessibility_Level
+ (N : Node_Id;
+ Typ : Entity_Id) return Boolean;
+ -- Return True if the prefix does not have a value conversion of an
+ -- array because a value conversion is like an aggregate with respect
+ -- to determining accessibility level (RM 3.10.2); even if evaluation
+ -- of a value conversion is guaranteed to not create a new object,
+ -- accessibility rules are defined as if it might.
+
+ subtype Static_Accessibility_Level_Kind
+ is Accessibility_Level_Kind range Object_Decl_Level
+ .. Zero_On_Dynamic_Level;
+ -- Restrict the reange of Accessibility_Level_Kind to be non-dynamic for
+ -- use in the static version of Accessibility_Level below.
+
+ function Static_Accessibility_Level
+ (Expr : Node_Id;
+ Level : Static_Accessibility_Level_Kind;
+ In_Return_Context : Boolean := False) return Uint;
+ -- Overloaded version of Accessibility_Level which returns a universal
+ -- integer for use in compile-time checking. Note: Level is restricted to
+ -- be non-dynamic.
+
+ function Has_Unconstrained_Access_Discriminants
+ (Subtyp : Entity_Id) return Boolean;
+ -- Returns True if the given subtype is unconstrained and has one or more
+ -- access discriminants.
+
+ function Is_Anonymous_Access_Actual (N : Node_Id) return Boolean;
+ -- Determine if N is used as an actual for a call whose corresponding
+ -- formal is of an anonymous access type.
+
+ function Is_Special_Aliased_Formal_Access
+ (Exp : Node_Id;
+ In_Return_Context : Boolean := False) return Boolean;
+ -- Determines whether a dynamic check must be generated for explicitly
+ -- aliased formals within a function Scop for the expression Exp.
+
+ -- In_Return_Context forces Is_Special_Aliased_Formal_Access to assume
+ -- that Exp is within a return value which is useful for checking
+ -- expressions within discriminant associations of return objects.
+
+ -- More specially, Is_Special_Aliased_Formal_Access checks that Exp is a
+ -- 'Access attribute reference within a return statement where the ultimate
+ -- prefix is an aliased formal of Scop and that Scop returns an anonymous
+ -- access type. See RM 3.10.2 for more details.
+
+ function Needs_Result_Accessibility_Level
+ (Func_Id : Entity_Id) return Boolean;
+ -- Ada 2012 (AI05-0234): Return True if the function needs an implicit
+ -- parameter to identify the accessibility level of the function result
+ -- "determined by the point of call".
+
+ function Subprogram_Access_Level (Subp : Entity_Id) return Uint;
+ -- Return the accessibility level of the view denoted by Subp
+
+ 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.
+
+end Accessibility;
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
index 199dbe0..d2604ca 100644
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -3524,6 +3524,8 @@ __gnat_cpu_set (int cpu, size_t count ATTRIBUTE_UNUSED, cpu_set_t *set)
#if defined (__APPLE__)
#include <mach-o/dyld.h>
+#elif defined (__linux__)
+#include <link.h>
#endif
const void *
@@ -3532,10 +3534,8 @@ __gnat_get_executable_load_address (void)
#if defined (__APPLE__)
return _dyld_get_image_header (0);
-#elif 0 && defined (__linux__)
- /* Currently disabled as it needs at least -ldl. */
+#elif defined (__linux__)
struct link_map *map = _r_debug.r_map;
-
return (const void *)map->l_addr;
#elif defined (_WIN32)
diff --git a/gcc/ada/aspects.adb b/gcc/ada/aspects.adb
index 3471a81..81c9c28 100644
--- a/gcc/ada/aspects.adb
+++ b/gcc/ada/aspects.adb
@@ -373,7 +373,6 @@ package body Aspects is
else
Asps := New_List;
Set_Aspect_Specifications (To, Asps);
- Set_Has_Aspects (To);
end if;
-- Remove the aspect from its original owner and relocate it to node
diff --git a/gcc/ada/atree.ads b/gcc/ada/atree.ads
index 0c809f5..cc66ab3 100644
--- a/gcc/ada/atree.ads
+++ b/gcc/ada/atree.ads
@@ -148,7 +148,6 @@ package Atree is
-- This is a count of errors that are serious enough to stop expansion,
-- and hence to prevent generation of an object file even if the
-- switch -gnatQ is set. Initialized to zero at the start of compilation.
- -- Initialized for -gnatVa use, see comment above.
-- WARNING: There is a matching C declaration of this variable in fe.h
@@ -156,12 +155,11 @@ package Atree is
-- Number of errors detected so far. Includes count of serious errors and
-- non-serious errors, so this value is always greater than or equal to the
-- Serious_Errors_Detected value. Initialized to zero at the start of
- -- compilation. Initialized for -gnatVa use, see comment above.
+ -- compilation.
Warnings_Detected : Nat := 0;
-- Number of warnings detected. Initialized to zero at the start of
- -- compilation. Initialized for -gnatVa use, see comment above. This
- -- count includes the count of style and info messages.
+ -- compilation. This count includes the count of style and info messages.
Warning_Info_Messages : Nat := 0;
-- Number of info messages generated as warnings. Info messages are never
diff --git a/gcc/ada/bindgen.adb b/gcc/ada/bindgen.adb
index f2aaa2d..e72cdf8 100644
--- a/gcc/ada/bindgen.adb
+++ b/gcc/ada/bindgen.adb
@@ -114,25 +114,23 @@ package body Bindgen is
-- For CodePeer, introduce a wrapper subprogram which calls the
-- user-defined main subprogram.
- -- Names and link_names for CUDA device adainit/adafinal procs.
+ -- Name for local C-String variable
- Device_Subp_Name_Prefix : constant String := "imported_device_";
- Device_Link_Name_Prefix : constant String := "__device_";
-
- function Device_Ada_Final_Link_Name return String is
- (Device_Link_Name_Prefix & Ada_Final_Name.all);
+ Adainit_String_Obj_Name : constant String := "Adainit_Name_C_String";
- function Device_Ada_Final_Subp_Name return String is
- (Device_Subp_Name_Prefix & Ada_Final_Name.all);
+ -- Name and link_name for CUDA device initialization procedure
- function Device_Ada_Init_Link_Name return String is
- (Device_Link_Name_Prefix & Ada_Init_Name.all);
+ Device_Ada_Init_Subp_Name : constant String := "Device_Initialization";
+ Device_Link_Name_Prefix : constant String := "__device_";
- function Device_Ada_Init_Subp_Name return String is
- (Device_Subp_Name_Prefix & Ada_Init_Name.all);
+ function Device_Link_Name (Suffix : String) return String is
+ (Device_Link_Name_Prefix &
+ (if CUDA_Device_Library_Name = null
+ then "ada" -- is this an error path?
+ else CUDA_Device_Library_Name.all) & Suffix);
- -- Text for aspect specifications (if any) given as part of the
- -- Adainit and Adafinal spec declarations.
+ function Device_Ada_Init_Link_Name return String
+ is (Device_Link_Name (Suffix => "init"));
----------------------------------
-- Interface_State Pragma Table --
@@ -521,12 +519,6 @@ package body Bindgen is
WBI (" System.Standard_Library.Adafinal;");
end if;
- -- perform device (as opposed to host) finalization
- if Enable_CUDA_Expansion then
- WBI (" pragma CUDA_Execute (" &
- Device_Ada_Final_Subp_Name & ", 1, 1);");
- end if;
-
WBI (" end " & Ada_Final_Name.all & ";");
WBI ("");
end Gen_Adafinal;
@@ -1360,11 +1352,13 @@ package body Bindgen is
end loop;
WBI (" procedure " & Device_Ada_Init_Subp_Name & ";");
- WBI (" pragma Import (C, " & Device_Ada_Init_Subp_Name &
+ WBI (" pragma Export (C, " & Device_Ada_Init_Subp_Name &
", Link_Name => """ & Device_Ada_Init_Link_Name & """);");
- WBI (" procedure " & Device_Ada_Final_Subp_Name & ";");
- WBI (" pragma Import (C, " & Device_Ada_Final_Subp_Name &
- ", Link_Name => """ & Device_Ada_Final_Link_Name & """);");
+
+ -- C-string declaration for adainit
+ WBI (" " & Adainit_String_Obj_Name
+ & " : Interfaces.C.Strings.Chars_Ptr;");
+ WBI ("");
WBI ("");
end Gen_CUDA_Defs;
@@ -1374,6 +1368,41 @@ package body Bindgen is
-------------------
procedure Gen_CUDA_Init is
+ -- Generate call to register one function
+ procedure Gen_CUDA_Register_Function_Call
+ (Kernel_Name : String;
+ Kernel_String : String;
+ Kernel_Proc : String);
+
+ -------------------------------------
+ -- Gen_CUDA_Register_Function_Call --
+ -------------------------------------
+
+ procedure Gen_CUDA_Register_Function_Call
+ (Kernel_Name : String;
+ Kernel_String : String;
+ Kernel_Proc : String) is
+ begin
+ WBI (" " & Kernel_String & " :=");
+ WBI (" Interfaces.C.Strings.New_Char_Array ("""
+ & Kernel_Name
+ & """);");
+
+ -- Generate call to CUDA runtime to register function.
+ WBI (" CUDA_Register_Function (");
+ WBI (" Fat_Binary_Handle, ");
+ WBI (" " & Kernel_Proc & "'Address,");
+ WBI (" " & Kernel_String & ",");
+ WBI (" " & Kernel_String & ",");
+ WBI (" -1,");
+ WBI (" System.Null_Address,");
+ WBI (" System.Null_Address,");
+ WBI (" System.Null_Address,");
+ WBI (" System.Null_Address,");
+ WBI (" System.Null_Address);");
+ WBI ("");
+ end Gen_CUDA_Register_Function_Call;
+
begin
if not Enable_CUDA_Expansion then
return;
@@ -1404,26 +1433,19 @@ package body Bindgen is
Get_Name_String (CUDA_Kernels.Table (K).Kernel_Name);
-- Kernel_Name is the name of the kernel, after package expansion.
begin
- WBI (" " & Kernel_String & " :=");
- WBI (" Interfaces.C.Strings.New_Char_Array ("""
- & Kernel_Name
- & """);");
- -- Generate call to CUDA runtime to register function.
- WBI (" CUDA_Register_Function (");
- WBI (" Fat_Binary_Handle, ");
- WBI (" " & Kernel_Proc & "'Address,");
- WBI (" " & Kernel_String & ",");
- WBI (" " & Kernel_String & ",");
- WBI (" -1,");
- WBI (" System.Null_Address,");
- WBI (" System.Null_Address,");
- WBI (" System.Null_Address,");
- WBI (" System.Null_Address,");
- WBI (" System.Null_Address);");
- WBI ("");
+ Gen_CUDA_Register_Function_Call
+ (Kernel_Name => Kernel_Name,
+ Kernel_String => Kernel_String,
+ Kernel_Proc => Kernel_Proc);
end;
end loop;
+ -- Register device-side Adainit
+ Gen_CUDA_Register_Function_Call
+ (Kernel_Name => Device_Ada_Init_Link_Name,
+ Kernel_String => Adainit_String_Obj_Name,
+ Kernel_Proc => Device_Ada_Init_Subp_Name);
+
WBI (" CUDA_Register_Fat_Binary_End (Fat_Binary_Handle);");
-- perform device (as opposed to host) elaboration
@@ -2644,7 +2666,8 @@ package body Bindgen is
WBI (" procedure " & Ada_Init_Name.all & ";");
if Enable_CUDA_Device_Expansion then
WBI (" pragma Export (C, " & Ada_Init_Name.all &
- ", Link_Name => """ & Device_Ada_Init_Link_Name & """);");
+ ", Link_Name => """ & Device_Link_Name_Prefix
+ & Ada_Init_Name.all & """);");
WBI (" pragma CUDA_Global (" & Ada_Init_Name.all & ");");
else
WBI (" pragma Export (C, " & Ada_Init_Name.all & ", """ &
@@ -2661,10 +2684,10 @@ package body Bindgen is
if not Cumulative_Restrictions.Set (No_Finalization) then
WBI ("");
WBI (" procedure " & Ada_Final_Name.all & ";");
-
if Enable_CUDA_Device_Expansion then
WBI (" pragma Export (C, " & Ada_Final_Name.all &
- ", Link_Name => """ & Device_Ada_Final_Link_Name & """);");
+ ", Link_Name => """ & Device_Link_Name_Prefix &
+ Ada_Final_Name.all & """);");
WBI (" pragma CUDA_Global (" & Ada_Final_Name.all & ");");
else
WBI (" pragma Export (C, " & Ada_Final_Name.all & ", """ &
@@ -2894,6 +2917,13 @@ package body Bindgen is
Gen_Adainit (Elab_Order);
+ if Enable_CUDA_Expansion then
+ WBI (" procedure " & Device_Ada_Init_Subp_Name & " is");
+ WBI (" begin");
+ WBI (" raise Program_Error;");
+ WBI (" end " & Device_Ada_Init_Subp_Name & ";");
+ end if;
+
if Bind_Main_Program then
Gen_Main;
end if;
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index 8fa16b8..5833be3 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -570,119 +570,6 @@ package body Checks is
Install_Null_Excluding_Check (P);
end Apply_Access_Check;
- -------------------------------
- -- Apply_Accessibility_Check --
- -------------------------------
-
- procedure Apply_Accessibility_Check
- (N : Node_Id;
- Typ : Entity_Id;
- Insert_Node : Node_Id)
- is
- Loc : constant Source_Ptr := Sloc (N);
-
- Check_Cond : Node_Id;
- Param_Ent : Entity_Id := Param_Entity (N);
- Param_Level : Node_Id;
- 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)
- and then Ekind (Entity (N)) in E_Constant | E_Variable
- and then Present (Effective_Extra_Accessibility (Entity (N)))
- then
- Param_Ent := Entity (N);
- while Present (Renamed_Object (Param_Ent)) loop
- -- Renamed_Object must return an Entity_Name here
- -- because of preceding "Present (E_E_A (...))" test.
-
- Param_Ent := Entity (Renamed_Object (Param_Ent));
- end loop;
- end if;
-
- if Inside_A_Generic then
- return;
-
- -- Only apply the run-time check if the access parameter has an
- -- associated extra access level parameter and when accessibility checks
- -- are enabled.
-
- elsif Present (Param_Ent)
- and then Present (Get_Dynamic_Accessibility (Param_Ent))
- and then not Accessibility_Checks_Suppressed (Param_Ent)
- and then not Accessibility_Checks_Suppressed (Typ)
- then
- -- Obtain the parameter's accessibility level
-
- Param_Level :=
- New_Occurrence_Of (Get_Dynamic_Accessibility (Param_Ent), Loc);
-
- -- Use the dynamic accessibility parameter for the function's result
- -- when one has been created instead of statically referring to the
- -- deepest type level so as to appropriatly handle the rules for
- -- RM 3.10.2 (10.1/3).
-
- if Ekind (Scope (Param_Ent)) = E_Function
- and then In_Return_Value (N)
- and then Ekind (Typ) = E_Anonymous_Access_Type
- then
- -- Associate the level of the result type to the extra result
- -- accessibility parameter belonging to the current function.
-
- if Present (Extra_Accessibility_Of_Result (Scope (Param_Ent))) then
- Type_Level :=
- New_Occurrence_Of
- (Extra_Accessibility_Of_Result (Scope (Param_Ent)), Loc);
-
- -- In Ada 2005 and earlier modes, a result extra accessibility
- -- parameter is not generated and no dynamic check is performed.
-
- else
- return;
- end if;
-
- -- Otherwise get the type's accessibility level normally
-
- else
- Type_Level :=
- Make_Integer_Literal (Loc, Deepest_Type_Access_Level (Typ));
- end if;
-
- -- Raise Program_Error if the accessibility level of the access
- -- parameter is deeper than the level of the target access type.
-
- Check_Cond :=
- Make_Op_Gt (Loc,
- Left_Opnd => Param_Level,
- Right_Opnd => Type_Level);
-
- Insert_Action (Insert_Node,
- Make_Raise_Program_Error (Loc,
- Condition => Check_Cond,
- Reason => PE_Accessibility_Check_Failed));
-
- Analyze_And_Resolve (N);
-
- -- If constant folding has happened on the condition for the
- -- generated error, then warn about it being unconditional.
-
- if Nkind (Check_Cond) = N_Identifier
- and then Entity (Check_Cond) = Standard_True
- then
- Error_Msg_Warn := SPARK_Mode /= On;
- Error_Msg_N ("accessibility check fails<<", N);
- Error_Msg_N ("\Program_Error [<<", N);
- end if;
- end if;
- end Apply_Accessibility_Check;
-
--------------------------------
-- Apply_Address_Clause_Check --
--------------------------------
@@ -778,7 +665,7 @@ package body Checks is
-- Note: Expr is empty if the address-clause is applied to in-mode
-- actuals (allowed by 13.1(22)).
- if not Present (Expr)
+ if No (Expr)
or else
(Is_Entity_Name (Expression (AC))
and then Ekind (Entity (Expression (AC))) = E_Constant
@@ -999,21 +886,26 @@ package body Checks is
Determine_Range (N, VOK, Vlo, Vhi, Assume_Valid => True);
if VOK and then Tlo <= Vlo and then Vhi <= Thi then
- Rewrite (Left_Opnd (N),
- Make_Type_Conversion (Loc,
- Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
- Expression => Relocate_Node (Left_Opnd (N))));
-
- Rewrite (Right_Opnd (N),
- Make_Type_Conversion (Loc,
- Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
- Expression => Relocate_Node (Right_Opnd (N))));
-
-- Rewrite the conversion operand so that the original
-- node is retained, in order to avoid the warning for
-- redundant conversions in Resolve_Type_Conversion.
- Rewrite (N, Relocate_Node (N));
+ declare
+ Op : constant Node_Id := New_Op_Node (Nkind (N), Loc);
+ begin
+ Set_Left_Opnd (Op,
+ Make_Type_Conversion (Loc,
+ Subtype_Mark =>
+ New_Occurrence_Of (Target_Type, Loc),
+ Expression => Relocate_Node (Left_Opnd (N))));
+ Set_Right_Opnd (Op,
+ Make_Type_Conversion (Loc,
+ Subtype_Mark =>
+ New_Occurrence_Of (Target_Type, Loc),
+ Expression => Relocate_Node (Right_Opnd (N))));
+
+ Rewrite (N, Op);
+ end;
Set_Etype (N, Target_Type);
@@ -3784,13 +3676,14 @@ package body Checks is
-- Universal_Integer. So in numeric conversions it is usually
-- within range of the target integer type. Use the static
-- bounds of the base types to check. Disable this optimization
- -- in case of a generic formal discrete type, because we don't
- -- necessarily know the upper bound yet.
+ -- in case of a descendant of a generic formal discrete type,
+ -- because we don't necessarily know the upper bound yet.
if Nkind (Expr) = N_Attribute_Reference
and then Attribute_Name (Expr) = Name_Pos
and then Is_Enumeration_Type (Etype (Prefix (Expr)))
- and then not Is_Generic_Type (Etype (Prefix (Expr)))
+ and then
+ not Is_Generic_Type (Root_Type (Etype (Prefix (Expr))))
and then Is_Integer_Type (Target_Type)
then
declare
@@ -8403,115 +8296,10 @@ package body Checks is
Loc : constant Source_Ptr := Sloc (Parent (N));
Typ : constant Entity_Id := Etype (N);
- function Safe_To_Capture_In_Parameter_Value return Boolean;
- -- Determines if it is safe to capture Known_Non_Null status for an
- -- the entity referenced by node N. The caller ensures that N is indeed
- -- an entity name. It is safe to capture the non-null status for an IN
- -- parameter when the reference occurs within a declaration that is sure
- -- to be executed as part of the declarative region.
-
procedure Mark_Non_Null;
-- After installation of check, if the node in question is an entity
-- name, then mark this entity as non-null if possible.
- function Safe_To_Capture_In_Parameter_Value return Boolean is
- E : constant Entity_Id := Entity (N);
- S : constant Entity_Id := Current_Scope;
- S_Par : Node_Id;
-
- begin
- if Ekind (E) /= E_In_Parameter then
- return False;
- end if;
-
- -- Two initial context checks. We must be inside a subprogram body
- -- with declarations and reference must not appear in nested scopes.
-
- if (Ekind (S) /= E_Function and then Ekind (S) /= E_Procedure)
- or else Scope (E) /= S
- then
- return False;
- end if;
-
- S_Par := Parent (Parent (S));
-
- if Nkind (S_Par) /= N_Subprogram_Body
- or else No (Declarations (S_Par))
- then
- return False;
- end if;
-
- declare
- N_Decl : Node_Id;
- P : Node_Id;
-
- begin
- -- Retrieve the declaration node of N (if any). Note that N
- -- may be a part of a complex initialization expression.
-
- P := Parent (N);
- N_Decl := Empty;
- while Present (P) loop
-
- -- If we have a short circuit form, and we are within the right
- -- hand expression, we return false, since the right hand side
- -- is not guaranteed to be elaborated.
-
- if Nkind (P) in N_Short_Circuit
- and then N = Right_Opnd (P)
- then
- return False;
- end if;
-
- -- Similarly, if we are in an if expression and not part of the
- -- condition, then we return False, since neither the THEN or
- -- ELSE dependent expressions will always be elaborated.
-
- if Nkind (P) = N_If_Expression
- and then N /= First (Expressions (P))
- then
- return False;
- end if;
-
- -- If within a case expression, and not part of the expression,
- -- then return False, since a particular dependent expression
- -- may not always be elaborated
-
- if Nkind (P) = N_Case_Expression
- and then N /= Expression (P)
- then
- return False;
- end if;
-
- -- While traversing the parent chain, if node N belongs to a
- -- statement, then it may never appear in a declarative region.
-
- if Nkind (P) in N_Statement_Other_Than_Procedure_Call
- or else Nkind (P) = N_Procedure_Call_Statement
- then
- return False;
- end if;
-
- -- If we are at a declaration, record it and exit
-
- if Nkind (P) in N_Declaration
- and then Nkind (P) not in N_Subprogram_Specification
- then
- N_Decl := P;
- exit;
- end if;
-
- P := Parent (P);
- end loop;
-
- if No (N_Decl) then
- return False;
- end if;
-
- return List_Containing (N_Decl) = Declarations (S_Par);
- end;
- end Safe_To_Capture_In_Parameter_Value;
-
-------------------
-- Mark_Non_Null --
-------------------
@@ -8527,19 +8315,10 @@ package body Checks is
Set_Is_Known_Null (Entity (N), False);
- -- We can mark the entity as known to be non-null if either it is
- -- safe to capture the value, or in the case of an IN parameter,
- -- which is a constant, if the check we just installed is in the
- -- declarative region of the subprogram body. In this latter case,
- -- a check is decisive for the rest of the body if the expression
- -- is sure to be elaborated, since we know we have to elaborate
- -- all declarations before executing the body.
-
- -- Couldn't this always be part of Safe_To_Capture_Value ???
+ -- We can mark the entity as known to be non-null if it is safe to
+ -- capture the value.
- if Safe_To_Capture_Value (N, Entity (N))
- or else Safe_To_Capture_In_Parameter_Value
- then
+ if Safe_To_Capture_Value (N, Entity (N)) then
Set_Is_Known_Non_Null (Entity (N));
end if;
end if;
diff --git a/gcc/ada/checks.ads b/gcc/ada/checks.ads
index 48678cd..772adf0 100644
--- a/gcc/ada/checks.ads
+++ b/gcc/ada/checks.ads
@@ -189,16 +189,6 @@ package Checks is
-- Determines whether an expression node requires a run-time access
-- check and if so inserts the appropriate run-time check.
- procedure Apply_Accessibility_Check
- (N : Node_Id;
- Typ : Entity_Id;
- Insert_Node : Node_Id);
- -- Given a name N denoting an access parameter, emits a run-time
- -- accessibility check (if necessary), checking that the level of
- -- the object denoted by the access parameter is not deeper than the
- -- level of the type Typ. Program_Error is raised if the check fails.
- -- Insert_Node indicates the node where the check should be inserted.
-
procedure Apply_Address_Clause_Check (E : Entity_Id; N : Node_Id);
-- E is the entity for an object which has an address clause. If checks
-- are enabled, then this procedure generates a check that the specified
@@ -776,12 +766,14 @@ package Checks is
-- itself lead to erroneous or unpredictable execution, or to
-- other objects becoming abnormal.
- -- We quote the rules in full here since they are quite delicate. Most
- -- of the time, we can just compute away with wrong values, and get a
- -- possibly wrong result, which is well within the range of allowed
- -- implementation defined behavior. The two tricky cases are subscripted
- -- array assignments, where we don't want to do wild stores, and case
- -- statements where we don't want to do wild jumps.
+ -- We quote the rules in full here since they are quite delicate.
+ -- (???The rules quoted here are obsolete; see the GNAT User's Guide for a
+ -- description of all the -gnatV switches.) Most of the time, we can just
+ -- compute away with wrong values, and get a possibly wrong result, which
+ -- is well within the range of allowed implementation defined behavior. The
+ -- two tricky cases are subscripted array assignments, where we don't want
+ -- to do wild stores, and case statements where we don't want to do wild
+ -- jumps.
-- In GNAT, we control validity checking with a switch -gnatV that can take
-- three parameters, n/d/f for None/Default/Full. These modes have the
@@ -799,15 +791,8 @@ package Checks is
-- alternatives will be executed. Wild jumps cannot result even
-- in this mode, since we always do a range check
- -- For subscripted array assignments, wild stores will result in
- -- the expected manner when addresses are calculated using values
- -- of subscripts that are out of range.
-
- -- It could perhaps be argued that this mode is still conformant with
- -- the letter of the RM, since implementation defined is a rather
- -- broad category, but certainly it is not in the spirit of the
- -- RM requirement, since wild stores certainly seem to be a case of
- -- erroneous behavior.
+ -- For subscripted array assignments, wild stores can result in
+ -- overwriting arbitrary memory locations.
-- Default (default standard RM-compatible validity checking)
diff --git a/gcc/ada/contracts.adb b/gcc/ada/contracts.adb
index a300d73..59121ca 100644
--- a/gcc/ada/contracts.adb
+++ b/gcc/ada/contracts.adb
@@ -42,13 +42,13 @@ with Nmake; use Nmake;
with Opt; use Opt;
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_Ch12; use Sem_Ch12;
with Sem_Ch13; use Sem_Ch13;
with Sem_Disp; use Sem_Disp;
with Sem_Prag; use Sem_Prag;
-with Sem_Res; use Sem_Res;
with Sem_Type; use Sem_Type;
with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo;
@@ -59,6 +59,7 @@ with Snames; use Snames;
with Stand; use Stand;
with Stringt; use Stringt;
with Tbuild; use Tbuild;
+with Warnsw; use Warnsw;
package body Contracts is
@@ -107,6 +108,11 @@ package body Contracts is
-- well as Contract_Cases, Subprogram_Variant, invariants and predicates.
-- Body_Id denotes the entity of the subprogram body.
+ procedure Preanalyze_Condition
+ (Subp : Entity_Id;
+ Expr : Node_Id);
+ -- Preanalyze the class-wide condition Expr of Subp
+
procedure Set_Class_Condition
(Kind : Condition_Kind;
Subp : Entity_Id;
@@ -310,6 +316,7 @@ package body Contracts is
| Name_Async_Writers
| Name_Effective_Reads
| Name_Effective_Writes
+ | Name_No_Caching
or else (Ekind (Id) = E_Task_Type
and Prag_Nam in Name_Part_Of
| Name_Depends
@@ -853,6 +860,7 @@ package body Contracts is
AW_Val : Boolean := False;
ER_Val : Boolean := False;
EW_Val : Boolean := False;
+ NC_Val : Boolean;
Seen : Boolean := False;
Prag : Node_Id;
Obj_Typ : Entity_Id;
@@ -950,18 +958,25 @@ package body Contracts is
end if;
-- Verify the mutual interaction of the various external properties.
- -- For variables for which No_Caching is enabled, it has been checked
- -- already that only False values for other external properties are
- -- allowed.
+ -- For types and variables for which No_Caching is enabled, it has been
+ -- checked already that only False values for other external properties
+ -- are allowed.
if Seen
- and then (Ekind (Type_Or_Obj_Id) /= E_Variable
- or else not No_Caching_Enabled (Type_Or_Obj_Id))
+ and then not No_Caching_Enabled (Type_Or_Obj_Id)
then
Check_External_Properties
(Type_Or_Obj_Id, AR_Val, AW_Val, ER_Val, EW_Val);
end if;
+ -- Analyze the non-external volatility property No_Caching
+
+ Prag := Get_Pragma (Type_Or_Obj_Id, Pragma_No_Caching);
+
+ if Present (Prag) then
+ Analyze_External_Property_In_Decl_Part (Prag, NC_Val);
+ end if;
+
-- The following checks are relevant only when SPARK_Mode is on, as
-- they are not standard Ada legality rules. Internally generated
-- temporaries are ignored, as well as return objects.
@@ -1041,10 +1056,10 @@ package body Contracts is
if Is_Type_Id
and then not Is_Effectively_Volatile (Type_Or_Obj_Id)
- and then Has_Volatile_Component (Type_Or_Obj_Id)
+ and then Has_Effectively_Volatile_Component (Type_Or_Obj_Id)
then
Error_Msg_N
- ("non-volatile type & cannot have volatile"
+ ("non-volatile type & cannot have effectively volatile"
& " components",
Type_Or_Obj_Id);
end if;
@@ -1070,7 +1085,6 @@ package body Contracts is
Saved_SMP : constant Node_Id := SPARK_Mode_Pragma;
-- Save the SPARK_Mode-related data to restore on exit
- NC_Val : Boolean;
Items : Node_Id;
Prag : Node_Id;
Ref_Elmt : Elmt_Id;
@@ -1112,14 +1126,6 @@ package body Contracts is
Check_Type_Or_Object_External_Properties (Type_Or_Obj_Id => Obj_Id);
- -- Analyze the non-external volatility property No_Caching
-
- Prag := Get_Pragma (Obj_Id, Pragma_No_Caching);
-
- if Present (Prag) then
- Analyze_External_Property_In_Decl_Part (Prag, NC_Val);
- end if;
-
-- Constant-related checks
if Ekind (Obj_Id) = E_Constant then
@@ -1685,6 +1691,10 @@ package body Contracts is
Set_Debug_Info_Needed (Wrapper_Id);
Set_Wrapped_Statements (Subp_Id, Wrapper_Id);
+ Set_Has_Pragma_Inline (Wrapper_Id, Has_Pragma_Inline (Subp_Id));
+ Set_Has_Pragma_Inline_Always
+ (Wrapper_Id, Has_Pragma_Inline_Always (Subp_Id));
+
-- Create specification and declaration for the wrapper
if No (Ret_Type) or else Ret_Type = Standard_Void_Type then
@@ -1713,20 +1723,6 @@ package body Contracts is
Make_Handled_Sequence_Of_Statements (Loc,
End_Label => Make_Identifier (Loc, Chars (Wrapper_Id))));
- -- Move certain flags which are relevant to the body
-
- -- Wouldn't a better way be to perform some sort of copy of Body_Decl
- -- for Wrapper_Body be less error-prone ???
-
- if Was_Expression_Function (Body_Decl) then
- Set_Was_Expression_Function (Body_Decl, False);
- Set_Was_Expression_Function (Wrapper_Body);
- end if;
-
- Set_Has_Pragma_Inline (Wrapper_Id, Has_Pragma_Inline (Subp_Id));
- Set_Has_Pragma_Inline_Always
- (Wrapper_Id, Has_Pragma_Inline_Always (Subp_Id));
-
-- Prepend a call to the wrapper when the subprogram is a procedure
if No (Ret_Type) or else Ret_Type = Standard_Void_Type then
@@ -4548,242 +4544,10 @@ package body Contracts is
procedure Merge_Class_Conditions (Spec_Id : Entity_Id) is
- procedure Preanalyze_Condition
- (Subp : Entity_Id;
- Expr : Node_Id);
- -- Preanalyze the class-wide condition Expr of Subp
-
procedure Process_Inherited_Conditions (Kind : Condition_Kind);
-- Collect all inherited class-wide conditions of Spec_Id and merge
-- them into one big condition.
- --------------------------
- -- Preanalyze_Condition --
- --------------------------
-
- procedure Preanalyze_Condition
- (Subp : Entity_Id;
- Expr : Node_Id)
- is
- procedure Clear_Unset_References;
- -- Clear unset references on formals of Subp since preanalysis
- -- occurs in a place unrelated to the actual code.
-
- procedure Remove_Controlling_Arguments;
- -- Traverse Expr and clear the Controlling_Argument of calls to
- -- nonabstract functions.
-
- procedure Remove_Formals (Id : Entity_Id);
- -- Remove formals from homonym chains and make them not visible
-
- procedure Restore_Original_Selected_Component;
- -- Traverse Expr searching for dispatching calls to functions whose
- -- original node was a selected component, and replace them with
- -- their original node.
-
- ----------------------------
- -- Clear_Unset_References --
- ----------------------------
-
- procedure Clear_Unset_References is
- F : Entity_Id := First_Formal (Subp);
-
- begin
- while Present (F) loop
- Set_Unset_Reference (F, Empty);
- Next_Formal (F);
- end loop;
- end Clear_Unset_References;
-
- ----------------------------------
- -- Remove_Controlling_Arguments --
- ----------------------------------
-
- procedure Remove_Controlling_Arguments is
- function Remove_Ctrl_Arg (N : Node_Id) return Traverse_Result;
- -- Reset the Controlling_Argument of calls to nonabstract
- -- function calls.
-
- ---------------------
- -- Remove_Ctrl_Arg --
- ---------------------
-
- function Remove_Ctrl_Arg (N : Node_Id) return Traverse_Result is
- begin
- if Nkind (N) = N_Function_Call
- and then Present (Controlling_Argument (N))
- and then not Is_Abstract_Subprogram (Entity (Name (N)))
- then
- Set_Controlling_Argument (N, Empty);
- end if;
-
- return OK;
- end Remove_Ctrl_Arg;
-
- procedure Remove_Ctrl_Args is new Traverse_Proc (Remove_Ctrl_Arg);
- begin
- Remove_Ctrl_Args (Expr);
- end Remove_Controlling_Arguments;
-
- --------------------
- -- Remove_Formals --
- --------------------
-
- procedure Remove_Formals (Id : Entity_Id) is
- F : Entity_Id := First_Formal (Id);
-
- begin
- while Present (F) loop
- Set_Is_Immediately_Visible (F, False);
- Remove_Homonym (F);
- Next_Formal (F);
- end loop;
- end Remove_Formals;
-
- -----------------------------------------
- -- Restore_Original_Selected_Component --
- -----------------------------------------
-
- procedure Restore_Original_Selected_Component is
- Restored_Nodes_List : Elist_Id := No_Elist;
-
- procedure Fix_Parents (N : Node_Id);
- -- Traverse the subtree of N fixing the Parent field of all the
- -- nodes.
-
- function Restore_Node (N : Node_Id) return Traverse_Result;
- -- Process dispatching calls to functions whose original node was
- -- a selected component, and replace them with their original
- -- node. Restored nodes are stored in the Restored_Nodes_List
- -- to fix the parent fields of their subtrees in a separate
- -- tree traversal.
-
- -----------------
- -- Fix_Parents --
- -----------------
-
- procedure Fix_Parents (N : Node_Id) is
-
- function Fix_Parent
- (Parent_Node : Node_Id;
- Node : Node_Id) return Traverse_Result;
- -- Process a single node
-
- ----------------
- -- Fix_Parent --
- ----------------
-
- function Fix_Parent
- (Parent_Node : Node_Id;
- Node : Node_Id) return Traverse_Result
- is
- Par : constant Node_Id := Parent (Node);
-
- begin
- if Par /= Parent_Node then
- pragma Assert (not Is_List_Member (Node));
- Set_Parent (Node, Parent_Node);
- end if;
-
- return OK;
- end Fix_Parent;
-
- procedure Fix_Parents is
- new Traverse_Proc_With_Parent (Fix_Parent);
-
- begin
- Fix_Parents (N);
- end Fix_Parents;
-
- ------------------
- -- Restore_Node --
- ------------------
-
- function Restore_Node (N : Node_Id) return Traverse_Result is
- begin
- if Nkind (N) = N_Function_Call
- and then Nkind (Original_Node (N)) = N_Selected_Component
- and then Is_Dispatching_Operation (Entity (Name (N)))
- then
- Rewrite (N, Original_Node (N));
- Set_Original_Node (N, N);
-
- -- Save the restored node in the Restored_Nodes_List to fix
- -- the parent fields of their subtrees in a separate tree
- -- traversal.
-
- Append_New_Elmt (N, Restored_Nodes_List);
- end if;
-
- return OK;
- end Restore_Node;
-
- procedure Restore_Nodes is new Traverse_Proc (Restore_Node);
-
- -- Start of processing for Restore_Original_Selected_Component
-
- begin
- Restore_Nodes (Expr);
-
- -- After restoring the original node we must fix the decoration
- -- of the Parent attribute to ensure tree consistency; required
- -- because when the class-wide condition is inherited, calls to
- -- New_Copy_Tree will perform copies of this subtree, and formal
- -- occurrences with wrong Parent field cannot be mapped to the
- -- new formals.
-
- if Present (Restored_Nodes_List) then
- declare
- Elmt : Elmt_Id := First_Elmt (Restored_Nodes_List);
-
- begin
- while Present (Elmt) loop
- Fix_Parents (Node (Elmt));
- Next_Elmt (Elmt);
- end loop;
- end;
- end if;
- end Restore_Original_Selected_Component;
-
- -- Start of processing for Preanalyze_Condition
-
- begin
- pragma Assert (Present (Expr));
- pragma Assert (Inside_Class_Condition_Preanalysis = False);
-
- Push_Scope (Subp);
- Install_Formals (Subp);
- Inside_Class_Condition_Preanalysis := True;
-
- Preanalyze_And_Resolve (Expr, Standard_Boolean);
-
- Inside_Class_Condition_Preanalysis := False;
- Remove_Formals (Subp);
- Pop_Scope;
-
- -- If this preanalyzed condition has occurrences of dispatching calls
- -- using the Object.Operation notation, during preanalysis such calls
- -- are rewritten as dispatching function calls; if at later stages
- -- this condition is inherited we must have restored the original
- -- selected-component node to ensure that the preanalysis of the
- -- inherited condition rewrites these dispatching calls in the
- -- correct context to avoid reporting spurious errors.
-
- Restore_Original_Selected_Component;
-
- -- Traverse Expr and clear the Controlling_Argument of calls to
- -- nonabstract functions. Required since the preanalyzed condition
- -- is not yet installed on its definite context and will be cloned
- -- and extended in derivations with additional conditions.
-
- Remove_Controlling_Arguments;
-
- -- Clear also attribute Unset_Reference; again because preanalysis
- -- occurs in a place unrelated to the actual code.
-
- Clear_Unset_References;
- end Preanalyze_Condition;
-
----------------------------------
-- Process_Inherited_Conditions --
----------------------------------
@@ -5116,6 +4880,250 @@ package body Contracts is
end loop;
end Merge_Class_Conditions;
+ ---------------------------------
+ -- Preanalyze_Class_Conditions --
+ ---------------------------------
+
+ procedure Preanalyze_Class_Conditions (Spec_Id : Entity_Id) is
+ Cond : Node_Id;
+
+ begin
+ for Kind in Condition_Kind loop
+ Cond := Class_Condition (Kind, Spec_Id);
+
+ if Present (Cond) then
+ Preanalyze_Condition (Spec_Id, Cond);
+ end if;
+ end loop;
+ end Preanalyze_Class_Conditions;
+
+ --------------------------
+ -- Preanalyze_Condition --
+ --------------------------
+
+ procedure Preanalyze_Condition
+ (Subp : Entity_Id;
+ Expr : Node_Id)
+ is
+ procedure Clear_Unset_References;
+ -- Clear unset references on formals of Subp since preanalysis
+ -- occurs in a place unrelated to the actual code.
+
+ procedure Remove_Controlling_Arguments;
+ -- Traverse Expr and clear the Controlling_Argument of calls to
+ -- nonabstract functions.
+
+ procedure Remove_Formals (Id : Entity_Id);
+ -- Remove formals from homonym chains and make them not visible
+
+ procedure Restore_Original_Selected_Component;
+ -- Traverse Expr searching for dispatching calls to functions whose
+ -- original node was a selected component, and replace them with
+ -- their original node.
+
+ ----------------------------
+ -- Clear_Unset_References --
+ ----------------------------
+
+ procedure Clear_Unset_References is
+ F : Entity_Id := First_Formal (Subp);
+
+ begin
+ while Present (F) loop
+ Set_Unset_Reference (F, Empty);
+ Next_Formal (F);
+ end loop;
+ end Clear_Unset_References;
+
+ ----------------------------------
+ -- Remove_Controlling_Arguments --
+ ----------------------------------
+
+ procedure Remove_Controlling_Arguments is
+ function Remove_Ctrl_Arg (N : Node_Id) return Traverse_Result;
+ -- Reset the Controlling_Argument of calls to nonabstract
+ -- function calls.
+
+ ---------------------
+ -- Remove_Ctrl_Arg --
+ ---------------------
+
+ function Remove_Ctrl_Arg (N : Node_Id) return Traverse_Result is
+ begin
+ if Nkind (N) = N_Function_Call
+ and then Present (Controlling_Argument (N))
+ and then not Is_Abstract_Subprogram (Entity (Name (N)))
+ then
+ Set_Controlling_Argument (N, Empty);
+ end if;
+
+ return OK;
+ end Remove_Ctrl_Arg;
+
+ procedure Remove_Ctrl_Args is new Traverse_Proc (Remove_Ctrl_Arg);
+ begin
+ Remove_Ctrl_Args (Expr);
+ end Remove_Controlling_Arguments;
+
+ --------------------
+ -- Remove_Formals --
+ --------------------
+
+ procedure Remove_Formals (Id : Entity_Id) is
+ F : Entity_Id := First_Formal (Id);
+
+ begin
+ while Present (F) loop
+ Set_Is_Immediately_Visible (F, False);
+ Remove_Homonym (F);
+ Next_Formal (F);
+ end loop;
+ end Remove_Formals;
+
+ -----------------------------------------
+ -- Restore_Original_Selected_Component --
+ -----------------------------------------
+
+ procedure Restore_Original_Selected_Component is
+ Restored_Nodes_List : Elist_Id := No_Elist;
+
+ procedure Fix_Parents (N : Node_Id);
+ -- Traverse the subtree of N fixing the Parent field of all the
+ -- nodes.
+
+ function Restore_Node (N : Node_Id) return Traverse_Result;
+ -- Process dispatching calls to functions whose original node was
+ -- a selected component, and replace them with their original
+ -- node. Restored nodes are stored in the Restored_Nodes_List
+ -- to fix the parent fields of their subtrees in a separate
+ -- tree traversal.
+
+ -----------------
+ -- Fix_Parents --
+ -----------------
+
+ procedure Fix_Parents (N : Node_Id) is
+
+ function Fix_Parent
+ (Parent_Node : Node_Id;
+ Node : Node_Id) return Traverse_Result;
+ -- Process a single node
+
+ ----------------
+ -- Fix_Parent --
+ ----------------
+
+ function Fix_Parent
+ (Parent_Node : Node_Id;
+ Node : Node_Id) return Traverse_Result
+ is
+ Par : constant Node_Id := Parent (Node);
+
+ begin
+ if Par /= Parent_Node then
+ pragma Assert (not Is_List_Member (Node));
+ Set_Parent (Node, Parent_Node);
+ end if;
+
+ return OK;
+ end Fix_Parent;
+
+ procedure Fix_Parents is
+ new Traverse_Proc_With_Parent (Fix_Parent);
+
+ begin
+ Fix_Parents (N);
+ end Fix_Parents;
+
+ ------------------
+ -- Restore_Node --
+ ------------------
+
+ function Restore_Node (N : Node_Id) return Traverse_Result is
+ begin
+ if Nkind (N) = N_Function_Call
+ and then Nkind (Original_Node (N)) = N_Selected_Component
+ and then Is_Dispatching_Operation (Entity (Name (N)))
+ then
+ Rewrite (N, Original_Node (N));
+ Set_Original_Node (N, N);
+
+ -- Save the restored node in the Restored_Nodes_List to fix
+ -- the parent fields of their subtrees in a separate tree
+ -- traversal.
+
+ Append_New_Elmt (N, Restored_Nodes_List);
+ end if;
+
+ return OK;
+ end Restore_Node;
+
+ procedure Restore_Nodes is new Traverse_Proc (Restore_Node);
+
+ -- Start of processing for Restore_Original_Selected_Component
+
+ begin
+ Restore_Nodes (Expr);
+
+ -- After restoring the original node we must fix the decoration
+ -- of the Parent attribute to ensure tree consistency; required
+ -- because when the class-wide condition is inherited, calls to
+ -- New_Copy_Tree will perform copies of this subtree, and formal
+ -- occurrences with wrong Parent field cannot be mapped to the
+ -- new formals.
+
+ if Present (Restored_Nodes_List) then
+ declare
+ Elmt : Elmt_Id := First_Elmt (Restored_Nodes_List);
+
+ begin
+ while Present (Elmt) loop
+ Fix_Parents (Node (Elmt));
+ Next_Elmt (Elmt);
+ end loop;
+ end;
+ end if;
+ end Restore_Original_Selected_Component;
+
+ -- Start of processing for Preanalyze_Condition
+
+ begin
+ pragma Assert (Present (Expr));
+ pragma Assert (Inside_Class_Condition_Preanalysis = False);
+
+ Push_Scope (Subp);
+ Install_Formals (Subp);
+ Inside_Class_Condition_Preanalysis := True;
+
+ Preanalyze_Spec_Expression (Expr, Standard_Boolean);
+
+ Inside_Class_Condition_Preanalysis := False;
+ Remove_Formals (Subp);
+ Pop_Scope;
+
+ -- If this preanalyzed condition has occurrences of dispatching calls
+ -- using the Object.Operation notation, during preanalysis such calls
+ -- are rewritten as dispatching function calls; if at later stages
+ -- this condition is inherited we must have restored the original
+ -- selected-component node to ensure that the preanalysis of the
+ -- inherited condition rewrites these dispatching calls in the
+ -- correct context to avoid reporting spurious errors.
+
+ Restore_Original_Selected_Component;
+
+ -- Traverse Expr and clear the Controlling_Argument of calls to
+ -- nonabstract functions. Required since the preanalyzed condition
+ -- is not yet installed on its definite context and will be cloned
+ -- and extended in derivations with additional conditions.
+
+ Remove_Controlling_Arguments;
+
+ -- Clear also attribute Unset_Reference; again because preanalysis
+ -- occurs in a place unrelated to the actual code.
+
+ Clear_Unset_References;
+ end Preanalyze_Condition;
+
----------------------------------------
-- Save_Global_References_In_Contract --
----------------------------------------
diff --git a/gcc/ada/contracts.ads b/gcc/ada/contracts.ads
index bde32ff..ae6355e 100644
--- a/gcc/ada/contracts.ads
+++ b/gcc/ada/contracts.ads
@@ -276,6 +276,10 @@ package Contracts is
-- which are invoked from the caller side; they are also used to build
-- the dispatch-table wrapper (DTW), if required.
+ procedure Preanalyze_Class_Conditions (Spec_Id : Entity_Id);
+ -- Preanalyze class-wide pre-/postconditions of the given subprogram
+ -- specification.
+
procedure Process_Class_Conditions_At_Freeze_Point (Typ : Entity_Id);
-- Merge, preanalyze, and check class-wide pre/postconditions of Typ
-- primitives.
diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb
index 94e729e..d84d114 100644
--- a/gcc/ada/debug.adb
+++ b/gcc/ada/debug.adb
@@ -189,7 +189,7 @@ package body Debug is
-- d_U Disable prepending messages with "error:".
-- d_V Enable verifications on the expanded tree
-- d_W
- -- d_X
+ -- d_X Disable assertions to check matching of extra formals
-- d_Y
-- d_Z
@@ -1044,6 +1044,10 @@ package body Debug is
-- d_V Enable verification of the expanded code before calling the backend
-- and generate error messages on each inconsistency found.
+ -- d_X Disable assertions to check matching of extra formals; switch added
+ -- temporarily to disable these checks until this work is complete if
+ -- they cause unexpected assertion failures.
+
-- d1 Error messages have node numbers where possible. Normally error
-- messages have only source locations. This option is useful when
-- debugging errors caused by expanded code, where the source location
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_aspects.rst b/gcc/ada/doc/gnat_rm/implementation_defined_aspects.rst
index 4541f2b..960c505 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_aspects.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_aspects.rst
@@ -422,7 +422,7 @@ This aspect is equivalent to :ref:`attribute Object_Size<Attribute-Object_Size>`
Aspect Obsolescent
==================
-.. index:: Obsolsecent
+.. index:: Obsolescent
This aspect is equivalent to :ref:`pragma Obsolescent<Pragma_Obsolescent>`. Note that the
evaluation of this aspect happens at the point of occurrence, it is not
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
index d839b1f..22dae06 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
@@ -589,7 +589,7 @@ Attribute Library_Level
``P'Library_Level``, where P is an entity name,
returns a Boolean value which is True if the entity is declared
at the library level, and False otherwise. Note that within a
-generic instantition, the name of the generic unit denotes the
+generic instantiation, the name of the generic unit denotes the
instance, which means that this attribute can be used to test
if a generic is instantiated at the library level, as shown
in this example:
@@ -1231,7 +1231,7 @@ Attribute System_Allocator_Alignment
.. index:: System_Allocator_Alignment
``Standard'System_Allocator_Alignment`` (``Standard`` is the only
-allowed prefix) provides the observable guaranted to be honored by
+allowed prefix) provides the observable guaranteed to be honored by
the system allocator (malloc). This is a static value that can be used
in user storage pools based on malloc either to reject allocation
with alignment too large or to enable a realignment circuitry if the
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst b/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst
index 095d04b..fb6a63c 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst
@@ -1215,7 +1215,7 @@ a distributed application.
*
"The range of type System.RPC.Partition_Id. See E.5(14)."
-System.RPC.Partion_ID'Last is Integer'Last. See source file :file:`s-rpc.ads`.
+System.RPC.Partition_ID'Last is Integer'Last. See source file :file:`s-rpc.ads`.
*
"Implementation-defined interfaces in the PCS. See E.5(26)."
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
index 6752d48..ed42d08 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
@@ -1389,7 +1389,7 @@ Pragma CPP_Virtual
This pragma is now obsolete and, other than generating a warning if warnings
on obsolescent features are enabled, is completely ignored.
It is retained for compatibility
-purposes. It used to be required to ensure compoatibility with C++, but
+purposes. It used to be required to ensure compatibility with C++, but
is no longer required for that purpose because GNAT generates
the same object layout as the G++ compiler by default.
@@ -1438,20 +1438,6 @@ This pragma applies only to protected types and specifies the floor
deadline inherited by a task when the task enters a protected object.
It is effective only when the EDF scheduling policy is used.
-.. _Pragma-Default_Initial_Condition:
-
-Pragma Default_Initial_Condition
-================================
-
-Syntax:
-
-.. code-block:: ada
-
- pragma Default_Initial_Condition [ (null | boolean_EXPRESSION) ];
-
-For the semantics of this pragma, see the entry for aspect
-``Default_Initial_Condition`` in the SPARK 2014 Reference Manual, section 7.3.3.
-
Pragma Debug
============
@@ -1495,6 +1481,20 @@ This pragma is equivalent to a corresponding ``Check_Policy`` pragma
with a first argument of ``Debug``. It is retained for historical
compatibility reasons.
+.. _Pragma-Default_Initial_Condition:
+
+Pragma Default_Initial_Condition
+================================
+
+Syntax:
+
+.. code-block:: ada
+
+ pragma Default_Initial_Condition [ (null | boolean_EXPRESSION) ];
+
+For the semantics of this pragma, see the entry for aspect
+``Default_Initial_Condition`` in the SPARK 2014 Reference Manual, section 7.3.3.
+
Pragma Default_Scalar_Storage_Order
===================================
.. index:: Default_Scalar_Storage_Order
@@ -2174,16 +2174,19 @@ Syntax:
.. code-block:: ada
- pragma Extensions_Allowed (On | Off);
+ pragma Extensions_Allowed (On | Off | All);
-This configuration pragma enables or disables the implementation
-extension mode (the use of Off as a parameter cancels the effect
-of the *-gnatX* command switch).
+This configuration pragma enables (via the "On" or "All" argument) or disables
+(via the "Off" argument) the implementation extension mode; the pragma takes
+precedence over the *-gnatX* and *-gnatX0* command switches.
-In extension mode, the latest version of the Ada language is
-implemented (currently Ada 2022), and in addition a number
-of GNAT specific extensions are recognized as follows:
+If an argument of "All" is specified, the latest version of the Ada language
+is implemented (currently Ada 2022) and, in addition, a number
+of GNAT specific extensions are recognized. These extensions are listed
+below. An argument of "On" has the same effect except that only
+some, not all, of the listed extensions are enabled; those extensions
+are identified below.
* Constrained attribute for generic objects
@@ -2197,10 +2200,7 @@ of GNAT specific extensions are recognized as follows:
functions and the compiler will evaluate some of these intrinsic statically,
in particular the ``Shift_Left`` and ``Shift_Right`` intrinsics.
-* ``'Reduce`` attribute
-
- This attribute part of the Ada 202x language definition is provided for
- now under -gnatX to confirm and potentially refine its usage and syntax.
+ An Extensions_Allowed pragma argument of "On" enables this extension.
* ``[]`` aggregates
@@ -2334,6 +2334,8 @@ of GNAT specific extensions are recognized as follows:
for a given identifer must all statically match. Currently, the case
of a binding for a nondiscrete component is not implemented.
+ An Extensions_Allowed pragma argument of "On" enables this extension.
+
* Fixed lower bounds for array types and subtypes
Unconstrained array types and subtypes can be specified with a lower bound
@@ -2378,6 +2380,8 @@ 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.
+ An Extensions_Allowed pragma argument of "On" enables this extension.
+
* Prefixed-view notation for calls to primitive subprograms of untagged types
Since Ada 2005, calls to primitive subprograms of a tagged type that
@@ -2395,6 +2399,8 @@ of GNAT specific extensions are recognized as follows:
name, preference is given to the component in a selected_component
(as is currently the case for tagged types with such component names).
+ An Extensions_Allowed pragma argument of "On" enables this extension.
+
* Expression defaults for generic formal functions
The declaration of a generic formal function is allowed to specify
@@ -3866,7 +3872,7 @@ decrease or increase in successive iterations of the loop. In its simplest
form, just one expression is specified, whose value must increase or decrease
on each iteration of the loop.
-In a more complex form, multiple arguments can be given which are intepreted
+In a more complex form, multiple arguments can be given which are interpreted
in a nesting lexicographic manner. For example:
.. code-block:: ada
@@ -4634,6 +4640,22 @@ even though
RM 8.3 (15) stipulates that an overridden operation is not visible within the
declaration of the overriding operation.
+.. _Pragma-Part_Of:
+
+Pragma Part_Of
+==============
+
+Syntax:
+
+.. code-block:: ada
+
+ pragma Part_Of (ABSTRACT_STATE);
+
+ ABSTRACT_STATE ::= NAME
+
+For the semantics of this pragma, see the entry for aspect ``Part_Of`` in the
+SPARK 2014 Reference Manual, section 7.2.6.
+
Pragma Partition_Elaboration_Policy
===================================
@@ -4651,22 +4673,6 @@ This pragma is standard in Ada 2005, but is available in all earlier
versions of Ada as an implementation-defined pragma.
See Ada 2012 Reference Manual for details.
-.. _Pragma-Part_Of:
-
-Pragma Part_Of
-==============
-
-Syntax:
-
-.. code-block:: ada
-
- pragma Part_Of (ABSTRACT_STATE);
-
- ABSTRACT_STATE ::= NAME
-
-For the semantics of this pragma, see the entry for aspect ``Part_Of`` in the
-SPARK 2014 Reference Manual, section 7.2.6.
-
Pragma Passive
==============
@@ -4947,7 +4953,7 @@ appear at the start of the declarations in a subprogram body
Note: This pragma is called ``Post_Class`` rather than
``Post'Class`` because the latter would not be strictly
conforming to the allowed syntax for pragmas. The motivation
-for provinding pragmas equivalent to the aspects is to allow a program
+for providing pragmas equivalent to the aspects is to allow a program
to be written using the pragmas, and then compiled if necessary
using an Ada compiler that does not recognize the pragmas or
aspects, but is prepared to ignore the pragmas. The assertion
@@ -6213,7 +6219,7 @@ replacement of any dots in the unit name by the specified string literal.
Note that Source_File_Name pragmas should not be used if you are using
project files. The reason for this rule is that the project manager is not
-aware of these pragmas, and so other tools that use the projet file would not
+aware of these pragmas, and so other tools that use the project file would not
be aware of the intended naming conventions. If you are using project files,
file naming is controlled by Source_File_Name_Project pragmas, which are
usually supplied automatically by the project manager. A pragma
@@ -6869,7 +6875,7 @@ Syntax:
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" (``TLS``). On systems supporting this (which
-include Windows, Solaris, GNU/Linux, and VxWorks 6), this causes each
+include Windows, Solaris, GNU/Linux, and VxWorks), this causes each
thread (and hence each Ada task) to see a distinct copy of the variable.
The variable must not have default initialization, and if there is
@@ -7287,33 +7293,10 @@ configuration pragma will ensure this test is not suppressed:
This pragma is standard in Ada 2005. It is available in all earlier versions
of Ada as an implementation-defined pragma.
-Note that in addition to the checks defined in the Ada RM, GNAT recogizes a
+Note that in addition to the checks defined in the Ada RM, GNAT recognizes a
number of implementation-defined check names. See the description of pragma
``Suppress`` for full details.
-Pragma Use_VADS_Size
-====================
-.. index:: Size, VADS compatibility
-
-.. index:: Rational profile
-
-
-Syntax:
-
-
-.. code-block:: ada
-
- pragma Use_VADS_Size;
-
-
-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
-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.
-
.. _Pragma-Unused:
Pragma Unused
@@ -7348,6 +7331,29 @@ are typically to be used in cases where such warnings are expected.
Thus it is never necessary to use ``pragma Unused`` for such
variables, though it is harmless to do so.
+Pragma Use_VADS_Size
+====================
+.. index:: Size, VADS compatibility
+
+.. index:: Rational profile
+
+
+Syntax:
+
+
+.. code-block:: ada
+
+ pragma Use_VADS_Size;
+
+
+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
+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.
+
Pragma Validity_Checks
======================
@@ -7588,7 +7594,7 @@ expression (which does not exist in Ada 83).
Note if the second argument of ``DETAILS`` is a ``local_NAME`` then the
second form is always understood. If the intention is to use
the fourth form, then you can write ``NAME & ""`` to force the
-intepretation as a *static_string_EXPRESSION*.
+interpretation as a *static_string_EXPRESSION*.
Note: if the first argument is a valid ``TOOL_NAME``, it will be interpreted
that way. The use of the ``TOOL_NAME`` argument is relevant only to users
diff --git a/gcc/ada/doc/gnat_rm/security_hardening_features.rst b/gcc/ada/doc/gnat_rm/security_hardening_features.rst
index d7c02b9..ad165cd 100644
--- a/gcc/ada/doc/gnat_rm/security_hardening_features.rst
+++ b/gcc/ada/doc/gnat_rm/security_hardening_features.rst
@@ -383,11 +383,127 @@ For each block that is marked as visited, the mechanism checks that at
least one of its predecessors, and at least one of its successors, are
also marked as visited.
-Verification is performed just before returning. Subprogram
-executions that complete by raising or propagating an exception bypass
-verification-and-return points. A subprogram that can only complete
-by raising or propagating an exception may have instrumentation
-disabled altogether.
+Verification is performed just before a subprogram returns. The
+following fragment:
+
+.. code-block:: ada
+
+ if X then
+ Y := F (Z);
+ return;
+ end if;
+
+
+gets turned into:
+
+.. code-block:: ada
+
+ type Visited_Bitmap is array (1..N) of Boolean with Pack;
+ Visited : aliased Visited_Bitmap := (others => False);
+ -- Bitmap of visited blocks. N is the basic block count.
+ [...]
+ -- Basic block #I
+ Visited(I) := True;
+ if X then
+ -- Basic block #J
+ Visited(J) := True;
+ Y := F (Z);
+ CFR.Check (N, Visited'Access, CFG'Access);
+ -- CFR is a hypothetical package whose Check procedure calls
+ -- libgcc's __hardcfr_check, that traps if the Visited bitmap
+ -- does not hold a valid path in CFG, the run-time
+ -- representation of the control flow graph in the enclosing
+ -- subprogram.
+ return;
+ end if;
+ -- Basic block #K
+ Visited(K) := True;
+
+
+Verification would also be performed before tail calls, if any
+front-ends marked them as mandatory or desirable, but none do.
+Regular calls are optimized into tail calls too late for this
+transformation to act on it.
+
+In order to avoid adding verification after potential tail calls,
+which would prevent tail-call optimization, we recognize returning
+calls, i.e., calls whose result, if any, is returned by the calling
+subprogram to its caller immediately after the call returns.
+Verification is performed before such calls, whether or not they are
+ultimately optimized to tail calls. This behavior is enabled by
+default whenever sibcall optimization is enabled (see
+:switch:`-foptimize-sibling-calls`); it may be disabled with
+:switch:`-fno-hardcfr-check-returning-calls`, or enabled with
+:switch:`-fhardcfr-check-returning-calls`, regardless of the
+optimization, but the lack of other optimizations may prevent calls
+from being recognized as returning calls:
+
+.. code-block:: ada
+
+ -- CFR.Check here, with -fhardcfr-check-returning-calls.
+ P (X);
+ -- CFR.Check here, with -fno-hardcfr-check-returning-calls.
+ return;
+
+or:
+
+.. code-block:: ada
+
+ -- CFR.Check here, with -fhardcfr-check-returning-calls.
+ R := F (X);
+ -- CFR.Check here, with -fno-hardcfr-check-returning-calls.
+ return R;
+
+
+Any subprogram from which an exception may escape, i.e., that may
+raise or propagate an exception that isn't handled internally, is
+conceptually enclosed by a cleanup handler that performs verification,
+unless this is disabled with :switch:`-fno-hardcfr-check-exceptions`.
+With this feature enabled, a subprogram body containing:
+
+.. code-block:: ada
+
+ -- ...
+ Y := F (X); -- May raise exceptions.
+ -- ...
+ raise E; -- Not handled internally.
+ -- ...
+
+
+gets modified as follows:
+
+.. code-block:: ada
+
+ begin
+ -- ...
+ Y := F (X); -- May raise exceptions.
+ -- ...
+ raise E; -- Not handled internally.
+ -- ...
+ exception
+ when others =>
+ CFR.Check (N, Visited'Access, CFG'Access);
+ raise;
+ end;
+
+
+Verification may also be performed before No_Return calls, whether
+only nothrow ones, with
+:switch:`-fhardcfr-check-noreturn-calls=nothrow`, or all of them, with
+:switch:`-fhardcfr-check-noreturn-calls=always`. The default is
+:switch:`-fhardcfr-check-noreturn-calls=never` for this feature, that
+disables checking before No_Return calls.
+
+When a No_Return call returns control to its caller through an
+exception, verification may have already been performed before the
+call, if :switch:`-fhardcfr-check-noreturn-calls=always` is in effect.
+The compiler arranges for already-checked No_Return calls without a
+preexisting handler to bypass the implicitly-added cleanup handler and
+thus the redundant check, but a local exception or cleanup handler, if
+present, will modify the set of visited blocks, and checking will take
+place again when the caller reaches the next verification point,
+whether it is a return or reraise statement after the exception is
+otherwise handled, or even another No_Return call.
The instrumentation for hardening with control flow redundancy can be
observed in dump files generated by the command-line option
diff --git a/gcc/ada/doc/gnat_rm/standard_library_routines.rst b/gcc/ada/doc/gnat_rm/standard_library_routines.rst
index 398b613..27659a4 100644
--- a/gcc/ada/doc/gnat_rm/standard_library_routines.rst
+++ b/gcc/ada/doc/gnat_rm/standard_library_routines.rst
@@ -157,7 +157,7 @@ the unit is not implemented.
``Ada.Directories.Hierarchical_File_Names`` *(A.16.1)*
This package provides additional directory operations handling
- hiearchical file names.
+ hierarchical file names.
``Ada.Directories.Information`` *(A.16)*
@@ -550,7 +550,7 @@ the unit is not implemented.
This package provides the capability of associating arbitrary
task-specific data with separate tasks.
-``Ada.Task_Identifification`` *(C.7.1)*
+``Ada.Task_Identification`` *(C.7.1)*
This package provides capabilities for task identification.
``Ada.Task_Termination`` *(C.7.3)*
diff --git a/gcc/ada/doc/gnat_rm/the_gnat_library.rst b/gcc/ada/doc/gnat_rm/the_gnat_library.rst
index d791f81..3aae70a 100644
--- a/gcc/ada/doc/gnat_rm/the_gnat_library.rst
+++ b/gcc/ada/doc/gnat_rm/the_gnat_library.rst
@@ -47,7 +47,7 @@ of GNAT, and will generate a warning message.
This child of ``Ada.Characters``
provides a set of definitions corresponding to those in the
RM-defined package ``Ada.Characters.Latin_1`` but with the
-few modifications required for ``Latin-9``
+few modifications required for ``Latin-9``.
The provision of such a package
is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
@@ -69,12 +69,12 @@ instead of ``Character``. The provision of such a package
is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
-.. _`Ada.Characters.Wide_Latin_9_(a-cwila1.ads)`:
+.. _`Ada.Characters.Wide_Latin_9_(a-cwila9.ads)`:
-``Ada.Characters.Wide_Latin_9`` (:file:`a-cwila1.ads`)
+``Ada.Characters.Wide_Latin_9`` (:file:`a-cwila9.ads`)
======================================================
-.. index:: Ada.Characters.Wide_Latin_9 (a-cwila1.ads)
+.. index:: Ada.Characters.Wide_Latin_9 (a-cwila9.ads)
.. index:: Latin_9 constants for Wide_Character
@@ -159,8 +159,8 @@ where this concept makes sense.
This child of ``Ada.Command_Line``
provides a mechanism for logically removing
arguments from the argument list. Once removed, an argument is not visible
-to further calls on the subprograms in ``Ada.Command_Line`` will not
-see the removed argument.
+to further calls to the subprograms in ``Ada.Command_Line``. These calls
+will not see the removed argument.
.. _`Ada.Command_Line.Response_File_(a-clrefi.ads)`:
@@ -833,7 +833,7 @@ obtaining information about exceptions provided by Ada 83 compilers.
.. index:: Memory corruption debugging
-Provide a debugging storage pools that helps tracking memory corruption
+Provides a debugging storage pools that helps tracking memory corruption
problems.
See ``The GNAT Debug_Pool Facility`` section in the :title:`GNAT User's Guide`.
@@ -1043,7 +1043,7 @@ a message from a subprogram in a pure package, since the
necessary types and subprograms are in ``Ada.Exceptions``
which is not a pure unit. ``GNAT.Exceptions`` provides a
facility for getting around this limitation for a few
-predefined exceptions, and for example allow raising
+predefined exceptions, and for example allows raising
``Constraint_Error`` with a message from a pure subprogram.
.. _`GNAT.Expect_(g-expect.ads)`:
@@ -1098,7 +1098,7 @@ in this package can be used to reestablish the required mode.
.. index:: Formatted String
Provides support for C/C++ printf() formatted strings. The format is
-copied from the printf() routine and should therefore gives identical
+copied from the printf() routine and should therefore give identical
output. Some generic routines are provided to be able to use types
derived from Integer, Float or enumerations as values for the
formatted string.
@@ -1314,7 +1314,7 @@ Provides a generator of static minimal perfect hash functions. No
collisions occur and each item can be retrieved from the table in one
probe (perfect property). The hash table size corresponds to the exact
size of the key set and no larger (minimal property). The key set has to
-be know in advance (static property). The hash functions are also order
+be known in advance (static property). The hash functions are also order
preserving. If w2 is inserted after w1 in the generator, their
hashcode are in the same order. These hashing functions are very
convenient for use with realtime applications.
@@ -1399,7 +1399,7 @@ this interface usable for large files or socket streams.
.. index:: Secondary Stack Info
-Provide the capability to query the high water mark of the current task's
+Provides the capability to query the high water mark of the current task's
secondary stack.
.. _`GNAT.Semaphores_(g-semaph.ads)`:
@@ -1514,7 +1514,7 @@ targets.
A high level and portable interface to develop sockets based applications.
This package is based on the sockets thin binding found in
``GNAT.Sockets.Thin``. Currently ``GNAT.Sockets`` is implemented
-on all native GNAT ports and on VxWorks cross prots. It is not implemented for
+on all native GNAT ports and on VxWorks cross ports. It is not implemented for
the LynxOS cross port.
.. _`GNAT.Source_Info_(g-souinf.ads)`:
@@ -1781,12 +1781,12 @@ in various debugging situations.
.. index:: Trace back facilities
-.. _`GNAT.UTF_32_(g-table.ads)`:
+.. _`GNAT.UTF_32_(g-utf_32.ads)`:
-``GNAT.UTF_32`` (:file:`g-table.ads`)
-=====================================
+``GNAT.UTF_32`` (:file:`g-utf_32.ads`)
+======================================
-.. index:: GNAT.UTF_32 (g-table.ads)
+.. index:: GNAT.UTF_32 (g-utf_32.ads)
.. index:: Wide character codes
@@ -1800,12 +1800,12 @@ lexical rules for identifiers and strings, and also a
lower case to upper case fold routine corresponding to
the Ada 2005 rules for identifier equivalence.
-.. _`GNAT.Wide_Spelling_Checker_(g-u3spch.ads)`:
+.. _`GNAT.UTF_32_Spelling_Checker_(g-u3spch.ads)`:
-``GNAT.Wide_Spelling_Checker`` (:file:`g-u3spch.ads`)
-=====================================================
+``GNAT.UTF_32_Spelling_Checker`` (:file:`g-u3spch.ads`)
+=======================================================
-.. index:: GNAT.Wide_Spelling_Checker (g-u3spch.ads)
+.. index:: GNAT.UTF_32_Spelling_Checker (g-u3spch.ads)
.. index:: Spell checking
diff --git a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
index d4bddff..fe0b567 100644
--- a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
+++ b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
@@ -2180,7 +2180,13 @@ Alphabetical List of All Switches
.. index:: -gnatX (gcc)
:switch:`-gnatX`
- Enable GNAT implementation extensions and latest Ada version.
+ Enable core GNAT implementation extensions and latest Ada version.
+
+
+.. index:: -gnatX0 (gcc)
+
+:switch:`-gnatX0`
+ Enable all GNAT implementation extensions and latest Ada version.
.. index:: -gnaty (gcc)
@@ -2789,6 +2795,8 @@ of the pragma in the :title:`GNAT_Reference_manual`).
* :switch:`-gnatw.q` (questionable layout of record types)
+ * :switch:`-gnatw_q` (ignored equality)
+
* :switch:`-gnatw_r` (out-of-order record representation clauses)
* :switch:`-gnatw.s` (overridden size clause)
@@ -2930,7 +2938,7 @@ of the pragma in the :title:`GNAT_Reference_manual`).
tests that are known to be True or False at compile time. The default
is that such warnings are not generated.
Note that this warning does
- not get issued for the use of boolean variables or constants whose
+ not get issued for the use of boolean constants whose
values are known at compile time, since this is a standard technique
for conditional compilation in Ada, and this would generate too many
false positive warnings.
@@ -3213,8 +3221,13 @@ of the pragma in the :title:`GNAT_Reference_manual`).
This switch activates warnings on component clauses in record
representation clauses that leave holes (gaps) in the record layout.
- If this warning option is active, then record representation clauses
- should specify a contiguous layout, adding unused fill fields if needed.
+ If a record representation clause does not specify a location for
+ every component of the record type, then the warnings generated (or not
+ generated) are unspecified. For example, there may be gaps for which
+ either no warning is generated or a warning is generated that
+ incorrectly describes the location of the gap. This undesirable situation
+ can sometimes be avoided by adding (and specifying the location for) unused
+ fill fields.
.. index:: -gnatw.H (gcc)
@@ -3681,6 +3694,25 @@ of the pragma in the :title:`GNAT_Reference_manual`).
a record type would very likely cause inefficiencies.
+.. index:: -gnatw_q (gcc)
+
+:switch:`-gnatw_q`
+ *Activate warnings for ignored equality operators.*
+
+ This switch activates warnings for a user-defined "=" function that does
+ not compose (i.e. is ignored for a predefined "=" for a composite type
+ containing a component whose type has the user-defined "=" as
+ primitive). Note that the user-defined "=" must be a primitive operator
+ in order to trigger the warning.
+
+ The default is that these warnings are not given.
+
+.. index:: -gnatw_Q (gcc)
+
+:switch:`-gnatw_Q`
+ *Suppress warnings for ignored equality operators.*
+
+
.. index:: -gnatwr (gcc)
:switch:`-gnatwr`
@@ -5585,16 +5617,27 @@ indicate Ada 83 compatibility mode.
language.
-.. index:: -gnatX (gcc)
+.. index:: -gnatX0 (gcc)
.. index:: Ada language extensions
.. index:: GNAT extensions
-:switch:`-gnatX` (Enable GNAT Extensions)
+:switch:`-gnatX0` (Enable GNAT Extensions)
This switch directs the compiler to implement the latest version of the
language (currently Ada 2022) and also to enable certain GNAT implementation
extensions that are not part of any Ada standard. For a full list of these
extensions, see the GNAT reference manual, ``Pragma Extensions_Allowed``.
+.. index:: -gnatX (gcc)
+.. index:: Ada language extensions
+.. index:: GNAT extensions
+
+:switch:`-gnatX` (Enable core GNAT Extensions)
+ This switch is similar to -gnatX0 except that only some, not all, of the
+ GNAT-defined language extensions are enabled. For a list of the
+ extensions enabled by this switch, see the GNAT reference manual
+ ``Pragma Extensions_Allowed`` and the description of that pragma's
+ "On" (as opposed to "All") argument.
+
.. _Character_Set_Control:
@@ -7386,7 +7429,7 @@ development environments much more flexible.
Examples of ``gnatbind`` Usage
------------------------------
-Here are some examples of ``gnatbind`` invovations:
+Here are some examples of ``gnatbind`` invocations:
::
diff --git a/gcc/ada/doc/gnat_ugn/elaboration_order_handling_in_gnat.rst b/gcc/ada/doc/gnat_ugn/elaboration_order_handling_in_gnat.rst
index 4982ebf..76a1461 100644
--- a/gcc/ada/doc/gnat_ugn/elaboration_order_handling_in_gnat.rst
+++ b/gcc/ada/doc/gnat_ugn/elaboration_order_handling_in_gnat.rst
@@ -265,7 +265,7 @@ respect to control and data flow.
Checking the Elaboration Order
==============================
-To avoid placing the entire elaboration-order burden on the programmer, Ada
+To avoid placing the entire elaboration-order burden on the programmer, Ada
provides three lines of defense:
* *Static semantics*
@@ -931,9 +931,9 @@ Resolving Elaboration Circularities
===================================
The most desirable option from the point of view of long-term maintenance is to
-rearrange the program so that the elaboration problems are avoided. One useful
-technique is to place the elaboration code into separate child packages.
-Another is to move some of the initialization code to explicitly invoked
+rearrange the program so that the elaboration problems are avoided. One useful
+technique is to place the elaboration code into separate child packages.
+Another is to move some of the initialization code to explicitly invoked
subprograms, where the program controls the order of initialization explicitly.
Although this is the most desirable option, it may be impractical and involve
too much modification, especially in the case of complex legacy code.
@@ -990,8 +990,9 @@ following tactics to eliminate the circularity:
change pragma Elaborate_All for unit "..." to Elaborate in unit "..."
This tactic is always suggested with the pragma ``Elaborate_All`` elimination
- tactic. It offers a different alernative of guaranteeing that the argument of
- the pragma will still be elaborated prior to the unit containing the pragma.
+ tactic. It offers a different alternative of guaranteeing that the argument
+ of the pragma will still be elaborated prior to the unit containing the
+ pragma.
The programmer should update the pragma as advised, and rebuild the program.
@@ -1281,7 +1282,7 @@ Summary of Procedures for Elaboration Control
A programmer should first compile the program with the default options, using
none of the binder or compiler switches. If the binder succeeds in finding an
-elaboration order, then apart from possible cases involing dispatching calls
+elaboration order, then apart from possible cases involving dispatching calls
and access-to-subprogram types, the program is free of elaboration errors.
If it is important for the program to be portable to compilers other than GNAT,
diff --git a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
index 0d78e43..5dab2d4 100644
--- a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
+++ b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
@@ -859,16 +859,18 @@ bug occurs, and then be able to retrieve the sequence of calls with the same
program compiled with debug information.
However the ``addr2line`` tool does not work with Position-Independent Code
-(PIC), the historical example being Windows DLLs, which nowadays encompasses
-Position-Independent Executables (PIE) on recent Windows versions.
-
-In order to translate addresses into the source lines with Position-Independent
-Executables on recent Windows versions, in other words without using the switch
-:switch:`-no-pie` during linking, you need to use the ``gnatsymbolize`` tool
-with :switch:`--load` instead of the ``addr2line`` tool. The main difference
-is that you need to copy the Load Address output in the traceback ahead of the
-sequence of addresses. And the default mode of ``gnatsymbolize`` is equivalent
-to that of ``addr2line`` with the above switches, so none of them is needed::
+(PIC), the historical example being Linux dynamic libraries and Windows DLLs,
+which nowadays encompasse Position-Independent Executables (PIE) on recent
+Linux and Windows versions.
+
+In order to translate addresses the source lines with Position-Independent
+Executables on recent Linux and Windows versions, in other words without
+using the switch :switch:`-no-pie` during linking, you need to use the
+``gnatsymbolize`` tool with :switch:`--load` instead of the ``addr2line``
+tool. The main difference is that you need to copy the Load Address output
+in the traceback ahead of the sequence of addresses. And the default mode
+of ``gnatsymbolize`` is equivalent to that of ``addr2line`` with the above
+switches, so none of them is needed::
$ gnatmake stb -g -bargs -E
$ stb
@@ -879,7 +881,7 @@ to that of ``addr2line`` with the above switches, so none of them is needed::
Call stack traceback locations:
0x401373 0x40138b 0x40139c 0x401335 0x4011c4 0x4011f1 0x77e892a4
- $ gnatsymbolize --load stb 0x400000 0x401373 0x40138b 0x40139c 0x401335
+ $ gnatsymbolize --load stb 0x400000 0x401373 0x40138b 0x40139c 0x401335 \
0x4011c4 0x4011f1 0x77e892a4
0x00401373 Stb.P1 at stb.adb:5
@@ -926,10 +928,9 @@ Ada facilities defined in ``Ada.Exceptions``. Here is a simple example:
P2;
end STB;
-This program will output:
-
::
+ $ gnatmake stb -g -bargs -E -largs -no-pie
$ stb
raised CONSTRAINT_ERROR : stb.adb:12 range check failed
@@ -957,12 +958,17 @@ addresses to strings:
with Ada.Text_IO;
with GNAT.Traceback;
with GNAT.Debug_Utilities;
+ with System;
procedure STB is
use Ada;
+ use Ada.Text_IO;
use GNAT;
use GNAT.Traceback;
+ use System;
+
+ LA : constant Address := Executable_Load_Address;
procedure P1 is
TB : Tracebacks_Array (1 .. 10);
@@ -972,14 +978,14 @@ addresses to strings:
begin
Call_Chain (TB, Len);
- Text_IO.Put ("In STB.P1 : ");
+ Put ("In STB.P1 : ");
for K in 1 .. Len loop
- Text_IO.Put (Debug_Utilities.Image (TB (K)));
- Text_IO.Put (' ');
+ Put (Debug_Utilities.Image_C (TB (K)));
+ Put (' ');
end loop;
- Text_IO.New_Line;
+ New_Line;
end P1;
procedure P2 is
@@ -988,6 +994,10 @@ addresses to strings:
end P2;
begin
+ if LA /= Null_Address then
+ Put_Line ("Load address: " & Debug_Utilities.Image_C (LA));
+ end if;
+
P2;
end STB;
@@ -996,8 +1006,9 @@ addresses to strings:
$ gnatmake stb -g
$ stb
- In STB.P1 : 16#0040_F1E4# 16#0040_14F2# 16#0040_170B# 16#0040_171C#
- 16#0040_1461# 16#0040_11C4# 16#0040_11F1# 16#77E8_92A4#
+ Load address: 0x400000
+ In STB.P1 : 0x40F1E4 0x4014F2 0x40170B 0x40171C 0x401461 0x4011C4 \
+ 0x4011F1 0x77E892A4
You can then get further information by invoking the ``addr2line`` tool or
@@ -1058,7 +1069,7 @@ Here is an example:
::
- $ gnatmake -g .\stb -bargs -E
+ $ gnatmake -g stb -bargs -E
$ stb
0040149F in stb.p1 at stb.adb:8
@@ -1070,16 +1081,6 @@ Here is an example:
004011F1 in mainCRTStartup at crt1.c:222
77E892A4 in ?? at ??:0
-In the above example the ``.\`` syntax in the ``gnatmake`` command
-is currently required by ``addr2line`` for files that are in
-the current working directory.
-Moreover, the exact sequence of linker options may vary from platform
-to platform.
-The above :switch:`-largs` section is for Windows platforms. By contrast,
-under Unix there is no need for the :switch:`-largs` section.
-Differences across platforms are due to details of linker implementation.
-
-
.. rubric:: Tracebacks From Anywhere in a Program
It is possible to get a symbolic stack traceback
@@ -1252,8 +1253,8 @@ most often, and are therefore the most time-consuming.
better handle Ada programs and multitasking.
It is currently supported on the following platforms
-* linux x86/x86_64
-* windows x86
+* Linux x86/x86_64
+* Windows x86/x86_64 (without PIE support)
In order to profile a program using ``gprof``, several steps are needed:
@@ -1291,6 +1292,10 @@ Note that only the objects that were compiled with the ``-pg`` switch will
be profiled; if you need to profile your whole project, use the ``-f``
gnatmake switch to force full recompilation.
+Note that on Windows, gprof does not support PIE. The ``-no-pie`` switch
+should be added to the linker flags to disable this feature.
+
+
.. _Program_execution:
@@ -2321,7 +2326,7 @@ erroneous, and the compiler would be entitled to assume that
However, in practice, this would cause some existing code that
seems to work with no optimization to start failing at high
-levels of optimzization.
+levels of optimization.
What the compiler does for such cases is to assume that marking
a variable as aliased indicates that some "funny business" may
@@ -2728,7 +2733,7 @@ To deal with the portability issue, and with the problem of
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
+furthermore, permits separate selection of operating modes for
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.
diff --git a/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst b/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst
index 92877a2..7df45d5 100644
--- a/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst
+++ b/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst
@@ -14,7 +14,6 @@ This chapter describes a number of utility programs:
* :ref:`The_File_Cleanup_Utility_gnatclean`
* :ref:`The_GNAT_Library_Browser_gnatls`
- * :ref:`The_Coding_Standard_Verifier_gnatcheck`
* :ref:`The_GNAT_Pretty_Printer_gnatpp`
* :ref:`The_Body_Stub_Generator_gnatstub`
* :ref:`The_Backtrace_Symbolizer_gnatsymbolize`
@@ -467,27 +466,6 @@ building specialized scripts.
.. only:: PRO or GPL
- .. _The_Coding_Standard_Verifier_gnatcheck:
-
- The Coding Standard Verifier ``gnatcheck``
- ==========================================
-
- .. index:: ! gnatcheck
- .. index:: ASIS
-
- The ``gnatcheck`` tool is an ASIS-based utility that checks coding standard
- compliance of Ada source files according to a given set of semantic rules.
-
- ``gnatcheck`` is a project-aware tool
- (see :ref:`Using_Project_Files_with_GNAT_Tools` for a description of
- the project-related switches). The project file package that can specify
- ``gnatcheck`` switches is named ``Check``.
-
- For full details, plese refer to :title:`GNATcheck Reference Manual`.
-
-
-.. only:: PRO or GPL
-
.. _The_GNAT_Pretty_Printer_gnatpp:
The GNAT Pretty Printer ``gnatpp``
@@ -2176,6 +2154,7 @@ building specialized scripts.
with GNAT.IO; use GNAT.IO;
with GNAT.Traceback; use GNAT.Traceback;
with GNAT.Debug_Utilities;
+
package body Pck is
procedure Call_Me_Third is
TB : Tracebacks_Array (1 .. 5);
@@ -2199,40 +2178,57 @@ building specialized scripts.
Call_Me_Second;
end Call_Me_First;
end Pck;
+
+ with GNAT.IO; use GNAT.IO;
+ with GNAT.Debug_Utilities;
+ with GNAT.Traceback;
+ with System;
+
with Pck; use Pck;
procedure Foo is
+ LA : constant System.Address := \
+ GNAT.Traceback.Executable_Load_Address;
+
+ use type System.Address;
+
begin
+ if LA /= System.Null_Address then
+ Put_Line ("Load address: " & GNAT.Debug_Utilities.Image_C (LA));
+ end if;
+
Global_Val := 123;
Call_Me_First;
end Foo;
This program, when built and run, prints a list of addresses which
correspond to the traceback when inside function ``Call_Me_Third``.
- For instance, on x86_64 GNU/Linux:
+ For instance, on x86-64 GNU/Linux:
::
$ gnatmake -g -q foo.adb
$ ./foo
- 0x0000000000402561
- 0x00000000004025EF
- 0x00000000004025FB
- 0x0000000000402611
- 0x00000000004024C7
+ Load address: 0x00005586C9D7D000
+ 0x00005586C9D81105
+ 0x00005586C9D8119B
+ 0x00005586C9D811A7
+ 0x00005586C9D8128C
+ 0x00005586C9D81069
``gnatsymbolize`` can be used to translate those addresses into
code locations as follow:
::
- $ gnatsymbolize foo 0x0000000000402561 0x00000000004025EF \
- 0x00000000004025FB 0x0000000000402611 0x00000000004024C7
- Pck.Call_Me_Third at pck.adb:12
- Pck.Call_Me_Second at pck.adb:20
- Pck.Call_Me_First at pck.adb:25
- Foo at foo.adb:6
- Main at b~foo.adb:184
+ $ gnatsymbolize --load foo 0x00005586C9D7D000 0x00005586C9D81105 \
+ 0x00005586C9D8119B 0x00005586C9D811A7 0x00005586C9D8128C \
+ 0x00005586C9D81069
+ 0x5586c9d81105 Pck.Call_Me_Third at pck.adb:12
+ 0x5586c9d8119b Pck.Call_Me_Second at pck.adb:20
+ 0x5586c9d811a7 Pck.Call_Me_First at pck.adb:25
+ 0x5586c9d8128c Foo at foo.adb:6
+ 0x5586c9d81069 Main at b~foo.adb:199
Switches for ``gnatsymbolize``
------------------------------
@@ -2265,7 +2261,7 @@ building specialized scripts.
:switch:`--load`
Interpret the first address as the load address of the executable.
- This is needed for position-independent executables on Windows.
+ This is needed for position-independent executables on Linux and Windows.
Requirements for Correct Operation
----------------------------------
diff --git a/gcc/ada/doc/share/conf.py b/gcc/ada/doc/share/conf.py
index bb36bfa..48f1a96 100644
--- a/gcc/ada/doc/share/conf.py
+++ b/gcc/ada/doc/share/conf.py
@@ -2,6 +2,9 @@
# Style_Check:Python_Fragment (meaning no pyflakes check)
#
# GNAT build configuration file
+# --------------------------------
+# This file defines the configuration for all files created
+# by Sphinx. In this case, pdf (using latex) and html
import sys
import os
@@ -13,16 +16,12 @@ sys.path.append('.')
import ada_pygments
import latex_elements
-# Some configuration values for the various documentation handled by
-# this conf.py
-
+# Define list of documents to be built and their title
DOCS = {
- 'gnat_rm': {
- 'title': 'GNAT Reference Manual'},
- 'gnat_ugn': {
- 'title': 'GNAT User\'s Guide for Native Platforms'},
- 'gnat-style': {
- 'title': 'GNAT Coding Style: A Guide for GNAT Developers'}}
+ "gnat_rm": {"title": "GNAT Reference Manual"},
+ "gnat_ugn": {"title": "GNAT User's Guide for Native Platforms"},
+ "gnat-style": {"title": "GNAT Coding Style: A Guide for GNAT Developers"},
+}
# Then retrieve the source directory
root_source_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -30,14 +29,17 @@ gnatvsn_spec = os.path.join(root_source_dir, '..', 'gnatvsn.ads')
basever = os.path.join(root_source_dir, '..', '..', 'BASE-VER')
texi_fsf = True # Set to False when FSF doc is switched to sphinx by default
+# get vsn specs
with open(gnatvsn_spec, 'r') as fd:
gnatvsn_content = fd.read()
+# read copyright test from .rst file (used also for sanity-checking)
def get_copyright():
return '2008-%s, Free Software Foundation' % time.strftime('%Y')
+# get environment gnat version (used also for sanity-checking)
def get_gnat_version():
m = re.search(r'Gnat_Static_Version_String : ' +
r'constant String := "([^\(\)]+)\(.*\)?";',
@@ -58,6 +60,7 @@ def get_gnat_version():
sys.exit(1)
+# get gnat build type from runtime
def get_gnat_build_type():
m = re.search(r'Build_Type : constant Gnat_Build_Type := (.+);',
gnatvsn_content)
@@ -70,7 +73,35 @@ def get_gnat_build_type():
sys.exit(1)
+# Enable Sphinx extensions
+# Note that these are active for all files to be build (see DOCS list)
+extensions = ['sphinx_rtd_theme']
+
+# todo interprets ".. todo::" commands in .rst files
+# mathjax enables math equations to render correctly
+extensions += ['sphinx.ext.todo', 'sphinx.ext.mathjax']
+todo_include_todos = True
+
+# define templates source folder
+templates_path = ['_templates']
+# define the types of files to read as source for documents
+source_suffix = '.rst'
+
+# enable figure, object, table numeration on documents
+print('enabling table, code-block and figure numeration')
+numfig = True
+numfig_format = {
+ 'figure': 'figure %s',
+ 'table': 'table %s',
+ 'code-block': 'listing %s',
+ 'section': 'section %s',
+}
+print('done')
+
+
+# Start building the documents
# First retrieve the name of the documentation we are building
+print('checking doc name... ')
doc_name = os.environ.get('DOC_NAME', None)
if doc_name is None:
print('DOC_NAME environment variable should be set')
@@ -79,7 +110,7 @@ if doc_name is None:
if doc_name not in DOCS:
print('%s is not a valid documentation name' % doc_name)
sys.exit(1)
-
+print('found... ' , doc_name)
# Exclude sources that are not part of the current documentation
exclude_patterns = []
@@ -88,16 +119,13 @@ for d in os.listdir(root_source_dir):
exclude_patterns.append(d)
print('ignoring %s' % d)
+# Special condition for gnat_rm
if doc_name == 'gnat_rm':
exclude_patterns.append('share/gnat_project_manager.rst')
print('ignoring share/gnat_project_manager.rst')
-extensions = []
-templates_path = ['_templates']
-source_suffix = '.rst'
-master_doc = doc_name
-
# General information about the project.
+master_doc = doc_name
project = DOCS[doc_name]['title']
copyright = get_copyright()
@@ -107,42 +135,58 @@ release = get_gnat_version()
pygments_style = None
tags.add(get_gnat_build_type())
-html_theme = 'sphinxdoc'
+
+# Define figures to be included
+html_theme = 'sphinx_rtd_theme'
if os.path.isfile('adacore_transparent.png'):
+ # split html and pdf logos to avoid 'same name' error in sphinx <5.2+
html_logo = 'adacore_transparent.png'
+ latex_logo = 'adacore_transparent.png'
if os.path.isfile('favicon.ico'):
html_favicon = 'favicon.ico'
html_static_path = ['_static']
+# Use gnat.sty for bulding documents
latex_additional_files = ['gnat.sty']
+# Add copyright info to file
copyright_macros = {
'date': time.strftime("%b %d, %Y"),
'edition': 'GNAT %s Edition' % 'Pro' if get_gnat_build_type() == 'PRO'
else 'GPL',
'name': 'GNU Ada',
'tool': 'GNAT',
- 'version': version}
+ 'version': version
+}
+# Send info to latex for building document
latex_elements = {
- 'preamble': '\\usepackage{gnat}\n' +
- latex_elements.TOC_DEPTH +
- latex_elements.PAGE_BLANK +
- latex_elements.TOC_CMD +
- latex_elements.LATEX_HYPHEN +
- latex_elements.doc_settings(DOCS[doc_name]['title'],
- get_gnat_version()),
- 'tableofcontents': latex_elements.TOC % copyright_macros}
-
+ 'preamble': '\\usepackage{gnat}\n' # use gnat.sty format
+ + latex_elements.TOC_DEPTH # define table of contents max depth to display
+ + latex_elements.PAGE_BLANK # define blank pages and when to be used
+ + latex_elements.TOC_CMD # write table of contents
+ + latex_elements.LATEX_HYPHEN # define latex hyphen '-'
+ + '\\sloppy\n\n' # sloppy/fussy define how words are spread in a paragraph
+ # the following is used to send title and gnat version to latex
+ + latex_elements.doc_settings(DOCS[doc_name]['title'], get_gnat_version()),
+ 'tableofcontents': latex_elements.TOC % copyright_macros, # build TOC
+ 'papersize': 'a4paper,table', # papersize as a4, else default letter
+ 'figure_align': 'H', # align figure as square and to paragraph text
+ 'maketitle': '\\maketitle', # execute custom maketitle
+}
+
+# Show page references for cross-reference in docs
+latex_show_pagerefs = True
+# Define latex metadata
latex_documents = [
(master_doc, '%s.tex' % doc_name, project, 'AdaCore', 'manual')]
-
+# Define .txt files metadata
texinfo_documents = [
- (master_doc, doc_name, project,
- 'AdaCore', doc_name, doc_name, '')]
+ (master_doc, doc_name, project, 'AdaCore', doc_name, doc_name, '')]
+# setup AdaCore custom pygments
def setup(app):
app.add_lexer('ada', ada_pygments.AdaLexer)
app.add_lexer('gpr', ada_pygments.GNATProjectLexer)
diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index e350f13..d71dcaf 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -358,9 +358,11 @@ package Einfo is
--
-- For objects, the Actual_Subtype is set only if this is a discriminated
-- type. For arrays, the bounds of the expression are obtained and the
--- Etype of the object is directly the constrained subtype. This is
--- rather irregular, and the semantic checks that depend on the nominal
--- subtype being unconstrained use flag Is_Constr_Subt_For_U_Nominal(qv).
+-- Etype of the object is directly the constrained subtype, except in the
+-- case of a return object that lives on the secondary stack where Etype
+-- is the nominal unconstrained subtype. This is rather irregular and the
+-- semantic checks that depend on the nominal subtype being unconstrained
+-- use flag Is_Constr_Subt_For_U_Nominal(qv).
-- Address_Clause (synthesized)
-- Applies to entries, objects and subprograms. Set if an address clause
@@ -874,7 +876,7 @@ package Einfo is
-- are generated (subprograms, package declarations and package
-- bodies). Defined if there are pending generic body instantiations
-- for the corresponding entity. If this flag is set, then generation
--- of the subprogram descriptor for the corresponding enities must
+-- of the subprogram descriptor for the corresponding entities must
-- be delayed, since the insertion of the generic body may add entries
-- to the list of handlers.
--
@@ -2570,7 +2572,7 @@ package Einfo is
-- Is_Elaboration_Checks_OK_Id
-- Defined in elaboration targets (see terminology in Sem_Elab). Set when
--- the target appears in a region which is subject to elabled elaboration
+-- the target appears in a region which is subject to enabled elaboration
-- checks. Such targets are allowed to generate run-time conditional ABE
-- checks or guaranteed ABE failures.
@@ -3114,7 +3116,7 @@ package Einfo is
-- Defined in all entities, set in E_Package and E_Generic_Package
-- entities to which a pragma Preelaborate is applied, and also in
-- all entities within such packages. Note that the fact that this
--- flag is set does not necesarily mean that no elaboration code is
+-- flag is set does not necessarily mean that no elaboration code is
-- generated for the package.
-- Is_Primitive
@@ -3228,7 +3230,7 @@ package Einfo is
-- Defined in all entities, set only for a variable or constant for
-- which the Renamed_Object field is non-empty and for which the
-- renaming is handled by the front end, by macro substitution of
--- a copy of the (evaluated) name tree whereever the variable is used.
+-- a copy of the (evaluated) name tree wherever the variable is used.
-- Is_Return_Object
-- Defined in all object entities. True if the object is the return
@@ -3964,7 +3966,8 @@ package Einfo is
-- Present in variable entities. Contains all references to the variable
-- when it is subject to pragma Part_Of. If the variable is a constituent
-- of a single protected/task type, the references are examined as they
--- must appear only within the type defintion and the corresponding body.
+-- must appear only within the type definition and the corresponding
+-- body.
-- Partial_DIC_Procedure (synthesized)
-- Defined in type entities. Set for a private type and its full view
@@ -4058,7 +4061,7 @@ package Einfo is
-- Prev_Entity
-- Defined in all entities. The entities of a scope are chained, and this
--- field is used as a backward pointer for this entity list - effectivly
+-- field is used as a backward pointer for this entity list - effectively
-- making the entity chain doubly-linked.
-- Primitive_Operations (synthesized)
diff --git a/gcc/ada/err_vars.ads b/gcc/ada/err_vars.ads
index 05329dc..66c4bb0 100644
--- a/gcc/ada/err_vars.ads
+++ b/gcc/ada/err_vars.ads
@@ -32,12 +32,6 @@ with Uintp; use Uintp;
package Err_Vars is
- -- All of these variables are set when needed, so they do not need to be
- -- initialized. However, there is code that saves and restores existing
- -- values, which may malfunction in -gnatVa mode if the variable has never
- -- been initialized, so we initialize some variables to avoid exceptions
- -- from invalid values in such cases.
-
-- Note on error counts (Serious_Errors_Detected, Total_Errors_Detected,
-- Warnings_Detected, Warning_Info_Messages, Report_Info_Messages). These
-- counts might more logically appear in this unit, but we place them
@@ -68,7 +62,6 @@ package Err_Vars is
-- resulting from illegalities, and also for substitution of more
-- appropriate error messages from higher semantic levels. It is
-- a counter so that the increment/decrement protocol nests neatly.
- -- Initialized for -gnatVa use, see comment above.
Error_Msg_Exception : exception;
-- Exception raised if Raise_Exception_On_Error is true
@@ -81,12 +74,6 @@ package Err_Vars is
-- Source_Reference line, then this is initialized to No_Source_File,
-- to force an initial reference to the real source file name.
- Warning_Doc_Switch : Boolean := True;
- -- If this is set True, then the ??/?x?/?x? sequences in error messages
- -- are active (see errout.ads for details). If this switch is False, then
- -- these sequences are ignored (i.e. simply equivalent to a single ?). The
- -- -gnatw.d switch sets this flag True, -gnatw.D sets this flag False.
-
----------------------------------------
-- Error Message Insertion Parameters --
----------------------------------------
diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
index 79e162a..b30e8b5 100644
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -53,6 +53,7 @@ with Stand; use Stand;
with Stylesw; use Stylesw;
with System.OS_Lib;
with Uname; use Uname;
+with Warnsw; pragma Unreferenced (Warnsw); -- disable spurious warning
package body Errout is
@@ -881,18 +882,40 @@ package body Errout is
-- Error_Msg_GNAT_Extension --
------------------------------
- procedure Error_Msg_GNAT_Extension (Extension : String; Loc : Source_Ptr) is
+ procedure Error_Msg_GNAT_Extension
+ (Extension : String;
+ Loc : Source_Ptr;
+ Is_Core_Extension : Boolean := False)
+ is
begin
- if not Extensions_Allowed then
- Error_Msg (Extension & " is a 'G'N'A'T-specific extension", Loc);
+ if (if Is_Core_Extension
+ then Core_Extensions_Allowed
+ else All_Extensions_Allowed)
+ then
+ return;
+ end if;
- if No (Ada_Version_Pragma) then
- Error_Msg ("\unit must be compiled with -gnatX "
- & "or use pragma Extensions_Allowed (On)", Loc);
+ Error_Msg (Extension & " is a 'G'N'A'T-specific extension", Loc);
+
+ if No (Ada_Version_Pragma) then
+ if Is_Core_Extension then
+ Error_Msg
+ ("\unit must be compiled with -gnatX '[or -gnatX0'] " &
+ "or use pragma Extensions_Allowed (On) '[or All']", Loc);
else
- Error_Msg_Sloc := Sloc (Ada_Version_Pragma);
- Error_Msg ("\incompatible with Ada version set#", Loc);
- Error_Msg ("\must use pragma Extensions_Allowed (On)", Loc);
+ Error_Msg
+ ("\unit must be compiled with -gnatX0 " &
+ "or use pragma Extensions_Allowed (All)", Loc);
+ end if;
+ else
+ Error_Msg_Sloc := Sloc (Ada_Version_Pragma);
+ Error_Msg ("\incompatible with Ada version set#", Loc);
+ if Is_Core_Extension then
+ Error_Msg
+ ("\must use pragma Extensions_Allowed (On) '[or All']", Loc);
+ else
+ Error_Msg
+ ("\must use pragma Extensions_Allowed (All)", Loc);
end if;
end if;
end Error_Msg_GNAT_Extension;
@@ -965,14 +988,14 @@ package body Errout is
-- after fixing the error, the use clause no longer looks like it was
-- unused.
- Check_Unreferenced := False;
- Check_Unreferenced_Formals := False;
+ Warnsw.Check_Unreferenced := False;
+ Warnsw.Check_Unreferenced_Formals := False;
end Handle_Serious_Error;
-- Start of processing for Error_Msg_Internal
begin
- -- Detect common mistake of prefixing or suffing the message with a
+ -- Detect common mistake of prefixing or suffixing the message with a
-- space character.
pragma Assert (Msg (Msg'First) /= ' ' and then Msg (Msg'Last) /= ' ');
@@ -1191,7 +1214,7 @@ package body Errout is
Next => No_Error_Msg,
Prev => No_Error_Msg,
Sptr => Span,
- Optr => Optr,
+ Optr => Opan,
Insertion_Sloc => (if Has_Insertion_Line then Error_Msg_Sloc
else No_Location),
Sfile => Get_Source_File_Index (Sptr),
@@ -1260,7 +1283,7 @@ package body Errout is
or else
(Sptr = Errors.Table (Last_Error_Msg).Sptr.Ptr
and then
- Optr > Errors.Table (Last_Error_Msg).Optr))
+ Optr > Errors.Table (Last_Error_Msg).Optr.Ptr))
then
Prev_Msg := Last_Error_Msg;
Next_Msg := No_Error_Msg;
@@ -1278,7 +1301,8 @@ package body Errout is
then
exit when Sptr < Errors.Table (Next_Msg).Sptr.Ptr
or else (Sptr = Errors.Table (Next_Msg).Sptr.Ptr
- and then Optr < Errors.Table (Next_Msg).Optr);
+ and then
+ Optr < Errors.Table (Next_Msg).Optr.Ptr);
end if;
Prev_Msg := Next_Msg;
@@ -1657,8 +1681,8 @@ package body Errout is
(Warning_Specifically_Suppressed (CE.Sptr.Ptr, CE.Text, Tag)
/= No_String
or else
- Warning_Specifically_Suppressed (CE.Optr, CE.Text, Tag) /=
- No_String)
+ Warning_Specifically_Suppressed (CE.Optr.Ptr, CE.Text, Tag)
+ /= No_String)
then
Delete_Warning (Cur);
@@ -2208,9 +2232,9 @@ package body Errout is
Write_Str (",""locations"":[");
Write_JSON_Span (Errors.Table (E));
- if Errors.Table (E).Optr /= Errors.Table (E).Sptr.Ptr then
+ if Errors.Table (E).Optr.Ptr /= Errors.Table (E).Sptr.Ptr then
Write_Str (",{""caret"":");
- Write_JSON_Location (Errors.Table (E).Optr);
+ Write_JSON_Location (Errors.Table (E).Optr.Ptr);
Write_Str ("}");
end if;
@@ -2930,7 +2954,7 @@ package body Errout is
else SGR_Error);
begin
Write_Source_Code_Lines
- (Errors.Table (E).Sptr, SGR_Span);
+ (Errors.Table (E).Optr, SGR_Span);
end;
end if;
end if;
@@ -3305,7 +3329,7 @@ package body Errout is
-- Don't remove if location does not match
- and then Errors.Table (E).Optr = Loc
+ and then Errors.Table (E).Optr.Ptr = Loc
-- Don't remove if not warning/info message. Note that we do
-- not remove style messages here. They are warning messages
@@ -3327,6 +3351,17 @@ package body Errout is
Warning_Info_Messages := Warning_Info_Messages - 1;
end if;
+ -- When warning about a runtime exception has been escalated
+ -- into error, the starting message has increased the total
+ -- errors counter, so here we decrease this counter.
+
+ if Errors.Table (E).Warn_Runtime_Raise
+ and then not Errors.Table (E).Msg_Cont
+ and then Warning_Mode = Treat_Run_Time_Warnings_As_Errors
+ then
+ Total_Errors_Detected := Total_Errors_Detected - 1;
+ end if;
+
return True;
-- No removal required
@@ -3361,23 +3396,13 @@ package body Errout is
E := Errors.Table (E).Next;
end loop;
+ -- Warnings may have been posted on subexpressions of original tree
+
if Nkind (N) = N_Raise_Constraint_Error
and then Is_Rewrite_Substitution (N)
and then No (Condition (N))
then
- -- Warnings may have been posted on subexpressions of the original
- -- tree. We place the original node back on the tree to remove
- -- those warnings, whose sloc do not match those of any node in
- -- the current tree. Given that we are in unreachable code, this
- -- modification to the tree is harmless.
-
- if Is_List_Member (N) then
- Set_Condition (N, Original_Node (N));
- Check_All_Warnings (Condition (N));
- else
- Rewrite (N, Original_Node (N));
- Check_All_Warnings (N);
- end if;
+ Check_All_Warnings (Original_Node (N));
end if;
return OK;
diff --git a/gcc/ada/errout.ads b/gcc/ada/errout.ads
index 45166f5..aeb9a2f 100644
--- a/gcc/ada/errout.ads
+++ b/gcc/ada/errout.ads
@@ -59,15 +59,6 @@ package Errout is
Error_Msg_Exception : exception renames Err_Vars.Error_Msg_Exception;
-- Exception raised if Raise_Exception_On_Error is true
- Warning_Doc_Switch : Boolean renames Err_Vars.Warning_Doc_Switch;
- -- If this is set True, then the ??/?*?/?$?/?x?/?.x?/?_x? insertion
- -- sequences in error messages generate appropriate tags for the output
- -- error messages. If this switch is False, then these sequences are still
- -- recognized (for the purposes of implementing the pattern matching in
- -- pragmas Warnings (Off,..) and Warning_As_Pragma(...) but do not result
- -- in adding the error message tag. The -gnatw.d switch sets this flag
- -- True, -gnatw.D sets this flag False.
-
Current_Node : Node_Id := Empty;
-- Used by Error_Msg as a default Node_Id.
-- Relevant only when Opt.Include_Subprogram_In_Messages is set.
@@ -314,10 +305,11 @@ package Errout is
-- continuations, use this in each continuation message.
-- Insertion character ?x? ?.x? ?_x? (warning with switch)
- -- Like ?, but if the flag Warn_Doc_Switch is True, adds the string
+ -- "x" is a (lower-case) warning switch character.
+ -- Like ??, but if the flag Warn_Doc_Switch is True, adds the string
-- "[-gnatwx]", "[-gnatw.x]", or "[-gnatw_x]", at the end of the
- -- warning message. x must be lower case. For continuations, use this
- -- on each continuation message.
+ -- warning message. For continuations, use this on each continuation
+ -- message.
-- Insertion character ?*? (restriction warning)
-- Like ?, but if the flag Warn_Doc_Switch is True, adds the string
@@ -937,11 +929,18 @@ package Errout is
procedure Error_Msg_Ada_2022_Feature (Feature : String; Loc : Source_Ptr);
-- Analogous to Error_Msg_Ada_2012_Feature, for Ada 2022
- procedure Error_Msg_GNAT_Extension (Extension : String; Loc : Source_Ptr);
- -- If not operating with extensions allowed, posts errors complaining
- -- that Extension is only supported when the -gnatX switch is enabled
- -- or pragma Extensions_Allowed (On) is used. Loc indicates the source
- -- location of the extension construct.
+ procedure Error_Msg_GNAT_Extension
+ (Extension : String;
+ Loc : Source_Ptr;
+ Is_Core_Extension : Boolean := False);
+ -- To be called as part of checking a GNAT language extension (either a
+ -- core extension or not, as indicated by the Is_Core_Extension parameter).
+ -- If switch -gnatX0 or pragma Extension_Allowed (All) is in effect, then
+ -- either kind of extension is allowed; if switch -gnatX or pragma
+ -- Extensions_Allowed (On) is in effect, then only core extensions are
+ -- allowed. Otherwise, no extensions are allowed. A disallowed construct
+ -- is flagged as an error. Loc indicates the source location of the
+ -- extension construct.
procedure dmsg (Id : Error_Msg_Id) renames Erroutc.dmsg;
-- Debugging routine to dump an error message
diff --git a/gcc/ada/erroutc.adb b/gcc/ada/erroutc.adb
index d0cbe9f..d40c668 100644
--- a/gcc/ada/erroutc.adb
+++ b/gcc/ada/erroutc.adb
@@ -44,6 +44,7 @@ with Stringt; use Stringt;
with Targparm;
with Uintp; use Uintp;
with Widechar; use Widechar;
+with Warnsw; use Warnsw;
package body Erroutc is
@@ -311,32 +312,33 @@ package body Erroutc is
begin
w ("Dumping error message, Id = ", Int (Id));
- w (" Text = ", E.Text.all);
- w (" Next = ", Int (E.Next));
- w (" Prev = ", Int (E.Prev));
- w (" Sfile = ", Int (E.Sfile));
+ w (" Text = ", E.Text.all);
+ w (" Next = ", Int (E.Next));
+ w (" Prev = ", Int (E.Prev));
+ w (" Sfile = ", Int (E.Sfile));
Write_Str
- (" Sptr = ");
+ (" Sptr = ");
Write_Location (E.Sptr.Ptr); -- ??? Do not write the full span for now
Write_Eol;
Write_Str
- (" Optr = ");
- Write_Location (E.Optr);
+ (" Optr = ");
+ Write_Location (E.Optr.Ptr);
Write_Eol;
- w (" Line = ", Int (E.Line));
- w (" Col = ", Int (E.Col));
- w (" Warn = ", E.Warn);
- w (" Warn_Err = ", E.Warn_Err);
- w (" Warn_Chr = '" & E.Warn_Chr & ''');
- w (" Style = ", E.Style);
- w (" Serious = ", E.Serious);
- w (" Uncond = ", E.Uncond);
- w (" Msg_Cont = ", E.Msg_Cont);
- w (" Deleted = ", E.Deleted);
- w (" Node = ", Int (E.Node));
+ w (" Line = ", Int (E.Line));
+ w (" Col = ", Int (E.Col));
+ w (" Warn = ", E.Warn);
+ w (" Warn_Err = ", E.Warn_Err);
+ w (" Warn_Runtime_Raise = ", E.Warn_Runtime_Raise);
+ w (" Warn_Chr = '" & E.Warn_Chr & ''');
+ w (" Style = ", E.Style);
+ w (" Serious = ", E.Serious);
+ w (" Uncond = ", E.Uncond);
+ w (" Msg_Cont = ", E.Msg_Cont);
+ w (" Deleted = ", E.Deleted);
+ w (" Node = ", Int (E.Node));
Write_Eol;
end dmsg;
diff --git a/gcc/ada/erroutc.ads b/gcc/ada/erroutc.ads
index 7957228..c992bba 100644
--- a/gcc/ada/erroutc.ads
+++ b/gcc/ada/erroutc.ads
@@ -209,7 +209,7 @@ package Erroutc is
-- will be posted. Note that an error placed on an instantiation will
-- have Sptr pointing to the instantiation point.
- Optr : Source_Ptr;
+ Optr : Source_Span;
-- Flag location used in the call to post the error. This is the same as
-- Sptr, except when an error is posted on a particular instantiation of
-- a generic. In such a case, Sptr will point to the original source
diff --git a/gcc/ada/errutil.adb b/gcc/ada/errutil.adb
index 921de31..887dc88 100644
--- a/gcc/ada/errutil.adb
+++ b/gcc/ada/errutil.adb
@@ -208,7 +208,7 @@ package body Errutil is
Prev => No_Error_Msg,
Sfile => Get_Source_File_Index (Sptr),
Sptr => To_Span (Sptr),
- Optr => Optr,
+ Optr => To_Span (Optr),
Insertion_Sloc => No_Location,
Line => Get_Physical_Line_Number (Sptr),
Col => Get_Column_Number (Sptr),
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 1857055..4d8bb817 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -71,6 +71,7 @@ with Stringt; use Stringt;
with Tbuild; use Tbuild;
with Uintp; use Uintp;
with Urealp; use Urealp;
+with Warnsw; use Warnsw;
package body Exp_Aggr is
@@ -2058,7 +2059,7 @@ package body Exp_Aggr is
-- to do that if we already have the base type at hand.
if Etype (L) = Index_Base then
- L_L := L;
+ L_L := New_Copy_Tree (L);
else
L_L :=
Make_Qualified_Expression (Loc,
@@ -2067,7 +2068,7 @@ package body Exp_Aggr is
end if;
if Etype (H) = Index_Base then
- L_H := H;
+ L_H := New_Copy_Tree (H);
else
L_H :=
Make_Qualified_Expression (Loc,
@@ -6840,7 +6841,7 @@ package body Exp_Aggr is
or else Parent_Kind = N_Component_Association
or else (Parent_Kind = N_Object_Declaration
and then (Needs_Finalization (Typ)
- or else Is_Build_In_Place_Return_Object
+ or else Is_Special_Return_Object
(Defining_Identifier (Parent_Node))))
or else (Parent_Kind = N_Assignment_Statement
and then Inside_Init_Proc)
diff --git a/gcc/ada/exp_atag.adb b/gcc/ada/exp_atag.adb
index 7871363..074ab4e 100644
--- a/gcc/ada/exp_atag.adb
+++ b/gcc/ada/exp_atag.adb
@@ -312,7 +312,7 @@ package body Exp_Atag is
if not Is_Predefined_Dispatching_Operation (Prim)
and then not Is_Predefined_Dispatching_Operation (E)
- and then not Present (Interface_Alias (Prim))
+ and then No (Interface_Alias (Prim))
and then not Is_Abstract_Subprogram (E)
and then not Is_Eliminated (E)
and then Prim_Pos <= CPP_Nb_Prims
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index 0e79b5d..b7554e0 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Accessibility; use Accessibility;
with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
@@ -1998,16 +1999,21 @@ package body Exp_Attr is
-- Start of processing for Expand_N_Attribute_Reference
begin
- -- Do required validity checking, if enabled. Do not apply check to
- -- output parameters of an Asm instruction, since the value of this
- -- is not set till after the attribute has been elaborated, and do
- -- not apply the check to the arguments of a 'Read or 'Input attribute
- -- reference since the scalar argument is an OUT scalar.
+ -- Do required validity checking, if enabled.
+ --
+ -- Skip check for output parameters of an Asm instruction (since their
+ -- valuesare not set till after the attribute has been elaborated),
+ -- for the arguments of a 'Read attribute reference (since the
+ -- scalar argument is an OUT scalar) and for the arguments of a
+ -- 'Has_Same_Storage or 'Overlaps_Storage attribute reference (which not
+ -- considered to be reads of their prefixes and expressions, see Ada RM
+ -- 13.3(73.10/3)).
if Validity_Checks_On and then Validity_Check_Operands
and then Id /= Attribute_Asm_Output
and then Id /= Attribute_Read
- and then Id /= Attribute_Input
+ and then Id /= Attribute_Has_Same_Storage
+ and then Id /= Attribute_Overlaps_Storage
then
declare
Expr : Node_Id;
@@ -2210,13 +2216,25 @@ package body Exp_Attr is
-- Local declarations
- Enc_Object : constant Node_Id := Enclosing_Object (Ref_Object);
+ Enc_Object : Node_Id := Enclosing_Object (Ref_Object);
-- Start of processing for Access_Cases
begin
Btyp_DDT := Designated_Type (Btyp);
+ -- When Enc_Object is a view conversion then RM 3.10.2 (9)
+ -- applies and we obtain the expression being converted.
+ -- Otherwise we do not dig any deeper since a conversion
+ -- might generate a copy and we can't assume it will be as
+ -- long-lived as the original.
+
+ while Nkind (Enc_Object) = N_Type_Conversion
+ and then Is_View_Conversion (Enc_Object)
+ loop
+ Enc_Object := Expression (Enc_Object);
+ end loop;
+
-- Handle designated types that come from the limited view
if From_Limited_With (Btyp_DDT)
@@ -2311,19 +2329,40 @@ package body Exp_Attr is
if Is_Access_Protected_Subprogram_Type (Btyp) then
Expand_Access_To_Protected_Op (N, Pref, Typ);
- -- If prefix is a subprogram that has class-wide preconditions and
- -- an indirect-call wrapper (ICW) of such subprogram is available
- -- then replace the prefix by the ICW.
-
elsif Is_Access_Subprogram_Type (Btyp)
and then Is_Entity_Name (Pref)
- and then Present (Class_Preconditions (Entity (Pref)))
- and then Present (Indirect_Call_Wrapper (Entity (Pref)))
then
- Rewrite (Pref,
- New_Occurrence_Of
- (Indirect_Call_Wrapper (Entity (Pref)), Loc));
- Analyze_And_Resolve (N, Typ);
+ -- If prefix is a subprogram that has class-wide preconditions
+ -- and an indirect-call wrapper (ICW) of the subprogram is
+ -- available then replace the prefix by the ICW.
+
+ if Present (Class_Preconditions (Entity (Pref)))
+ and then Present (Indirect_Call_Wrapper (Entity (Pref)))
+ then
+ Rewrite (Pref,
+ New_Occurrence_Of
+ (Indirect_Call_Wrapper (Entity (Pref)), Loc));
+ Analyze_And_Resolve (N, Typ);
+ end if;
+
+ -- Ensure the availability of the extra formals to check that
+ -- they match.
+
+ if not Is_Frozen (Entity (Pref))
+ or else From_Limited_With (Etype (Entity (Pref)))
+ then
+ Create_Extra_Formals (Entity (Pref));
+ end if;
+
+ if not Is_Frozen (Btyp_DDT)
+ or else From_Limited_With (Etype (Btyp_DDT))
+ then
+ Create_Extra_Formals (Btyp_DDT);
+ end if;
+
+ pragma Assert
+ (Extra_Formals_Match_OK
+ (E => Entity (Pref), Ref_E => Btyp_DDT));
-- If prefix is a type name, this is a reference to the current
-- instance of the type, within its initialization procedure.
@@ -6575,7 +6614,7 @@ package body Exp_Attr is
-- If Storage_Size wasn't found (can only occur in the simple
-- storage pool case), then simply use zero for the result.
- if not Present (Alloc_Op) then
+ if No (Alloc_Op) then
Rewrite (N, Make_Integer_Literal (Loc, 0));
-- Otherwise, rewrite the allocator as a call to pool type's
diff --git a/gcc/ada/exp_ch11.adb b/gcc/ada/exp_ch11.adb
index 98ce886..5b83035 100644
--- a/gcc/ada/exp_ch11.adb
+++ b/gcc/ada/exp_ch11.adb
@@ -53,6 +53,7 @@ with Stringt; use Stringt;
with Targparm; use Targparm;
with Tbuild; use Tbuild;
with Uintp; use Uintp;
+with Warnsw; use Warnsw;
package body Exp_Ch11 is
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 0d82691..6de5843 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Accessibility; use Accessibility;
with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
@@ -44,7 +45,6 @@ with Exp_Dist; use Exp_Dist;
with Exp_Put_Image;
with Exp_Smem; use Exp_Smem;
with Exp_Strm; use Exp_Strm;
-with Exp_Tss; use Exp_Tss;
with Exp_Util; use Exp_Util;
with Freeze; use Freeze;
with Ghost; use Ghost;
@@ -408,15 +408,6 @@ package body Exp_Ch3 is
-- Freeze entities of all predefined primitive operations. This is needed
-- because the bodies of these operations do not normally do any freezing.
- function Stream_Operation_OK
- (Typ : Entity_Id;
- Operation : TSS_Name_Type) return Boolean;
- -- Check whether the named stream operation must be emitted for a given
- -- type. The rules for inheritance of stream attributes by type extensions
- -- are enforced by this function. Furthermore, various restrictions prevent
- -- the generation of these operations, as a useful optimization or for
- -- certification purposes and to save unnecessary generated code.
-
--------------------------
-- Adjust_Discriminants --
--------------------------
@@ -4599,7 +4590,8 @@ package body Exp_Ch3 is
end if;
-- If not inherited and not user-defined, build body as for a type with
- -- tagged components.
+ -- components of record type (i.e. a type for which "=" composes when
+ -- used as a component in an outer composite type).
if Build_Eq then
Decl :=
@@ -5379,6 +5371,10 @@ package body Exp_Ch3 is
procedure Register_Dispatch_Table_Wrappers (Typ : Entity_Id);
-- Register dispatch-table wrappers in the dispatch table of Typ
+ procedure Validate_Tagged_Type_Extra_Formals (Typ : Entity_Id);
+ -- Check extra formals of dispatching primitives of tagged type Typ.
+ -- Used in pragma Debug.
+
---------------------------------------
-- Build_Class_Condition_Subprograms --
---------------------------------------
@@ -5508,6 +5504,78 @@ package body Exp_Ch3 is
end loop;
end Register_Dispatch_Table_Wrappers;
+ ----------------------------------------
+ -- Validate_Tagged_Type_Extra_Formals --
+ ----------------------------------------
+
+ procedure Validate_Tagged_Type_Extra_Formals (Typ : Entity_Id) is
+ Ovr_Subp : Entity_Id;
+ Elmt : Elmt_Id;
+ Subp : Entity_Id;
+
+ begin
+ pragma Assert (not Is_Class_Wide_Type (Typ));
+
+ -- No check required if expansion is not active since we never
+ -- generate extra formals in such case.
+
+ if not Expander_Active then
+ return;
+ end if;
+
+ Elmt := First_Elmt (Primitive_Operations (Typ));
+ while Present (Elmt) loop
+ Subp := Node (Elmt);
+
+ -- Extra formals of a dispatching primitive must match:
+
+ -- 1) The extra formals of its covered interface primitive
+
+ if Present (Interface_Alias (Subp)) then
+ pragma Assert
+ (Extra_Formals_Match_OK
+ (E => Interface_Alias (Subp),
+ Ref_E => Alias (Subp)));
+ end if;
+
+ -- 2) The extra formals of its renamed primitive
+
+ if Present (Alias (Subp)) then
+ pragma Assert
+ (Extra_Formals_Match_OK
+ (E => Subp,
+ Ref_E => Ultimate_Alias (Subp)));
+ end if;
+
+ -- 3) The extra formals of its overridden primitive
+
+ if Present (Overridden_Operation (Subp)) then
+ Ovr_Subp := Overridden_Operation (Subp);
+
+ -- Handle controlling function wrapper
+
+ if Is_Wrapper (Subp)
+ and then Ultimate_Alias (Ovr_Subp) = Subp
+ then
+ if Present (Overridden_Operation (Ovr_Subp)) then
+ pragma Assert
+ (Extra_Formals_Match_OK
+ (E => Subp,
+ Ref_E => Overridden_Operation (Ovr_Subp)));
+ end if;
+
+ else
+ pragma Assert
+ (Extra_Formals_Match_OK
+ (E => Subp,
+ Ref_E => Ovr_Subp));
+ end if;
+ end if;
+
+ Next_Elmt (Elmt);
+ end loop;
+ end Validate_Tagged_Type_Extra_Formals;
+
-- Local variables
Typ : constant Node_Id := Entity (N);
@@ -5896,28 +5964,58 @@ package body Exp_Ch3 is
-- inherited functions, then add their bodies to the freeze actions.
Append_Freeze_Actions (Typ, Wrapper_Body_List);
+ end if;
- -- Create extra formals for the primitive operations of the type.
- -- This must be done before analyzing the body of the initialization
- -- procedure, because a self-referential type might call one of these
- -- primitives in the body of the init_proc itself.
+ -- Create extra formals for the primitive operations of the type.
+ -- This must be done before analyzing the body of the initialization
+ -- procedure, because a self-referential type might call one of these
+ -- primitives in the body of the init_proc itself.
+ --
+ -- This is not needed:
+ -- 1) If expansion is disabled, because extra formals are only added
+ -- when we are generating code.
+ --
+ -- 2) For types with foreign convention since primitives with foreign
+ -- convention don't have extra formals and AI95-117 requires that
+ -- all primitives of a tagged type inherit the convention.
+ if Expander_Active
+ and then Is_Tagged_Type (Typ)
+ and then not Has_Foreign_Convention (Typ)
+ then
declare
Elmt : Elmt_Id;
- Subp : Entity_Id;
+ E : Entity_Id;
begin
+ -- Add extra formals to primitive operations
+
Elmt := First_Elmt (Primitive_Operations (Typ));
while Present (Elmt) loop
- Subp := Node (Elmt);
- if not Has_Foreign_Convention (Subp)
- and then not Is_Predefined_Dispatching_Operation (Subp)
+ Create_Extra_Formals (Node (Elmt));
+ Next_Elmt (Elmt);
+ end loop;
+
+ -- Add extra formals to renamings of primitive operations. The
+ -- addition of extra formals is done in two steps to minimize
+ -- the compile time required for this action; the evaluation of
+ -- Find_Dispatching_Type() and Contains() is only done here for
+ -- renamings that are not primitive operations.
+
+ E := First_Entity (Scope (Typ));
+ while Present (E) loop
+ if Is_Dispatching_Operation (E)
+ and then Present (Alias (E))
+ and then Find_Dispatching_Type (E) = Typ
+ and then not Contains (Primitive_Operations (Typ), E)
then
- Create_Extra_Formals (Subp);
+ Create_Extra_Formals (E);
end if;
- Next_Elmt (Elmt);
+ Next_Entity (E);
end loop;
+
+ pragma Debug (Validate_Tagged_Type_Extra_Formals (Typ));
end;
end if;
@@ -6191,6 +6289,18 @@ package body Exp_Ch3 is
-- Generate all default initialization actions for object Def_Id. Any
-- new code is inserted after node After.
+ procedure Initialize_Return_Object
+ (Tag_Assign : Node_Id;
+ Adj_Call : Node_Id;
+ Expr : Node_Id;
+ Init_Stmt : Node_Id;
+ After : Node_Id);
+ -- Generate all initialization actions for return object Def_Id. Any
+ -- new code is inserted after node After.
+
+ function Make_Allocator_For_Return (Expr : Node_Id) return Node_Id;
+ -- Make an allocator for a return object initialized with Expr
+
function OK_To_Rename_Ref (N : Node_Id) return Boolean;
-- Return True if N denotes an entity with OK_To_Rename set
@@ -6949,6 +7059,108 @@ package body Exp_Ch3 is
end if;
end Default_Initialize_Object;
+ ------------------------------
+ -- Initialize_Return_Object --
+ ------------------------------
+
+ procedure Initialize_Return_Object
+ (Tag_Assign : Node_Id;
+ Adj_Call : Node_Id;
+ Expr : Node_Id;
+ Init_Stmt : Node_Id;
+ After : Node_Id)
+ is
+ begin
+ if Present (Tag_Assign) then
+ Insert_Action_After (After, Tag_Assign);
+ end if;
+
+ if Present (Adj_Call) then
+ Insert_Action_After (After, Adj_Call);
+ end if;
+
+ if No (Expr) then
+ Default_Initialize_Object (After);
+
+ elsif Is_Delayed_Aggregate (Expr)
+ and then not No_Initialization (N)
+ then
+ Convert_Aggr_In_Object_Decl (N);
+
+ elsif Present (Init_Stmt) then
+ Insert_Action_After (After, Init_Stmt);
+ Set_Expression (N, Empty);
+ end if;
+ end Initialize_Return_Object;
+
+ -------------------------------
+ -- Make_Allocator_For_Return --
+ -------------------------------
+
+ function Make_Allocator_For_Return (Expr : Node_Id) return Node_Id is
+ Func_Id : constant Entity_Id := Return_Applies_To (Scope (Def_Id));
+
+ Alloc : Node_Id;
+
+ begin
+ -- If the return object's declaration includes an expression and the
+ -- declaration isn't marked as No_Initialization, then we generate an
+ -- allocator with a qualified expression. Although this is necessary
+ -- only in the case where the result type is an interface (or class-
+ -- wide interface), we do it in all cases for the sake of consistency
+ -- instead of subsequently generating a separate assignment.
+
+ if Present (Expr)
+ and then not Is_Delayed_Aggregate (Expr)
+ and then not No_Initialization (N)
+ then
+ -- Ada 2005 (AI95-344): If the result type is class-wide, insert
+ -- a check that the level of the return expression's underlying
+ -- type is not deeper than the level of the master enclosing the
+ -- function.
+
+ -- AI12-043: The check is made immediately after the return object
+ -- is created.
+
+ if Is_Class_Wide_Type (Etype (Func_Id)) then
+ Apply_CW_Accessibility_Check (Expr, Func_Id);
+ end if;
+
+ -- We always use the type of the expression for the qualified
+ -- expression, rather than the return object's type. We cannot
+ -- always use the return object's type because the expression
+ -- might be of a specific type and the result object mignt not.
+
+ Alloc :=
+ Make_Allocator (Loc,
+ Expression =>
+ Make_Qualified_Expression (Loc,
+ Subtype_Mark =>
+ New_Occurrence_Of (Etype (Expr), Loc),
+ Expression => New_Copy_Tree (Expr)));
+
+ else
+ Alloc :=
+ Make_Allocator (Loc,
+ Expression => New_Occurrence_Of (Typ, Loc));
+
+ -- If the return object requires default initialization, then it
+ -- will happen later following the elaboration of the renaming.
+ -- If we don't turn it off here, then the object will be default
+ -- initialized twice.
+
+ Set_No_Initialization (Alloc);
+ end if;
+
+ -- Set the flag indicating that the allocator is made for a special
+ -- return object. This is used to bypass various legality checks as
+ -- well as to make sure that the result is not adjusted twice.
+
+ Set_For_Special_Return_Object (Alloc);
+
+ return Alloc;
+ end Make_Allocator_For_Return;
+
----------------------
-- OK_To_Rename_Ref --
----------------------
@@ -6962,10 +7174,9 @@ package body Exp_Ch3 is
-- Local variables
- Adj_Call : Node_Id;
- Expr_Q : Node_Id;
- Id_Ref : Node_Id;
- Tag_Assign : Node_Id;
+ Adj_Call : Node_Id := Empty;
+ Expr_Q : Node_Id := Empty;
+ Tag_Assign : Node_Id := Empty;
Init_After : Node_Id := N;
-- Node after which the initialization actions are to be inserted. This
@@ -7074,8 +7285,6 @@ package body Exp_Ch3 is
-- Default initialization required, and no expression present
if No (Expr) then
- Expr_Q := Expr;
-
-- If we have a type with a variant part, the initialization proc
-- will contain implicit tests of the discriminant values, which
-- counts as a violation of the restriction No_Implicit_Conditionals.
@@ -7134,7 +7343,7 @@ package body Exp_Ch3 is
end if;
end if;
- if not Is_Build_In_Place_Return_Object (Def_Id) then
+ if not Is_Special_Return_Object (Def_Id) then
Default_Initialize_Object (Init_After);
end if;
@@ -7194,7 +7403,7 @@ package body Exp_Ch3 is
Expander_Mode_Restore;
end if;
- if not Is_Build_In_Place_Return_Object (Def_Id) then
+ if not Is_Special_Return_Object (Def_Id) then
Convert_Aggr_In_Object_Decl (N);
end if;
@@ -7265,12 +7474,12 @@ package body Exp_Ch3 is
then
pragma Assert (Is_Class_Wide_Type (Typ));
- -- If the object is a built-in-place return object, bypass special
+ -- If the object is a special return object, then bypass special
-- treatment of class-wide interface initialization below. In this
-- case, the expansion of the return statement will take care of
-- creating the object (via allocator) and initializing it.
- if Is_Build_In_Place_Return_Object (Def_Id) then
+ if Is_Special_Return_Object (Def_Id) then
null;
elsif Tagged_Type_Expansion then
@@ -7570,8 +7779,7 @@ package body Exp_Ch3 is
if Present (Tag_Assign) then
if Present (Following_Address_Clause (N)) then
Ensure_Freeze_Node (Def_Id);
-
- else
+ elsif not Is_Special_Return_Object (Def_Id) then
Insert_Action_After (Init_After, Tag_Assign);
end if;
@@ -7581,23 +7789,26 @@ package body Exp_Ch3 is
-- record type.
elsif Is_CPP_Constructor_Call (Expr) then
+ declare
+ Id_Ref : constant Node_Id := New_Occurrence_Of (Def_Id, Loc);
- -- The call to the initialization procedure does NOT freeze the
- -- object being initialized.
+ begin
+ -- The call to the initialization procedure does NOT freeze
+ -- the object being initialized.
- Id_Ref := New_Occurrence_Of (Def_Id, Loc);
- Set_Must_Not_Freeze (Id_Ref);
- Set_Assignment_OK (Id_Ref);
+ Set_Must_Not_Freeze (Id_Ref);
+ Set_Assignment_OK (Id_Ref);
- Insert_Actions_After (Init_After,
- Build_Initialization_Call (Loc, Id_Ref, Typ,
- Constructor_Ref => Expr));
+ Insert_Actions_After (Init_After,
+ Build_Initialization_Call (Loc, Id_Ref, Typ,
+ Constructor_Ref => Expr));
- -- We remove here the original call to the constructor
- -- to avoid its management in the backend
+ -- We remove here the original call to the constructor
+ -- to avoid its management in the backend
- Set_Expression (N, Empty);
- return;
+ Set_Expression (N, Empty);
+ return;
+ end;
-- Handle initialization of limited tagged types
@@ -7637,18 +7848,15 @@ package body Exp_Ch3 is
then
Set_Is_Known_Valid (Def_Id);
- elsif Is_Access_Type (Typ) then
+ -- For access types, set the Is_Known_Non_Null flag if the
+ -- initializing value is known to be non-null. We can also
+ -- set Can_Never_Be_Null if this is a constant.
- -- For access types set the Is_Known_Non_Null flag if the
- -- initializing value is known to be non-null. We can also set
- -- Can_Never_Be_Null if this is a constant.
+ elsif Is_Access_Type (Typ) and then Known_Non_Null (Expr) then
+ Set_Is_Known_Non_Null (Def_Id, True);
- if Known_Non_Null (Expr) then
- Set_Is_Known_Non_Null (Def_Id, True);
-
- if Constant_Present (N) then
- Set_Can_Never_Be_Null (Def_Id);
- end if;
+ if Constant_Present (N) then
+ Set_Can_Never_Be_Null (Def_Id);
end if;
end if;
@@ -7661,9 +7869,10 @@ package body Exp_Ch3 is
if Validity_Checks_On
and then Comes_From_Source (N)
and then Validity_Check_Copies
- and then not Is_Generic_Type (Etype (Def_Id))
+ and then not Is_Generic_Type (Typ)
then
Ensure_Valid (Expr);
+
if Safe_To_Capture_Value (N, Def_Id) then
Set_Is_Known_Valid (Def_Id);
end if;
@@ -7741,10 +7950,9 @@ package body Exp_Ch3 is
Obj_Ref => New_Occurrence_Of (Def_Id, Loc),
Typ => Base_Typ);
- -- Guard against a missing [Deep_]Adjust when the base type
- -- was not properly frozen.
-
- if Present (Adj_Call) then
+ if Present (Adj_Call)
+ and then not Is_Special_Return_Object (Def_Id)
+ then
Insert_Action_After (Init_After, Adj_Call);
end if;
end if;
@@ -7779,7 +7987,7 @@ package body Exp_Ch3 is
end if;
if Nkind (Obj_Def) = N_Access_Definition
- and then not Is_Local_Anonymous_Access (Etype (Def_Id))
+ and then not Is_Local_Anonymous_Access (Typ)
then
-- An Ada 2012 stand-alone object of an anonymous access type
@@ -7891,16 +8099,17 @@ package body Exp_Ch3 is
-- if BIPalloc = 1 then
-- Rxx := BIPaccess;
+ -- Rxx.all := <expression>;
-- elsif BIPalloc = 2 then
- -- Rxx := new <expression-type>[storage_pool =
+ -- Rxx := new <expression-type>'(<expression>)[storage_pool =
-- system__secondary_stack__ss_pool][procedure_to_call =
-- system__secondary_stack__ss_allocate];
-- elsif BIPalloc = 3 then
- -- Rxx := new <expression-type>
+ -- Rxx := new <expression-type>'(<expression>)
-- elsif BIPalloc = 4 then
-- Pxx : system__storage_pools__root_storage_pool renames
-- BIPstoragepool.all;
- -- Rxx := new <expression-type>[storage_pool =
+ -- Rxx := new <expression-type>'(<expression>)[storage_pool =
-- Pxx][procedure_to_call =
-- system__storage_pools__allocate_any];
-- else
@@ -7908,15 +8117,12 @@ package body Exp_Ch3 is
-- end if;
-- Result : T renames Rxx.all;
- -- Result := <expression>;
-- in the unconstrained case.
if Is_Build_In_Place_Return_Object (Def_Id) then
declare
- Func_Id : constant Entity_Id :=
- Return_Applies_To (Scope (Def_Id));
- Ret_Obj_Typ : constant Entity_Id := Etype (Def_Id);
+ Func_Id : constant Entity_Id := Return_Applies_To (Scope (Def_Id));
Init_Stmt : Node_Id;
Obj_Acc_Formal : Entity_Id;
@@ -7946,9 +8152,9 @@ package body Exp_Ch3 is
if Present (Expr_Q)
and then not Is_Delayed_Aggregate (Expr_Q)
and then not No_Initialization (N)
- and then not Is_Interface (Etype (Def_Id))
+ and then not Is_Interface (Typ)
then
- if Is_Class_Wide_Type (Etype (Def_Id))
+ if Is_Class_Wide_Type (Typ)
and then not Is_Class_Wide_Type (Etype (Expr_Q))
then
Init_Stmt :=
@@ -7957,7 +8163,7 @@ package body Exp_Ch3 is
Expression =>
Make_Type_Conversion (Loc,
Subtype_Mark =>
- New_Occurrence_Of (Etype (Def_Id), Loc),
+ New_Occurrence_Of (Typ, Loc),
Expression => New_Copy_Tree (Expr_Q)));
else
@@ -7990,111 +8196,45 @@ package body Exp_Ch3 is
if Needs_BIP_Alloc_Form (Func_Id) then
declare
Desig_Typ : constant Entity_Id :=
- (if Ekind (Ret_Obj_Typ) = E_Array_Subtype
- then Etype (Func_Id) else Ret_Obj_Typ);
+ (if Ekind (Typ) = E_Array_Subtype
+ then Etype (Func_Id) else Typ);
-- Ensure that the we use a fat pointer when allocating
-- an unconstrained array on the heap. In this case the
- -- result object type is a constrained array type even
- -- though the function type is unconstrained.
+ -- result object's type is a constrained array type even
+ -- though the function's type is unconstrained.
+
Obj_Alloc_Formal : constant Entity_Id :=
Build_In_Place_Formal (Func_Id, BIP_Alloc_Form);
Pool_Id : constant Entity_Id :=
Make_Temporary (Loc, 'P');
- function Make_Allocator_For_BIP_Return return Node_Id;
- -- Make an allocator for the BIP return being processed
-
- -----------------------------------
- -- Make_Allocator_For_BIP_Return --
- -----------------------------------
-
- function Make_Allocator_For_BIP_Return return Node_Id is
- Alloc : Node_Id;
-
- begin
- if Present (Expr_Q)
- and then not Is_Delayed_Aggregate (Expr_Q)
- and then not No_Initialization (N)
- then
- -- Always use the type of the expression for the
- -- qualified expression, rather than the result type.
- -- In general we cannot always use the result type
- -- for the allocator, because the expression might be
- -- of a specific type, such as in the case of an
- -- aggregate or even a nonlimited object when the
- -- result type is a limited class-wide interface type.
-
- Alloc :=
- Make_Allocator (Loc,
- Expression =>
- Make_Qualified_Expression (Loc,
- Subtype_Mark =>
- New_Occurrence_Of (Etype (Expr_Q), Loc),
- Expression => New_Copy_Tree (Expr_Q)));
-
- else
- -- If the function returns a class-wide type we cannot
- -- use the return type for the allocator. Instead we
- -- use the type of the expression, which must be an
- -- aggregate of a definite type.
-
- if Is_Class_Wide_Type (Ret_Obj_Typ) then
- Alloc :=
- Make_Allocator (Loc,
- Expression =>
- New_Occurrence_Of (Etype (Expr_Q), Loc));
-
- else
- Alloc :=
- Make_Allocator (Loc,
- Expression =>
- New_Occurrence_Of (Ret_Obj_Typ, Loc));
- end if;
-
- -- If the object requires default initialization then
- -- that will happen later following the elaboration of
- -- the object renaming. If we don't turn it off here
- -- then the object will be default initialized twice.
-
- Set_No_Initialization (Alloc);
- end if;
-
- -- Set the flag indicating that the allocator came from
- -- a build-in-place return statement, so we can avoid
- -- adjusting the allocated object.
-
- Set_Alloc_For_BIP_Return (Alloc);
-
- return Alloc;
- end Make_Allocator_For_BIP_Return;
-
- Alloc_Obj_Id : Entity_Id;
+ Acc_Typ : Entity_Id;
Alloc_Obj_Decl : Node_Id;
- Alloc_Stmt : Node_Id;
+ Alloc_Obj_Id : Entity_Id;
+ Alloc_Stmt : Node_Id;
Guard_Except : Node_Id;
Heap_Allocator : Node_Id;
- Pool_Decl : Node_Id;
Pool_Allocator : Node_Id;
- Ptr_Type_Decl : Node_Id;
- Ref_Type : Entity_Id;
+ Pool_Decl : Node_Id;
+ Ptr_Typ_Decl : Node_Id;
SS_Allocator : Node_Id;
begin
-- Create an access type designating the function's
-- result subtype.
- Ref_Type := Make_Temporary (Loc, 'A');
+ Acc_Typ := Make_Temporary (Loc, 'A');
- Ptr_Type_Decl :=
+ Ptr_Typ_Decl :=
Make_Full_Type_Declaration (Loc,
- Defining_Identifier => Ref_Type,
+ Defining_Identifier => Acc_Typ,
Type_Definition =>
Make_Access_To_Object_Definition (Loc,
All_Present => True,
Subtype_Indication =>
New_Occurrence_Of (Desig_Typ, Loc)));
- Insert_Action (N, Ptr_Type_Decl);
+ Insert_Action (N, Ptr_Typ_Decl, Suppress => All_Checks);
-- Create an access object that will be initialized to an
-- access value denoting the return object, either coming
@@ -8102,25 +8242,24 @@ package body Exp_Ch3 is
-- or from the result of an allocator.
Alloc_Obj_Id := Make_Temporary (Loc, 'R');
- Set_Etype (Alloc_Obj_Id, Ref_Type);
Alloc_Obj_Decl :=
Make_Object_Declaration (Loc,
Defining_Identifier => Alloc_Obj_Id,
Object_Definition =>
- New_Occurrence_Of (Ref_Type, Loc));
+ New_Occurrence_Of (Acc_Typ, Loc));
- Insert_Action (N, Alloc_Obj_Decl);
+ Insert_Action (N, Alloc_Obj_Decl, Suppress => All_Checks);
-- First create the Heap_Allocator
- Heap_Allocator := Make_Allocator_For_BIP_Return;
+ Heap_Allocator := Make_Allocator_For_Return (Expr_Q);
-- The Pool_Allocator is just like the Heap_Allocator,
-- except we set Storage_Pool and Procedure_To_Call so
-- it will use the user-defined storage pool.
- Pool_Allocator := Make_Allocator_For_BIP_Return;
+ Pool_Allocator := Make_Allocator_For_Return (Expr_Q);
-- Do not generate the renaming of the build-in-place
-- pool parameter on ZFP because the parameter is not
@@ -8161,7 +8300,7 @@ package body Exp_Ch3 is
-- allocation.
else
- SS_Allocator := Make_Allocator_For_BIP_Return;
+ SS_Allocator := Make_Allocator_For_Return (Expr_Q);
-- The heap and pool allocators are marked as
-- Comes_From_Source since they correspond to an
@@ -8223,7 +8362,7 @@ package body Exp_Ch3 is
-- to-unconstrained to access-to-constrained), but the
-- the unchecked conversion will presumably fail to work
-- right in just such cases. It's not clear at all how to
- -- handle this. ???
+ -- handle this.
Alloc_Stmt :=
Make_If_Statement (Loc,
@@ -8242,7 +8381,7 @@ package body Exp_Ch3 is
New_Occurrence_Of (Alloc_Obj_Id, Loc),
Expression =>
Unchecked_Convert_To
- (Ref_Type,
+ (Acc_Typ,
New_Occurrence_Of (Obj_Acc_Formal, Loc)))),
Elsif_Parts => New_List (
@@ -8275,12 +8414,12 @@ package body Exp_Ch3 is
Then_Statements => New_List (
Build_Heap_Or_Pool_Allocator
(Temp_Id => Alloc_Obj_Id,
- Temp_Typ => Ref_Type,
+ Temp_Typ => Acc_Typ,
Func_Id => Func_Id,
Ret_Typ => Desig_Typ,
Alloc_Expr => Heap_Allocator))),
- -- ???If all is well, we can put the following
+ -- ??? If all is well, we can put the following
-- 'elsif' in the 'else', but this is a useful
-- self-check in case caller and callee don't agree
-- on whether BIPAlloc and so on should be passed.
@@ -8299,7 +8438,7 @@ package body Exp_Ch3 is
Pool_Decl,
Build_Heap_Or_Pool_Allocator
(Temp_Id => Alloc_Obj_Id,
- Temp_Typ => Ref_Type,
+ Temp_Typ => Acc_Typ,
Func_Id => Func_Id,
Ret_Typ => Desig_Typ,
Alloc_Expr => Pool_Allocator)))),
@@ -8332,7 +8471,10 @@ package body Exp_Ch3 is
-- From now on, the type of the return object is the
-- designated type.
- Set_Etype (Def_Id, Desig_Typ);
+ if Desig_Typ /= Typ then
+ Set_Etype (Def_Id, Desig_Typ);
+ Set_Actual_Subtype (Def_Id, Typ);
+ end if;
-- Remember the local access object for use in the
-- dereference of the renaming created below.
@@ -8340,33 +8482,33 @@ package body Exp_Ch3 is
Obj_Acc_Formal := Alloc_Obj_Id;
end;
- -- When the function's subtype is unconstrained and a run-time
- -- test is not needed, we nevertheless need to build the return
- -- using the function's result subtype.
+ -- When the function's type is unconstrained and a run-time test
+ -- is not needed, we nevertheless need to build the return using
+ -- the return object's type.
elsif not Is_Constrained (Underlying_Type (Etype (Func_Id))) then
declare
- Alloc_Obj_Id : Entity_Id;
+ Acc_Typ : Entity_Id;
Alloc_Obj_Decl : Node_Id;
- Ptr_Type_Decl : Node_Id;
- Ref_Type : Entity_Id;
+ Alloc_Obj_Id : Entity_Id;
+ Ptr_Typ_Decl : Node_Id;
begin
-- Create an access type designating the function's
-- result subtype.
- Ref_Type := Make_Temporary (Loc, 'A');
+ Acc_Typ := Make_Temporary (Loc, 'A');
- Ptr_Type_Decl :=
+ Ptr_Typ_Decl :=
Make_Full_Type_Declaration (Loc,
- Defining_Identifier => Ref_Type,
+ Defining_Identifier => Acc_Typ,
Type_Definition =>
Make_Access_To_Object_Definition (Loc,
All_Present => True,
Subtype_Indication =>
- New_Occurrence_Of (Ret_Obj_Typ, Loc)));
+ New_Occurrence_Of (Typ, Loc)));
- Insert_Action (N, Ptr_Type_Decl);
+ Insert_Action (N, Ptr_Typ_Decl, Suppress => All_Checks);
-- Create an access object initialized to the conversion
-- of the implicit access value passed in by the caller.
@@ -8379,12 +8521,12 @@ package body Exp_Ch3 is
Alloc_Obj_Decl :=
Make_Object_Declaration (Loc,
Defining_Identifier => Alloc_Obj_Id,
+ Constant_Present => True,
Object_Definition =>
- New_Occurrence_Of (Ref_Type, Loc),
+ New_Occurrence_Of (Acc_Typ, Loc),
Expression =>
Unchecked_Convert_To
- (Ref_Type,
- New_Occurrence_Of (Obj_Acc_Formal, Loc)));
+ (Acc_Typ, New_Occurrence_Of (Obj_Acc_Formal, Loc)));
Insert_Action (N, Alloc_Obj_Decl, Suppress => All_Checks);
@@ -8398,25 +8540,207 @@ package body Exp_Ch3 is
-- Initialize the object now that it has got its final subtype,
-- but before rewriting it as a renaming.
- if No (Expr_Q) then
- Default_Initialize_Object (Init_After);
+ Initialize_Return_Object
+ (Tag_Assign, Adj_Call, Expr_Q, Init_Stmt, Init_After);
- elsif Is_Delayed_Aggregate (Expr_Q)
- and then not No_Initialization (N)
- then
- Convert_Aggr_In_Object_Decl (N);
+ -- Replace the return object declaration with a renaming of a
+ -- dereference of the access value designating the return object.
- elsif Present (Init_Stmt) then
- Insert_Action_After (Init_After, Init_Stmt);
- Set_Expression (N, Empty);
+ Expr_Q :=
+ Make_Explicit_Dereference (Loc,
+ Prefix => New_Occurrence_Of (Obj_Acc_Formal, Loc));
+ Set_Etype (Expr_Q, Etype (Def_Id));
+
+ Rewrite_As_Renaming := True;
+ end;
+
+ -- If we can rename the initialization expression, we need to make sure
+ -- that we use the proper type in the case of a return object that lives
+ -- on the secondary stack. See other cases below for a similar handling.
+
+ elsif Rewrite_As_Renaming then
+ if Is_Secondary_Stack_Return_Object (Def_Id) then
+ declare
+ Func_Id : constant Entity_Id :=
+ Return_Applies_To (Scope (Def_Id));
+
+ Desig_Typ : constant Entity_Id :=
+ (if Ekind (Typ) = E_Array_Subtype
+ then Etype (Func_Id) else Typ);
+
+ begin
+ -- From now on, the type of the return object is the
+ -- designated type.
+
+ if Desig_Typ /= Typ then
+ Set_Etype (Def_Id, Desig_Typ);
+ Set_Actual_Subtype (Def_Id, Typ);
+ end if;
+ end;
+ end if;
+
+ -- If this is the return object of a function returning on the secondary
+ -- stack, convert the declaration to a renaming of the dereference of ah
+ -- allocator for the secondary stack.
+
+ -- Result : T [:= <expression>];
+
+ -- is converted to
+
+ -- type Txx is access all ...;
+ -- Rxx : constant Txx :=
+ -- new <expression-type>['(<expression>)][storage_pool =
+ -- system__secondary_stack__ss_pool][procedure_to_call =
+ -- system__secondary_stack__ss_allocate];
+
+ -- Result : T renames Rxx.all;
+
+ elsif Is_Secondary_Stack_Return_Object (Def_Id) then
+ declare
+ Func_Id : constant Entity_Id :=
+ Return_Applies_To (Scope (Def_Id));
+
+ Desig_Typ : constant Entity_Id :=
+ (if Ekind (Typ) = E_Array_Subtype
+ then Etype (Func_Id) else Typ);
+ -- Ensure that the we use a fat pointer when allocating
+ -- an unconstrained array on the heap. In this case the
+ -- result object's type is a constrained array type even
+ -- though the function's type is unconstrained.
+
+ Acc_Typ : Entity_Id;
+ Alloc_Obj_Decl : Node_Id;
+ Alloc_Obj_Id : Entity_Id;
+ Ptr_Type_Decl : Node_Id;
+
+ begin
+ -- Create an access type designating the function's
+ -- result subtype.
+
+ Acc_Typ := Make_Temporary (Loc, 'A');
+
+ Ptr_Type_Decl :=
+ Make_Full_Type_Declaration (Loc,
+ Defining_Identifier => Acc_Typ,
+ Type_Definition =>
+ Make_Access_To_Object_Definition (Loc,
+ All_Present => True,
+ Subtype_Indication =>
+ New_Occurrence_Of (Desig_Typ, Loc)));
+
+ Insert_Action (N, Ptr_Type_Decl, Suppress => All_Checks);
+
+ Set_Associated_Storage_Pool (Acc_Typ, RTE (RE_SS_Pool));
+
+ Alloc_Obj_Id := Make_Temporary (Loc, 'R');
+
+ Alloc_Obj_Decl :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Alloc_Obj_Id,
+ Constant_Present => True,
+ Object_Definition =>
+ New_Occurrence_Of (Acc_Typ, Loc),
+ Expression => Make_Allocator_For_Return (Expr_Q));
+
+ Insert_Action (N, Alloc_Obj_Decl, Suppress => All_Checks);
+
+ Set_Uses_Sec_Stack (Func_Id);
+ Set_Uses_Sec_Stack (Scope (Def_Id));
+ Set_Sec_Stack_Needed_For_Return (Scope (Def_Id));
+
+ -- From now on, the type of the return object is the
+ -- designated type.
+
+ if Desig_Typ /= Typ then
+ Set_Etype (Def_Id, Desig_Typ);
+ Set_Actual_Subtype (Def_Id, Typ);
end if;
+ -- Initialize the object now that it has got its final subtype,
+ -- but before rewriting it as a renaming.
+
+ Initialize_Return_Object
+ (Tag_Assign, Adj_Call, Expr_Q, Empty, Init_After);
+
-- Replace the return object declaration with a renaming of a
-- dereference of the access value designating the return object.
Expr_Q :=
Make_Explicit_Dereference (Loc,
- Prefix => New_Occurrence_Of (Obj_Acc_Formal, Loc));
+ Prefix => New_Occurrence_Of (Alloc_Obj_Id, Loc));
+ Set_Etype (Expr_Q, Etype (Def_Id));
+
+ Rewrite_As_Renaming := True;
+ end;
+
+ -- If this is the return object of a function returning a by-reference
+ -- type, convert the declaration to a renaming of the dereference of ah
+ -- allocator for the return stack.
+
+ -- Result : T [:= <expression>];
+
+ -- is converted to
+
+ -- type Txx is access all ...;
+ -- Rxx : constant Txx :=
+ -- new <expression-type>['(<expression>)][storage_pool =
+ -- system__secondary_stack__rs_pool][procedure_to_call =
+ -- system__secondary_stack__rs_allocate];
+
+ -- Result : T renames Rxx.all;
+
+ elsif Back_End_Return_Slot
+ and then Is_By_Reference_Return_Object (Def_Id)
+ then
+ declare
+ Acc_Typ : Entity_Id;
+ Alloc_Obj_Decl : Node_Id;
+ Alloc_Obj_Id : Entity_Id;
+ Ptr_Type_Decl : Node_Id;
+
+ begin
+ -- Create an access type designating the function's
+ -- result subtype.
+
+ Acc_Typ := Make_Temporary (Loc, 'A');
+
+ Ptr_Type_Decl :=
+ Make_Full_Type_Declaration (Loc,
+ Defining_Identifier => Acc_Typ,
+ Type_Definition =>
+ Make_Access_To_Object_Definition (Loc,
+ All_Present => True,
+ Subtype_Indication =>
+ New_Occurrence_Of (Typ, Loc)));
+
+ Insert_Action (N, Ptr_Type_Decl, Suppress => All_Checks);
+
+ Set_Associated_Storage_Pool (Acc_Typ, RTE (RE_RS_Pool));
+
+ Alloc_Obj_Id := Make_Temporary (Loc, 'R');
+
+ Alloc_Obj_Decl :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Alloc_Obj_Id,
+ Constant_Present => True,
+ Object_Definition =>
+ New_Occurrence_Of (Acc_Typ, Loc),
+ Expression => Make_Allocator_For_Return (Expr_Q));
+
+ Insert_Action (N, Alloc_Obj_Decl, Suppress => All_Checks);
+
+ -- Initialize the object now that it has got its final subtype,
+ -- but before rewriting it as a renaming.
+
+ Initialize_Return_Object
+ (Tag_Assign, Adj_Call, Expr_Q, Empty, Init_After);
+
+ -- Replace the return object declaration with a renaming of a
+ -- dereference of the access value designating the return object.
+
+ Expr_Q :=
+ Make_Explicit_Dereference (Loc,
+ Prefix => New_Occurrence_Of (Alloc_Obj_Id, Loc));
Set_Etype (Expr_Q, Etype (Def_Id));
Rewrite_As_Renaming := True;
@@ -11676,37 +12000,39 @@ package body Exp_Ch3 is
function Make_Tag_Assignment (N : Node_Id) return Node_Id is
Loc : constant Source_Ptr := Sloc (N);
- Def_If : constant Entity_Id := Defining_Identifier (N);
- Expr : constant Node_Id := Expression (N);
- Typ : constant Entity_Id := Etype (Def_If);
- Full_Typ : constant Entity_Id := Underlying_Type (Typ);
+ Def_If : constant Entity_Id := Defining_Identifier (N);
+ Expr : constant Node_Id := Expression (N);
+ Typ : constant Entity_Id := Etype (Def_If);
+ Full_Typ : constant Entity_Id := Underlying_Type (Typ);
+
New_Ref : Node_Id;
begin
- -- This expansion activity is called during analysis.
+ -- This expansion activity is called during analysis
if Is_Tagged_Type (Typ)
- and then not Is_Class_Wide_Type (Typ)
- and then not Is_CPP_Class (Typ)
- and then Tagged_Type_Expansion
- and then Nkind (Expr) /= N_Aggregate
- and then (Nkind (Expr) /= N_Qualified_Expression
- or else Nkind (Expression (Expr)) /= N_Aggregate)
+ and then not Is_Class_Wide_Type (Typ)
+ and then not Is_CPP_Class (Typ)
+ and then Tagged_Type_Expansion
+ and then Nkind (Expr) /= N_Aggregate
+ and then (Nkind (Expr) /= N_Qualified_Expression
+ or else Nkind (Expression (Expr)) /= N_Aggregate)
then
New_Ref :=
Make_Selected_Component (Loc,
- Prefix => New_Occurrence_Of (Def_If, Loc),
- Selector_Name =>
- New_Occurrence_Of (First_Tag_Component (Full_Typ), Loc));
+ Prefix => New_Occurrence_Of (Def_If, Loc),
+ Selector_Name =>
+ New_Occurrence_Of (First_Tag_Component (Full_Typ), Loc));
+
Set_Assignment_OK (New_Ref);
return
Make_Assignment_Statement (Loc,
- Name => New_Ref,
- Expression =>
- Unchecked_Convert_To (RTE (RE_Tag),
- New_Occurrence_Of (Node
- (First_Elmt (Access_Disp_Table (Full_Typ))), Loc)));
+ Name => New_Ref,
+ Expression =>
+ Unchecked_Convert_To (RTE (RE_Tag),
+ New_Occurrence_Of
+ (Node (First_Elmt (Access_Disp_Table (Full_Typ))), Loc)));
else
return Empty;
end if;
diff --git a/gcc/ada/exp_ch3.ads b/gcc/ada/exp_ch3.ads
index f7d43c4..24e2263 100644
--- a/gcc/ada/exp_ch3.ads
+++ b/gcc/ada/exp_ch3.ads
@@ -25,9 +25,10 @@
-- Expand routines for chapter 3 constructs
-with Types; use Types;
-with Elists; use Elists;
-with Uintp; use Uintp;
+with Types; use Types;
+with Elists; use Elists;
+with Exp_Tss; use Exp_Tss;
+with Uintp; use Uintp;
package Exp_Ch3 is
@@ -207,4 +208,13 @@ package Exp_Ch3 is
-- Make_Predefined_Primitive_Eq_Spec; see there for description of
-- the Renamed_Eq parameter.
+ function Stream_Operation_OK
+ (Typ : Entity_Id;
+ Operation : TSS_Name_Type) return Boolean;
+ -- Check whether the named stream operation must be emitted for a given
+ -- type. The rules for inheritance of stream attributes by type extensions
+ -- are enforced by this function. Furthermore, various restrictions prevent
+ -- the generation of these operations, as a useful optimization or for
+ -- certification purposes and to save unnecessary generated code.
+
end Exp_Ch3;
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 0b7e391..a8980a6 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Accessibility; use Accessibility;
with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
@@ -33,7 +34,6 @@ with Einfo.Utils; use Einfo.Utils;
with Elists; use Elists;
with Errout; use Errout;
with Exp_Aggr; use Exp_Aggr;
-with Exp_Atag; use Exp_Atag;
with Exp_Ch3; use Exp_Ch3;
with Exp_Ch6; use Exp_Ch6;
with Exp_Ch7; use Exp_Ch7;
@@ -151,14 +151,17 @@ package body Exp_Ch4 is
-- where we allow comparison of "out of range" values.
function Expand_Composite_Equality
- (Nod : Node_Id;
- Typ : Entity_Id;
- Lhs : Node_Id;
- Rhs : Node_Id) return Node_Id;
+ (Outer_Type : Entity_Id;
+ Nod : Node_Id;
+ Comp_Type : Entity_Id;
+ Lhs : Node_Id;
+ Rhs : Node_Id) return Node_Id;
-- Local recursive function used to expand equality for nested composite
-- types. Used by Expand_Record/Array_Equality. Nod provides the Sloc value
-- for generated code. Lhs and Rhs are the left and right sides for the
- -- comparison, and Typ is the type of the objects to compare.
+ -- comparison, and Comp_Typ is the type of the objects to compare.
+ -- Outer_Type is the composite type containing a component of type
+ -- Comp_Type -- used for printing messages.
procedure Expand_Concatenate (Cnode : Node_Id; Opnds : List_Id);
-- Routine to expand concatenation of a sequence of two or more operands
@@ -557,219 +560,6 @@ package body Exp_Ch4 is
PtrT : constant Entity_Id := Etype (N);
DesigT : constant Entity_Id := Designated_Type (PtrT);
- procedure Apply_Accessibility_Check
- (Ref : Node_Id;
- Built_In_Place : Boolean := False);
- -- Ada 2005 (AI-344): For an allocator with a class-wide designated
- -- type, generate an accessibility check to verify that the level of the
- -- type of the created object is not deeper than the level of the access
- -- type. If the type of the qualified expression is class-wide, then
- -- always generate the check (except in the case where it is known to be
- -- unnecessary, see comment below). Otherwise, only generate the check
- -- if the level of the qualified expression type is statically deeper
- -- than the access type.
- --
- -- Although the static accessibility will generally have been performed
- -- as a legality check, it won't have been done in cases where the
- -- allocator appears in generic body, so a run-time check is needed in
- -- general. One special case is when the access type is declared in the
- -- same scope as the class-wide allocator, in which case the check can
- -- never fail, so it need not be generated.
- --
- -- As an open issue, there seem to be cases where the static level
- -- associated with the class-wide object's underlying type is not
- -- sufficient to perform the proper accessibility check, such as for
- -- allocators in nested subprograms or accept statements initialized by
- -- class-wide formals when the actual originates outside at a deeper
- -- static level. The nested subprogram case might require passing
- -- accessibility levels along with class-wide parameters, and the task
- -- case seems to be an actual gap in the language rules that needs to
- -- be fixed by the ARG. ???
-
- -------------------------------
- -- Apply_Accessibility_Check --
- -------------------------------
-
- procedure Apply_Accessibility_Check
- (Ref : Node_Id;
- Built_In_Place : Boolean := False)
- is
- Pool_Id : constant Entity_Id := Associated_Storage_Pool (PtrT);
- Cond : Node_Id;
- Fin_Call : Node_Id;
- Free_Stmt : Node_Id;
- Obj_Ref : Node_Id;
- Stmts : List_Id;
-
- begin
- if Ada_Version >= Ada_2005
- 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
- (Is_Class_Wide_Type (Etype (Exp))
- and then Scope (PtrT) /= Current_Scope))
- then
- -- If the allocator was built in place, Ref is already a reference
- -- to the access object initialized to the result of the allocator
- -- (see Exp_Ch6.Make_Build_In_Place_Call_In_Allocator). We call
- -- Remove_Side_Effects for cases where the build-in-place call may
- -- still be the prefix of the reference (to avoid generating
- -- duplicate calls). Otherwise, it is the entity associated with
- -- the object containing the address of the allocated object.
-
- if Built_In_Place then
- Remove_Side_Effects (Ref);
- Obj_Ref := New_Copy_Tree (Ref);
- else
- Obj_Ref := New_Occurrence_Of (Ref, Loc);
- end if;
-
- -- For access to interface types we must generate code to displace
- -- the pointer to the base of the object since the subsequent code
- -- references components located in the TSD of the object (which
- -- is associated with the primary dispatch table --see a-tags.ads)
- -- and also generates code invoking Free, which requires also a
- -- reference to the base of the unallocated object.
-
- if Is_Interface (DesigT) and then Tagged_Type_Expansion then
- Obj_Ref :=
- Unchecked_Convert_To (Etype (Obj_Ref),
- Make_Function_Call (Loc,
- Name =>
- New_Occurrence_Of (RTE (RE_Base_Address), Loc),
- Parameter_Associations => New_List (
- Unchecked_Convert_To (RTE (RE_Address),
- New_Copy_Tree (Obj_Ref)))));
- end if;
-
- -- Step 1: Create the object clean up code
-
- Stmts := New_List;
-
- -- Deallocate the object if the accessibility check fails. This
- -- is done only on targets or profiles that support deallocation.
-
- -- Free (Obj_Ref);
-
- if RTE_Available (RE_Free) then
- Free_Stmt := Make_Free_Statement (Loc, New_Copy_Tree (Obj_Ref));
- Set_Storage_Pool (Free_Stmt, Pool_Id);
-
- Append_To (Stmts, Free_Stmt);
-
- -- The target or profile cannot deallocate objects
-
- else
- Free_Stmt := Empty;
- end if;
-
- -- Finalize the object if applicable. Generate:
-
- -- [Deep_]Finalize (Obj_Ref.all);
-
- if Needs_Finalization (DesigT)
- and then not No_Heap_Finalization (PtrT)
- then
- Fin_Call :=
- Make_Final_Call
- (Obj_Ref =>
- Make_Explicit_Dereference (Loc, New_Copy (Obj_Ref)),
- Typ => DesigT);
-
- -- Guard against a missing [Deep_]Finalize when the designated
- -- type was not properly frozen.
-
- if No (Fin_Call) then
- Fin_Call := Make_Null_Statement (Loc);
- end if;
-
- -- When the target or profile supports deallocation, wrap the
- -- finalization call in a block to ensure proper deallocation
- -- even if finalization fails. Generate:
-
- -- begin
- -- <Fin_Call>
- -- exception
- -- when others =>
- -- <Free_Stmt>
- -- raise;
- -- end;
-
- if Present (Free_Stmt) then
- Fin_Call :=
- Make_Block_Statement (Loc,
- Handled_Statement_Sequence =>
- Make_Handled_Sequence_Of_Statements (Loc,
- Statements => New_List (Fin_Call),
-
- Exception_Handlers => New_List (
- Make_Exception_Handler (Loc,
- Exception_Choices => New_List (
- Make_Others_Choice (Loc)),
- Statements => New_List (
- New_Copy_Tree (Free_Stmt),
- Make_Raise_Statement (Loc))))));
- end if;
-
- Prepend_To (Stmts, Fin_Call);
- end if;
-
- -- Signal the accessibility failure through a Program_Error
-
- Append_To (Stmts,
- Make_Raise_Program_Error (Loc,
- Reason => PE_Accessibility_Check_Failed));
-
- -- Step 2: Create the accessibility comparison
-
- -- Generate:
- -- Ref'Tag
-
- Obj_Ref :=
- Make_Attribute_Reference (Loc,
- Prefix => Obj_Ref,
- Attribute_Name => Name_Tag);
-
- -- For tagged types, determine the accessibility level by looking
- -- at the type specific data of the dispatch table. Generate:
-
- -- Type_Specific_Data (Address (Ref'Tag)).Access_Level
-
- if Tagged_Type_Expansion then
- Cond := Build_Get_Access_Level (Loc, Obj_Ref);
-
- -- Use a runtime call to determine the accessibility level when
- -- compiling on virtual machine targets. Generate:
-
- -- Get_Access_Level (Ref'Tag)
-
- else
- Cond :=
- Make_Function_Call (Loc,
- Name =>
- New_Occurrence_Of (RTE (RE_Get_Access_Level), Loc),
- Parameter_Associations => New_List (Obj_Ref));
- end if;
-
- Cond :=
- Make_Op_Gt (Loc,
- Left_Opnd => Cond,
- Right_Opnd => Accessibility_Level (N, Dynamic_Level));
-
- -- Due to the complexity and side effects of the check, utilize an
- -- if statement instead of the regular Program_Error circuitry.
-
- Insert_Action (N,
- Make_Implicit_If_Statement (N,
- Condition => Cond,
- Then_Statements => Stmts));
- end if;
- end Apply_Accessibility_Check;
-
-- Local variables
Indic : constant Node_Id := Subtype_Mark (Expression (N));
@@ -881,7 +671,8 @@ package body Exp_Ch4 is
if Is_Build_In_Place_Function_Call (Exp) then
Make_Build_In_Place_Call_In_Allocator (N, Exp);
- Apply_Accessibility_Check (N, Built_In_Place => True);
+ Apply_Accessibility_Check_For_Allocator
+ (N, Exp, N, Built_In_Place => True);
return;
-- Ada 2005 (AI-318-02): Specialization of the previous case for
@@ -893,7 +684,8 @@ package body Exp_Ch4 is
elsif Present (Unqual_BIP_Iface_Function_Call (Exp)) then
Make_Build_In_Place_Iface_Call_In_Allocator (N, Exp);
- Apply_Accessibility_Check (N, Built_In_Place => True);
+ Apply_Accessibility_Check_For_Allocator
+ (N, Exp, N, Built_In_Place => True);
return;
end if;
@@ -1106,6 +898,11 @@ package body Exp_Ch4 is
(Directly_Designated_Type (Etype (N))));
null;
+ -- Likewise if the allocator is made for a special return object
+
+ elsif For_Special_Return_Object (N) then
+ null;
+
elsif Is_Tagged_Type (T) and then not Is_Class_Wide_Type (T) then
TagT := T;
TagR :=
@@ -1154,19 +951,18 @@ package body Exp_Ch4 is
-- Adjust procedure, and the object is built in place. In Ada 95, the
-- object can be limited but not inherently limited if this allocator
-- came from a return statement (we're allocating the result on the
- -- 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)
+ -- secondary stack); in that case, the object will be moved, so we do
+ -- want to Adjust. But the call is always skipped if the allocator is
+ -- made for a special return object because it's generated elsewhere.
+
+ -- Needs_Finalization (DesigT) may 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)
and then not Aggr_In_Place
and then not Is_Limited_View (T)
- and then not Alloc_For_BIP_Return (N)
- and then not Is_Build_In_Place_Function_Call (Expression (N))
+ and then not For_Special_Return_Object (N)
then
-- An unchecked conversion is needed in the classwide case because
-- the designated type can be an ancestor of the subtype mark of
@@ -1188,7 +984,7 @@ package body Exp_Ch4 is
-- Note: the accessibility check must be inserted after the call to
-- [Deep_]Adjust to ensure proper completion of the assignment.
- Apply_Accessibility_Check (Temp);
+ Apply_Accessibility_Check_For_Allocator (N, Exp, Temp);
Rewrite (N, New_Occurrence_Of (Temp, Loc));
Analyze_And_Resolve (N, PtrT);
@@ -1424,33 +1220,52 @@ package body Exp_Ch4 is
Remove_Side_Effects (Op1, Name_Req => True);
Remove_Side_Effects (Op2, Name_Req => True);
- Rewrite (Op1,
- Make_Function_Call (Sloc (Op1),
- Name => New_Occurrence_Of (RTE (Comp), Loc),
+ declare
+ Comp_Call : constant Node_Id :=
+ Make_Function_Call (Loc,
+ Name => New_Occurrence_Of (RTE (Comp), Loc),
- Parameter_Associations => New_List (
- Make_Attribute_Reference (Loc,
- Prefix => Relocate_Node (Op1),
- Attribute_Name => Name_Address),
+ Parameter_Associations => New_List (
+ Make_Attribute_Reference (Loc,
+ Prefix => Relocate_Node (Op1),
+ Attribute_Name => Name_Address),
- Make_Attribute_Reference (Loc,
- Prefix => Relocate_Node (Op2),
- Attribute_Name => Name_Address),
+ Make_Attribute_Reference (Loc,
+ Prefix => Relocate_Node (Op2),
+ Attribute_Name => Name_Address),
- Make_Attribute_Reference (Loc,
- Prefix => Relocate_Node (Op1),
- Attribute_Name => Name_Length),
+ Make_Attribute_Reference (Loc,
+ Prefix => Relocate_Node (Op1),
+ Attribute_Name => Name_Length),
- Make_Attribute_Reference (Loc,
- Prefix => Relocate_Node (Op2),
- Attribute_Name => Name_Length))));
+ Make_Attribute_Reference (Loc,
+ Prefix => Relocate_Node (Op2),
+ Attribute_Name => Name_Length)));
+
+ Zero : constant Node_Id :=
+ Make_Integer_Literal (Loc,
+ Intval => Uint_0);
- Rewrite (Op2,
- Make_Integer_Literal (Sloc (Op2),
- Intval => Uint_0));
+ Comp_Op : Node_Id;
- Analyze_And_Resolve (Op1, Standard_Integer);
- Analyze_And_Resolve (Op2, Standard_Integer);
+ begin
+ case Nkind (N) is
+ when N_Op_Lt =>
+ Comp_Op := Make_Op_Lt (Loc, Comp_Call, Zero);
+ when N_Op_Le =>
+ Comp_Op := Make_Op_Le (Loc, Comp_Call, Zero);
+ when N_Op_Gt =>
+ Comp_Op := Make_Op_Gt (Loc, Comp_Call, Zero);
+ when N_Op_Ge =>
+ Comp_Op := Make_Op_Ge (Loc, Comp_Call, Zero);
+ when others =>
+ raise Program_Error;
+ end case;
+
+ Rewrite (N, Comp_Op);
+ end;
+
+ Analyze_And_Resolve (N, Standard_Boolean);
return;
end if;
end if;
@@ -1702,7 +1517,9 @@ package body Exp_Ch4 is
Prefix => Make_Identifier (Loc, Chars (B)),
Expressions => Index_List2);
- Test := Expand_Composite_Equality (Nod, Component_Type (Typ), L, R);
+ Test := Expand_Composite_Equality
+ (Outer_Type => Typ, Nod => Nod, Comp_Type => Component_Type (Typ),
+ Lhs => L, Rhs => R);
-- If some (sub)component is an unchecked_union, the whole operation
-- will raise program error.
@@ -1934,7 +1751,6 @@ package body Exp_Ch4 is
if Ltyp /= Rtyp then
Ltyp := Base_Type (Ltyp);
Rtyp := Base_Type (Rtyp);
- pragma Assert (Ltyp = Rtyp);
end if;
-- If the array type is distinct from the type of the arguments, it
@@ -1957,6 +1773,7 @@ package body Exp_Ch4 is
New_Rhs := Rhs;
end if;
+ pragma Assert (Ltyp = Rtyp);
First_Idx := First_Index (Ltyp);
-- If optimization is enabled and the array boils down to a couple of
@@ -1964,7 +1781,6 @@ package body Exp_Ch4 is
-- which should be easier to optimize by the code generator.
if Optimization_Level > 0
- and then Ltyp = Rtyp
and then Is_Constrained (Ltyp)
and then Number_Dimensions (Ltyp) = 1
and then Compile_Time_Known_Bounds (Ltyp)
@@ -1991,7 +1807,9 @@ package body Exp_Ch4 is
Prefix => New_Copy_Tree (New_Rhs),
Expressions => New_List (New_Copy_Tree (Low_B)));
- TestL := Expand_Composite_Equality (Nod, Ctyp, L, R);
+ TestL := Expand_Composite_Equality
+ (Outer_Type => Ltyp, Nod => Nod, Comp_Type => Ctyp,
+ Lhs => L, Rhs => R);
L :=
Make_Indexed_Component (Loc,
@@ -2003,7 +1821,9 @@ package body Exp_Ch4 is
Prefix => New_Rhs,
Expressions => New_List (New_Copy_Tree (High_B)));
- TestH := Expand_Composite_Equality (Nod, Ctyp, L, R);
+ TestH := Expand_Composite_Equality
+ (Outer_Type => Ltyp, Nod => Nod, Comp_Type => Ctyp,
+ Lhs => L, Rhs => R);
return
Make_And_Then (Loc, Left_Opnd => TestL, Right_Opnd => TestH);
@@ -2416,20 +2236,21 @@ package body Exp_Ch4 is
-- case because it is not possible to respect normal Ada visibility rules.
function Expand_Composite_Equality
- (Nod : Node_Id;
- Typ : Entity_Id;
- Lhs : Node_Id;
- Rhs : Node_Id) return Node_Id
+ (Outer_Type : Entity_Id;
+ Nod : Node_Id;
+ Comp_Type : Entity_Id;
+ Lhs : Node_Id;
+ Rhs : Node_Id) return Node_Id
is
Loc : constant Source_Ptr := Sloc (Nod);
Full_Type : Entity_Id;
Eq_Op : Entity_Id;
begin
- if Is_Private_Type (Typ) then
- Full_Type := Underlying_Type (Typ);
+ if Is_Private_Type (Comp_Type) then
+ Full_Type := Underlying_Type (Comp_Type);
else
- Full_Type := Typ;
+ Full_Type := Comp_Type;
end if;
-- If the private type has no completion the context may be the
@@ -2454,7 +2275,7 @@ package body Exp_Ch4 is
-- Case of tagged record types
if Is_Tagged_Type (Full_Type) then
- Eq_Op := Find_Primitive_Eq (Typ);
+ Eq_Op := Find_Primitive_Eq (Comp_Type);
pragma Assert (Present (Eq_Op));
return
@@ -2616,18 +2437,20 @@ package body Exp_Ch4 is
-- Equality composes in Ada 2012 for untagged record types. It also
-- composes for bounded strings, because they are part of the
- -- predefined environment. We could make it compose for bounded
- -- strings by making them tagged, or by making sure all subcomponents
- -- are set to the same value, even when not used. Instead, we have
- -- this special case in the compiler, because it's more efficient.
-
- elsif Ada_Version >= Ada_2012 or else Is_Bounded_String (Typ) then
+ -- predefined environment (see 4.5.2(32.1/1)). We could make it
+ -- compose for bounded strings by making them tagged, or by making
+ -- sure all subcomponents are set to the same value, even when not
+ -- used. Instead, we have this special case in the compiler, because
+ -- it's more efficient.
+ elsif Ada_Version >= Ada_2012 or else Is_Bounded_String (Comp_Type)
+ then
-- If no TSS has been created for the type, check whether there is
-- a primitive equality declared for it.
declare
- Op : constant Node_Id := Build_Eq_Call (Typ, Loc, Lhs, Rhs);
+ Op : constant Node_Id :=
+ Build_Eq_Call (Comp_Type, Loc, Lhs, Rhs);
begin
-- Use user-defined primitive if it exists, otherwise use
@@ -2647,6 +2470,33 @@ package body Exp_Ch4 is
-- Case of non-record types (always use predefined equality)
else
+ -- Print a warning if there is a user-defined "=", because it can be
+ -- surprising that the predefined "=" takes precedence over it.
+
+ -- Suppress the warning if the "user-defined" one is in the
+ -- predefined library, because those are defined to compose
+ -- properly by RM-4.5.2(32.1/1). Intrinsics also compose.
+
+ declare
+ Op : constant Entity_Id := Find_Primitive_Eq (Comp_Type);
+ begin
+ if Warn_On_Ignored_Equality
+ and then Present (Op)
+ and then not In_Predefined_Unit (Base_Type (Comp_Type))
+ and then not Is_Intrinsic_Subprogram (Op)
+ then
+ pragma Assert
+ (Is_First_Subtype (Outer_Type)
+ or else Is_Generic_Actual_Type (Outer_Type));
+ Error_Msg_Node_1 := Outer_Type;
+ Error_Msg_Node_2 := Comp_Type;
+ Error_Msg
+ ("?_q?""="" for type & uses predefined ""="" for }", Loc);
+ Error_Msg_Sloc := Sloc (Op);
+ Error_Msg ("\?_q?""="" # is ignored here", Loc);
+ end if;
+ end;
+
return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
end if;
end Expand_Composite_Equality;
@@ -2878,6 +2728,7 @@ package body Exp_Ch4 is
Len : Unat;
J : Nat;
Clen : Node_Id;
+ Decl : Node_Id;
Set : Boolean;
-- Start of processing for Expand_Concatenate
@@ -3404,10 +3255,32 @@ package body Exp_Ch4 is
Set_Is_Internal (Ent);
Set_Debug_Info_Needed (Ent);
+ -- If the bound is statically known to be out of range, we do not want
+ -- to abort, we want a warning and a constraint error at run time. Note
+ -- that we have arranged that the result will not be treated as a static
+ -- constant, so we won't get an illegality during the insertion. We also
+ -- enable all checks (in particular range checks) in case the bounds of
+ -- Subtyp_Ind are out of range.
+
+ Decl :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Ent,
+ Object_Definition => Subtyp_Ind);
+ Insert_Action (Cnode, Decl);
+
+ -- If the result of the concatenation appears as the initializing
+ -- expression of an object declaration, we can just rename the
+ -- result, rather than copying it.
+
+ Set_OK_To_Rename (Ent);
+
-- If we are concatenating strings and the current scope already uses
- -- the secondary stack, allocate the resulting string also on the
- -- secondary stack to avoid putting too much pressure on the primary
- -- stack.
+ -- the secondary stack, allocate the result also on the secondary stack
+ -- to avoid putting too much pressure on the primary stack.
+
+ -- We use an unconstrained allocation, i.e. we also allocate the bounds,
+ -- so that the result can be renamed in all contexts.
+
-- Don't do this if -gnatd.h is set, as this will break the wrapping of
-- Cnode in an Expression_With_Actions, see Expand_N_Op_Concat.
@@ -3417,84 +3290,77 @@ package body Exp_Ch4 is
and then not Debug_Flag_Dot_H
then
-- Generate:
- -- subtype Axx is ...;
- -- type Ayy is access Axx;
- -- Rxx : Ayy := new <subtype> [storage_pool = ss_pool];
- -- Sxx : <subtype> renames Rxx.all;
+ -- subtype Axx is String (<low-bound> .. <high-bound>)
+ -- type Ayy is access String;
+ -- Rxx : Ayy := new <Axx> [storage_pool = ss_pool];
+ -- Sxx : String renames Rxx.all;
declare
- Alloc : Node_Id;
ConstrT : constant Entity_Id := Make_Temporary (Loc, 'A');
Acc_Typ : constant Entity_Id := Make_Temporary (Loc, 'A');
+
+ Alloc : Node_Id;
+ Deref : Node_Id;
Temp : Entity_Id;
begin
- Insert_Action (Cnode,
+ Insert_Action (Decl,
Make_Subtype_Declaration (Loc,
Defining_Identifier => ConstrT,
Subtype_Indication => Subtyp_Ind),
Suppress => All_Checks);
- Freeze_Itype (ConstrT, Cnode);
- Insert_Action (Cnode,
+ Freeze_Itype (ConstrT, Decl);
+
+ Insert_Action (Decl,
Make_Full_Type_Declaration (Loc,
Defining_Identifier => Acc_Typ,
Type_Definition =>
Make_Access_To_Object_Definition (Loc,
- Subtype_Indication => New_Occurrence_Of (ConstrT, Loc))),
+ Subtype_Indication => New_Occurrence_Of (Atyp, Loc))),
Suppress => All_Checks);
+
+ Mutate_Ekind (Acc_Typ, E_Access_Type);
+ Set_Associated_Storage_Pool (Acc_Typ, RTE (RE_SS_Pool));
+
Alloc :=
Make_Allocator (Loc,
Expression => New_Occurrence_Of (ConstrT, Loc));
- -- Allocate on the secondary stack. This is currently done
- -- only for type String, which normally doesn't have default
- -- initialization, but we need to Set_No_Initialization in case
- -- of Initialize_Scalars or Normalize_Scalars; otherwise, the
- -- allocator will get transformed and will not use the secondary
- -- stack.
+ -- This is currently done only for type String, which normally
+ -- doesn't have default initialization, but we need to set the
+ -- No_Initialization flag in case of either Initialize_Scalars
+ -- or Normalize_Scalars.
- Set_Storage_Pool (Alloc, RTE (RE_SS_Pool));
- Set_Procedure_To_Call (Alloc, RTE (RE_SS_Allocate));
Set_No_Initialization (Alloc);
Temp := Make_Temporary (Loc, 'R', Alloc);
- Insert_Action (Cnode,
+ Insert_Action (Decl,
Make_Object_Declaration (Loc,
Defining_Identifier => Temp,
Object_Definition => New_Occurrence_Of (Acc_Typ, Loc),
Expression => Alloc),
Suppress => All_Checks);
- Insert_Action (Cnode,
+ Deref :=
+ Make_Explicit_Dereference (Loc,
+ Prefix => New_Occurrence_Of (Temp, Loc));
+ Set_Etype (Deref, Atyp);
+
+ Rewrite (Decl,
Make_Object_Renaming_Declaration (Loc,
Defining_Identifier => Ent,
- Subtype_Mark => New_Occurrence_Of (ConstrT, Loc),
- Name =>
- Make_Explicit_Dereference (Loc,
- Prefix => New_Occurrence_Of (Temp, Loc))),
- Suppress => All_Checks);
- end;
- else
- -- If the bound is statically known to be out of range, we do not
- -- want to abort, we want a warning and a runtime constraint error.
- -- Note that we have arranged that the result will not be treated as
- -- a static constant, so we won't get an illegality during this
- -- insertion.
- -- We also enable checks (in particular range checks) in case the
- -- bounds of Subtyp_Ind are out of range.
-
- Insert_Action (Cnode,
- Make_Object_Declaration (Loc,
- Defining_Identifier => Ent,
- Object_Definition => Subtyp_Ind));
- end if;
+ Subtype_Mark => New_Occurrence_Of (Atyp, Loc),
+ Name => Deref));
- -- If the result of the concatenation appears as the initializing
- -- expression of an object declaration, we can just rename the
- -- result, rather than copying it.
+ -- We do not analyze this renaming declaration because this would
+ -- change the subtype of Ent back to a constrained string.
- Set_OK_To_Rename (Ent);
+ Set_Etype (Ent, Atyp);
+ Set_Renamed_Object (Ent, Deref);
+ Set_Analyzed (Decl);
+ end;
+ end if;
-- Catch the static out of range case now
@@ -4135,39 +4001,42 @@ package body Exp_Ch4 is
Mod_Minus_Right : constant Uint :=
Modulus (Typ) - Intval (Right_Opnd (N));
- Exprs : constant List_Id := New_List;
- Cond_Expr : constant Node_Id := New_Op_Node (N_Op_Lt, Loc);
- Then_Expr : constant Node_Id := New_Op_Node (N_Op_Add, Loc);
- Else_Expr : constant Node_Id := New_Op_Node (N_Op_Subtract,
- Loc);
+ Cond_Expr : Node_Id;
+ Then_Expr : Node_Id;
+ Else_Expr : Node_Id;
begin
-- To prevent spurious visibility issues, convert all
-- operands to Standard.Unsigned.
- Set_Left_Opnd (Cond_Expr,
- Unchecked_Convert_To (Standard_Unsigned,
- New_Copy_Tree (Left_Opnd (N))));
- Set_Right_Opnd (Cond_Expr,
- Make_Integer_Literal (Loc, Mod_Minus_Right));
- Append_To (Exprs, Cond_Expr);
-
- Set_Left_Opnd (Then_Expr,
- Unchecked_Convert_To (Standard_Unsigned,
- New_Copy_Tree (Left_Opnd (N))));
- Set_Right_Opnd (Then_Expr,
- Make_Integer_Literal (Loc, Intval (Right_Opnd (N))));
- Append_To (Exprs, Then_Expr);
-
- Set_Left_Opnd (Else_Expr,
- Unchecked_Convert_To (Standard_Unsigned,
- New_Copy_Tree (Left_Opnd (N))));
- Set_Right_Opnd (Else_Expr,
- Make_Integer_Literal (Loc, Mod_Minus_Right));
- Append_To (Exprs, Else_Expr);
+ Cond_Expr :=
+ Make_Op_Lt (Loc,
+ Left_Opnd =>
+ Unchecked_Convert_To (Standard_Unsigned,
+ New_Copy_Tree (Left_Opnd (N))),
+ Right_Opnd =>
+ Make_Integer_Literal (Loc, Mod_Minus_Right));
+
+ Then_Expr :=
+ Make_Op_Add (Loc,
+ Left_Opnd =>
+ Unchecked_Convert_To (Standard_Unsigned,
+ New_Copy_Tree (Left_Opnd (N))),
+ Right_Opnd =>
+ Make_Integer_Literal (Loc, Intval (Right_Opnd (N))));
+
+ Else_Expr :=
+ Make_Op_Subtract (Loc,
+ Left_Opnd =>
+ Unchecked_Convert_To (Standard_Unsigned,
+ New_Copy_Tree (Left_Opnd (N))),
+ Right_Opnd =>
+ Make_Integer_Literal (Loc, Mod_Minus_Right));
Rewrite (N,
Unchecked_Convert_To (Typ,
- Make_If_Expression (Loc, Expressions => Exprs)));
+ Make_If_Expression (Loc,
+ Expressions =>
+ New_List (Cond_Expr, Then_Expr, Else_Expr))));
end;
end if;
end Expand_Modular_Addition;
@@ -4183,7 +4052,7 @@ package body Exp_Ch4 is
-- backend does not have to deal with nonbinary-modulus ops.
Op_Expr : constant Node_Id := New_Op_Node (Nkind (N), Loc);
- Mod_Expr : constant Node_Id := New_Op_Node (N_Op_Mod, Loc);
+ Mod_Expr : Node_Id;
Target_Type : Entity_Id;
begin
@@ -4278,10 +4147,10 @@ package body Exp_Ch4 is
Force_Evaluation (Op_Expr, Mode => Strict);
end if;
- Set_Left_Opnd (Mod_Expr, Op_Expr);
-
- Set_Right_Opnd (Mod_Expr,
- Make_Integer_Literal (Loc, Modulus (Typ)));
+ Mod_Expr :=
+ Make_Op_Mod (Loc,
+ Left_Opnd => Op_Expr,
+ Right_Opnd => Make_Integer_Literal (Loc, Modulus (Typ)));
Rewrite (N,
Unchecked_Convert_To (Typ, Mod_Expr));
@@ -4312,37 +4181,40 @@ package body Exp_Ch4 is
Mod_Minus_Right : constant Uint :=
Modulus (Typ) - Intval (Right_Opnd (N));
- Exprs : constant List_Id := New_List;
- Cond_Expr : constant Node_Id := New_Op_Node (N_Op_Lt, Loc);
- Then_Expr : constant Node_Id := New_Op_Node (N_Op_Add, Loc);
- Else_Expr : constant Node_Id := New_Op_Node (N_Op_Subtract,
- Loc);
+ Cond_Expr : Node_Id;
+ Then_Expr : Node_Id;
+ Else_Expr : Node_Id;
begin
- Set_Left_Opnd (Cond_Expr,
- Unchecked_Convert_To (Standard_Unsigned,
- New_Copy_Tree (Left_Opnd (N))));
- Set_Right_Opnd (Cond_Expr,
- Make_Integer_Literal (Loc, Intval (Right_Opnd (N))));
- Append_To (Exprs, Cond_Expr);
-
- Set_Left_Opnd (Then_Expr,
- Unchecked_Convert_To (Standard_Unsigned,
- New_Copy_Tree (Left_Opnd (N))));
- Set_Right_Opnd (Then_Expr,
- Make_Integer_Literal (Loc, Mod_Minus_Right));
- Append_To (Exprs, Then_Expr);
-
- Set_Left_Opnd (Else_Expr,
- Unchecked_Convert_To (Standard_Unsigned,
- New_Copy_Tree (Left_Opnd (N))));
- Set_Right_Opnd (Else_Expr,
- Unchecked_Convert_To (Standard_Unsigned,
- New_Copy_Tree (Right_Opnd (N))));
- Append_To (Exprs, Else_Expr);
+ Cond_Expr :=
+ Make_Op_Lt (Loc,
+ Left_Opnd =>
+ Unchecked_Convert_To (Standard_Unsigned,
+ New_Copy_Tree (Left_Opnd (N))),
+ Right_Opnd =>
+ Make_Integer_Literal (Loc, Intval (Right_Opnd (N))));
+
+ Then_Expr :=
+ Make_Op_Add (Loc,
+ Left_Opnd =>
+ Unchecked_Convert_To (Standard_Unsigned,
+ New_Copy_Tree (Left_Opnd (N))),
+ Right_Opnd =>
+ Make_Integer_Literal (Loc, Mod_Minus_Right));
+
+ Else_Expr :=
+ Make_Op_Subtract (Loc,
+ Left_Opnd =>
+ Unchecked_Convert_To (Standard_Unsigned,
+ New_Copy_Tree (Left_Opnd (N))),
+ Right_Opnd =>
+ Unchecked_Convert_To (Standard_Unsigned,
+ New_Copy_Tree (Right_Opnd (N))));
Rewrite (N,
Unchecked_Convert_To (Typ,
- Make_If_Expression (Loc, Expressions => Exprs)));
+ Make_If_Expression (Loc,
+ Expressions =>
+ New_List (Cond_Expr, Then_Expr, Else_Expr))));
end;
end if;
end Expand_Modular_Subtraction;
@@ -6602,15 +6474,15 @@ package body Exp_Ch4 is
Rop : constant Node_Id := Right_Opnd (N);
Static : constant Boolean := Is_OK_Static_Expression (N);
- procedure Substitute_Valid_Check;
+ procedure Substitute_Valid_Test;
-- Replaces node N by Lop'Valid. This is done when we have an explicit
-- test for the left operand being in range of its subtype.
- ----------------------------
- -- Substitute_Valid_Check --
- ----------------------------
+ ---------------------------
+ -- Substitute_Valid_Test --
+ ---------------------------
- procedure Substitute_Valid_Check is
+ procedure Substitute_Valid_Test is
function Is_OK_Object_Reference (Nod : Node_Id) return Boolean;
-- Determine whether arbitrary node Nod denotes a source object that
-- may safely act as prefix of attribute 'Valid.
@@ -6650,7 +6522,7 @@ package body Exp_Ch4 is
return False;
end Is_OK_Object_Reference;
- -- Start of processing for Substitute_Valid_Check
+ -- Start of processing for Substitute_Valid_Test
begin
Rewrite (N,
@@ -6674,7 +6546,7 @@ package body Exp_Ch4 is
Error_Msg_N -- CODEFIX
("\??use ''Valid attribute instead", N);
end if;
- end Substitute_Valid_Check;
+ end Substitute_Valid_Test;
-- Local variables
@@ -6727,15 +6599,15 @@ package body Exp_Ch4 is
-- eliminates the cases where MINIMIZED/ELIMINATED mode overflow
-- checks have changed the type of the left operand.
- and then Nkind (Rop) in N_Has_Entity
+ and then Is_Entity_Name (Rop)
and then Ltyp = Entity (Rop)
-- Skip this for predicated types, where such expressions are a
-- reasonable way of testing if something meets the predicate.
- and then not Present (Predicate_Function (Ltyp))
+ and then No (Predicate_Function (Ltyp))
then
- Substitute_Valid_Check;
+ Substitute_Valid_Test;
return;
end if;
@@ -6753,26 +6625,42 @@ package body Exp_Ch4 is
Lo : constant Node_Id := Low_Bound (Rop);
Hi : constant Node_Id := High_Bound (Rop);
- Lo_Orig : constant Node_Id := Original_Node (Lo);
- Hi_Orig : constant Node_Id := Original_Node (Hi);
-
- Lcheck : Compare_Result;
- Ucheck : Compare_Result;
+ Lo_Orig : constant Node_Id := Original_Node (Lo);
+ Hi_Orig : constant Node_Id := Original_Node (Hi);
+ Rop_Orig : constant Node_Id := Original_Node (Rop);
+
+ Comes_From_Simple_Range_In_Source : constant Boolean :=
+ Comes_From_Source (N)
+ and then not
+ (Is_Entity_Name (Rop_Orig)
+ and then Is_Type (Entity (Rop_Orig))
+ and then Present (Predicate_Function (Entity (Rop_Orig))));
+ -- This is true for a membership test present in the source with a
+ -- range or mark for a subtype that is not predicated. As already
+ -- explained a few lines above, we do not want to give warnings on
+ -- a test with a mark for a subtype that is predicated.
Warn : constant Boolean :=
Constant_Condition_Warnings
- and then Comes_From_Source (N)
+ and then Comes_From_Simple_Range_In_Source
and then not In_Instance;
-- This must be true for any of the optimization warnings, we
-- clearly want to give them only for source with the flag on. We
-- also skip these warnings in an instance since it may be the
-- case that different instantiations have different ranges.
+ Lcheck : Compare_Result;
+ Ucheck : Compare_Result;
+
begin
- -- If test is explicit x'First .. x'Last, replace by valid check
+ -- If test is explicit x'First .. x'Last, replace by 'Valid test
if Is_Scalar_Type (Ltyp)
+ -- Only relevant for source comparisons
+
+ and then Comes_From_Simple_Range_In_Source
+
-- And left operand is X'First where X matches left operand
-- type (this eliminates cases of type mismatch, including
-- the cases where ELIMINATED/MINIMIZED mode has changed the
@@ -6780,21 +6668,17 @@ package body Exp_Ch4 is
and then Nkind (Lo_Orig) = N_Attribute_Reference
and then Attribute_Name (Lo_Orig) = Name_First
- and then Nkind (Prefix (Lo_Orig)) in N_Has_Entity
+ and then Is_Entity_Name (Prefix (Lo_Orig))
and then Entity (Prefix (Lo_Orig)) = Ltyp
-- Same tests for right operand
and then Nkind (Hi_Orig) = N_Attribute_Reference
and then Attribute_Name (Hi_Orig) = Name_Last
- and then Nkind (Prefix (Hi_Orig)) in N_Has_Entity
+ and then Is_Entity_Name (Prefix (Hi_Orig))
and then Entity (Prefix (Hi_Orig)) = Ltyp
-
- -- Relevant only for source cases
-
- and then Comes_From_Source (N)
then
- Substitute_Valid_Check;
+ Substitute_Valid_Test;
goto Leave;
end if;
@@ -6803,7 +6687,7 @@ package body Exp_Ch4 is
-- for substituting a valid test. We only do this for discrete
-- types, since it won't arise in practice for float types.
- if Comes_From_Source (N)
+ if Comes_From_Simple_Range_In_Source
and then Is_Discrete_Type (Ltyp)
and then Compile_Time_Known_Value (Type_High_Bound (Ltyp))
and then Compile_Time_Known_Value (Type_Low_Bound (Ltyp))
@@ -6816,7 +6700,7 @@ package body Exp_Ch4 is
-- have a test in the generic that makes sense with some types
-- and not with other types.
- -- Similarly, do not rewrite membership as a validity check if
+ -- Similarly, do not rewrite membership as a 'Valid test if
-- within the predicate function for the type.
-- Finally, if the original bounds are type conversions, even
@@ -6836,7 +6720,7 @@ package body Exp_Ch4 is
null;
else
- Substitute_Valid_Check;
+ Substitute_Valid_Test;
goto Leave;
end if;
end if;
@@ -6971,12 +6855,12 @@ package body Exp_Ch4 is
goto Leave;
-- If type is scalar type, rewrite as x in t'First .. t'Last.
- -- This reason we do this is that the bounds may have the wrong
+ -- The reason we do this is that the bounds may have the wrong
-- type if they come from the original type definition. Also this
-- way we get all the processing above for an explicit range.
- -- Don't do this for predicated types, since in this case we
- -- want to check the predicate.
+ -- Don't do this for predicated types, since in this case we want
+ -- to generate the predicate check at the end of the function.
elsif Is_Scalar_Type (Typ) then
if No (Predicate_Function (Typ)) then
@@ -6991,6 +6875,7 @@ package body Exp_Ch4 is
Make_Attribute_Reference (Loc,
Attribute_Name => Name_Last,
Prefix => New_Occurrence_Of (Typ, Loc))));
+
Analyze_And_Resolve (N, Restyp);
end if;
@@ -7148,7 +7033,7 @@ package body Exp_Ch4 is
if Is_Entity_Name (Lop) then
Expr_Entity := Param_Entity (Lop);
- if not Present (Expr_Entity) then
+ if No (Expr_Entity) then
Expr_Entity := Entity (Lop);
end if;
end if;
@@ -7298,6 +7183,24 @@ package body Exp_Ch4 is
and then Current_Scope /= PFunc
and then Nkind (Rop) /= N_Range
then
+ -- First apply the transformation that was skipped above
+
+ if Is_Scalar_Type (Rtyp) then
+ Rewrite (Rop,
+ Make_Range (Loc,
+ Low_Bound =>
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Name_First,
+ Prefix => New_Occurrence_Of (Rtyp, Loc)),
+
+ High_Bound =>
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Name_Last,
+ Prefix => New_Occurrence_Of (Rtyp, Loc))));
+
+ Analyze_And_Resolve (N, Restyp);
+ end if;
+
if not In_Range_Check then
-- Indicate via Static_Mem parameter that this predicate
-- evaluation is for a membership test.
@@ -7317,10 +7220,6 @@ package body Exp_Ch4 is
Set_Analyzed (Left_Opnd (N));
Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
-
- -- All done, skip attempt at compile time determination of result
-
- return;
end if;
end Predicate_Check;
end Expand_N_In;
@@ -9819,7 +9718,7 @@ package body Exp_Ch4 is
-- avoids anomalies when the replacement is done in an instance and
-- is epsilon more efficient.
- Set_Entity (N, Standard_Entity (S_Op_Rem));
+ pragma Assert (Entity (N) = Standard_Op_Rem);
Set_Etype (N, Typ);
Set_Do_Division_Check (N, DDC);
Expand_N_Op_Rem (N);
@@ -13322,15 +13221,16 @@ package body Exp_Ch4 is
end if;
Check :=
- Expand_Composite_Equality (Nod, Etype (C),
- Lhs =>
- Make_Selected_Component (Loc,
- Prefix => New_Lhs,
- Selector_Name => New_Occurrence_Of (C, Loc)),
- Rhs =>
- Make_Selected_Component (Loc,
- Prefix => New_Rhs,
- Selector_Name => New_Occurrence_Of (C, Loc)));
+ Expand_Composite_Equality
+ (Outer_Type => Typ, Nod => Nod, Comp_Type => Etype (C),
+ Lhs =>
+ Make_Selected_Component (Loc,
+ Prefix => New_Lhs,
+ Selector_Name => New_Occurrence_Of (C, Loc)),
+ Rhs =>
+ Make_Selected_Component (Loc,
+ Prefix => New_Rhs,
+ Selector_Name => New_Occurrence_Of (C, Loc)));
-- If some (sub)component is an unchecked_union, the whole
-- operation will raise program error.
diff --git a/gcc/ada/exp_ch4.ads b/gcc/ada/exp_ch4.ads
index eb9b506..7efd105 100644
--- a/gcc/ada/exp_ch4.ads
+++ b/gcc/ada/exp_ch4.ads
@@ -97,7 +97,7 @@ package Exp_Ch4 is
-- individually to yield the required Boolean result. Loc is the
-- location for the generated nodes. Typ is the type of the record, and
-- Lhs, Rhs are the record expressions to be compared, these
- -- expressions need not to be analyzed but have to be side-effect free.
+ -- expressions need not be analyzed but have to be side-effect free.
-- Nod provides the Sloc value for generated code.
procedure Expand_Set_Membership (N : Node_Id);
diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
index d5d66d9..d67f788 100644
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Accessibility; use Accessibility;
with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
@@ -65,6 +66,7 @@ with Tbuild; use Tbuild;
with Ttypes; use Ttypes;
with Uintp; use Uintp;
with Validsw; use Validsw;
+with Warnsw; use Warnsw;
package body Exp_Ch5 is
@@ -3939,7 +3941,9 @@ package body Exp_Ch5 is
-- Start of processing for Expand_N_Case_Statement
begin
- if Extensions_Allowed and then not Is_Discrete_Type (Etype (Expr)) then
+ if Core_Extensions_Allowed
+ and then not Is_Discrete_Type (Etype (Expr))
+ then
Rewrite (N, Expand_General_Case_Statement);
Analyze (N);
return;
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index ce1a752..c026b63 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Accessibility; use Accessibility;
with Atree; use Atree;
with Aspects; use Aspects;
with Checks; use Checks;
@@ -191,16 +192,6 @@ package body Exp_Ch6 is
-- the activation Chain. Note: Master_Actual can be Empty, but only if
-- there are no tasks.
- procedure Apply_CW_Accessibility_Check (Exp : Node_Id; Func : Entity_Id);
- -- Ada 2005 (AI95-344): If the result type is class-wide, insert a check
- -- that the level of the return expression's underlying type is not deeper
- -- than the level of the master enclosing the function. Always generate the
- -- check when the type of the return expression is class-wide, when it's a
- -- type conversion, or when it's a formal parameter. Otherwise suppress the
- -- check in the case where the return expression has a specific type whose
- -- level is known not to be statically deeper than the result type of the
- -- function.
-
function Caller_Known_Size
(Func_Call : Node_Id;
Result_Subt : Entity_Id) return Boolean;
@@ -214,7 +205,8 @@ package body Exp_Ch6 is
(Subp_Call : Node_Id;
Subp_Id : Entity_Id) return Boolean;
-- Given a subprogram call to the given subprogram return True if the
- -- names of BIP extra actual and formal parameters match.
+ -- names of BIP extra actual and formal parameters match, and the number
+ -- of actuals (including extra actuals) matches the number of formals.
function Check_Number_Of_Actuals
(Subp_Call : Node_Id;
@@ -314,15 +306,6 @@ package body Exp_Ch6 is
-- Expand simple return from function. In the case where we are returning
-- from a function body this is called by Expand_N_Simple_Return_Statement.
- function Has_BIP_Extra_Formal
- (E : Entity_Id;
- Kind : BIP_Formal_Kind) return Boolean;
- -- Given a frozen subprogram, subprogram type, entry or entry family,
- -- return True if E has the BIP extra formal associated with Kind. It must
- -- be invoked with a frozen entity or a subprogram type of a dispatching
- -- call since we can only rely on the availability of the extra formals
- -- on these entities.
-
procedure Insert_Post_Call_Actions (N : Node_Id; Post_Call : List_Id);
-- Insert the Post_Call list previously produced by routine Expand_Actuals
-- or Expand_Call_Helper into the tree.
@@ -376,7 +359,7 @@ package body Exp_Ch6 is
-- If no return object is provided, then pass null
- if not Present (Return_Object) then
+ if No (Return_Object) then
Obj_Address := Make_Null (Loc);
Set_Parent (Obj_Address, Function_Call);
@@ -670,7 +653,10 @@ package body Exp_Ch6 is
-- Create the actual which is a pointer to the current activation chain
- if No (Chain) then
+ if Restriction_Active (No_Task_Hierarchy) then
+ Chain_Actual := Make_Null (Loc);
+
+ elsif No (Chain) then
Chain_Actual :=
Make_Attribute_Reference (Loc,
Prefix => Make_Identifier (Loc, Name_uChain),
@@ -1120,6 +1106,23 @@ package body Exp_Ch6 is
| N_Function_Call
| N_Procedure_Call_Statement);
+ -- In CodePeer_Mode, the tree for `'Elab_Spec` procedures will be
+ -- malformed because GNAT does not perform the usual expansion that
+ -- results in the importation of external elaboration procedure symbols.
+ -- This is expected: the CodePeer backend has special handling for this
+ -- malformed tree.
+ -- Thus, we do not need to check the tree (and in fact can't, because
+ -- it's malformed).
+
+ if CodePeer_Mode
+ and then Nkind (Name (Subp_Call)) = N_Attribute_Reference
+ and then Attribute_Name (Name (Subp_Call)) in Name_Elab_Spec
+ | Name_Elab_Body
+ | Name_Elab_Subp_Body
+ then
+ return True;
+ end if;
+
Formal := First_Formal_With_Extras (Subp_Id);
Actual := First_Actual (Subp_Call);
@@ -1627,6 +1630,27 @@ package body Exp_Ch6 is
Crep := False;
end if;
+ -- If the actual denotes a variable which captures the value of an
+ -- object for validation purposes, we propagate the link with this
+ -- object to the new variable made from the actual just above.
+
+ if Ekind (Formal) /= E_In_Parameter
+ and then Is_Validation_Variable_Reference (Actual)
+ then
+ declare
+ Ref : constant Node_Id := Unqual_Conv (Actual);
+
+ begin
+ if Is_Entity_Name (Ref) then
+ Set_Validated_Object (Var, Validated_Object (Entity (Ref)));
+
+ else
+ pragma Assert (False);
+ null;
+ end if;
+ end;
+ end if;
+
-- Setup initialization for case of in out parameter, or an out
-- parameter where the formal is an unconstrained array (in the
-- latter case, we have to pass in an object with bounds).
@@ -1806,7 +1830,7 @@ package body Exp_Ch6 is
Expr := New_Occurrence_Of (Temp, Loc);
end if;
- Rewrite (Actual, New_Occurrence_Of (Temp, Loc));
+ Rewrite (Actual, New_Occurrence_Of (Temp, Sloc (Actual)));
Analyze (Actual);
-- If the actual is a conversion of a packed reference, it may
@@ -1894,6 +1918,13 @@ package body Exp_Ch6 is
Name => Lhs,
Expression => Expr));
end if;
+
+ -- Add a copy-back to reflect any potential changes in value
+ -- back into the original object, if any.
+
+ if Is_Validation_Variable_Reference (Lhs) then
+ Add_Validation_Call_By_Copy_Code (Lhs);
+ end if;
end;
end if;
end Add_Call_By_Copy_Code;
@@ -2040,10 +2071,11 @@ package body Exp_Ch6 is
--------------------------------------
procedure Add_Validation_Call_By_Copy_Code (Act : Node_Id) is
+ Var : constant Node_Id := Unqual_Conv (Act);
+
Expr : Node_Id;
Obj : Node_Id;
Obj_Typ : Entity_Id;
- Var : constant Node_Id := Unqual_Conv (Act);
Var_Id : Entity_Id;
begin
@@ -2393,26 +2425,10 @@ package body Exp_Ch6 is
end if;
end if;
- -- The actual denotes a variable which captures the value of an
- -- object for validation purposes. Add a copy-back to reflect any
- -- potential changes in value back into the original object.
-
- -- Var : ... := Object;
- -- if not Var'Valid then -- validity check
- -- Call (Var); -- modify var
- -- Object := Var; -- update Object
-
- -- This case is given higher priority because the subsequent check
- -- for type conversion may add an extra copy of the variable and
- -- prevent proper value propagation back in the original object.
-
- if Is_Validation_Variable_Reference (Actual) then
- Add_Validation_Call_By_Copy_Code (Actual);
-
-- If argument is a type conversion for a type that is passed by
-- copy, then we must pass the parameter by copy.
- elsif Nkind (Actual) = N_Type_Conversion
+ if Nkind (Actual) = N_Type_Conversion
and then
(Is_Elementary_Type (E_Formal)
or else Is_Bit_Packed_Array (Etype (Formal))
@@ -2496,6 +2512,18 @@ package body Exp_Ch6 is
and then not In_Subrange_Of (E_Actual, E_Formal)))
then
Add_Call_By_Copy_Code;
+
+ -- The actual denotes a variable which captures the value of an
+ -- object for validation purposes. Add a copy-back to reflect any
+ -- potential changes in value back into the original object.
+
+ -- Var : ... := Object;
+ -- if not Var'Valid then -- validity check
+ -- Call (Var); -- modify var
+ -- Object := Var; -- update Object
+
+ elsif Is_Validation_Variable_Reference (Actual) then
+ Add_Validation_Call_By_Copy_Code (Actual);
end if;
-- RM 3.2.4 (23/3): A predicate is checked on in-out and out
@@ -3223,7 +3251,7 @@ package body Exp_Ch6 is
loop
Aspect_Bearer := Nearest_Ancestor (Aspect_Bearer);
- if not Present (Aspect_Bearer) then
+ if No (Aspect_Bearer) then
return False;
end if;
@@ -3313,8 +3341,8 @@ package body Exp_Ch6 is
or else No (Aspect)
-- Do not fold if multiple applicable predicate aspects
- or else Present (Find_Aspect (Subt, Aspect_Static_Predicate))
- or else Present (Find_Aspect (Subt, Aspect_Predicate))
+ or else Has_Aspect (Subt, Aspect_Static_Predicate)
+ or else Has_Aspect (Subt, Aspect_Predicate)
or else Augments_Other_Dynamic_Predicate (Aspect)
or else CodePeer_Mode
then
@@ -3342,9 +3370,53 @@ package body Exp_Ch6 is
------------------------------
procedure Check_Subprogram_Variant is
+
+ function Duplicate_Params_Without_Extra_Actuals
+ (Call_Node : Node_Id) return List_Id;
+ -- Duplicate actual parameters of Call_Node into New_Call without
+ -- extra actuals.
+
+ --------------------------------------------
+ -- Duplicate_Params_Without_Extra_Actuals --
+ --------------------------------------------
+
+ function Duplicate_Params_Without_Extra_Actuals
+ (Call_Node : Node_Id) return List_Id
+ is
+ Proc_Id : constant Entity_Id := Entity (Name (Call_Node));
+ Actuals : constant List_Id := Parameter_Associations (Call_Node);
+ NL : List_Id;
+ Actual : Node_Or_Entity_Id;
+ Formal : Entity_Id;
+
+ begin
+ if Actuals = No_List then
+ return No_List;
+
+ else
+ NL := New_List;
+ Actual := First (Actuals);
+ Formal := First_Formal (Proc_Id);
+
+ while Present (Formal)
+ and then Formal /= Extra_Formals (Proc_Id)
+ loop
+ Append (New_Copy (Actual), NL);
+ Next (Actual);
+
+ Next_Formal (Formal);
+ end loop;
+
+ return NL;
+ end if;
+ end Duplicate_Params_Without_Extra_Actuals;
+
+ -- Local variables
+
Variant_Prag : constant Node_Id :=
Get_Pragma (Current_Scope, Pragma_Subprogram_Variant);
+ New_Call : Node_Id;
Pragma_Arg1 : Node_Id;
Variant_Proc : Entity_Id;
@@ -3373,12 +3445,17 @@ package body Exp_Ch6 is
Variant_Proc := Entity (Pragma_Arg1);
- Insert_Action (Call_Node,
+ New_Call :=
Make_Procedure_Call_Statement (Loc,
Name =>
New_Occurrence_Of (Variant_Proc, Loc),
Parameter_Associations =>
- New_Copy_List (Parameter_Associations (Call_Node))));
+ Duplicate_Params_Without_Extra_Actuals (Call_Node));
+
+ Insert_Action (Call_Node, New_Call);
+
+ pragma Assert (Etype (New_Call) /= Any_Type
+ or else Serious_Errors_Detected > 0);
end if;
end Check_Subprogram_Variant;
@@ -3679,6 +3756,12 @@ package body Exp_Ch6 is
end if;
end if;
+ -- Ensure that the called subprogram has all its formals
+
+ if not Is_Frozen (Subp) then
+ Create_Extra_Formals (Subp);
+ end if;
+
-- Ada 2005 (AI-345): We have a procedure call as a triggering
-- alternative in an asynchronous select or as an entry call in
-- a conditional or timed select. Check whether the procedure call
@@ -3817,7 +3900,7 @@ package body Exp_Ch6 is
and then Thunk_Entity (Current_Scope) = Subp
and then Present (Extra_Formals (Subp))
then
- pragma Assert (Present (Extra_Formals (Current_Scope)));
+ pragma Assert (Extra_Formals_Match_OK (Current_Scope, Subp));
declare
Target_Formal : Entity_Id;
@@ -3839,6 +3922,13 @@ package body Exp_Ch6 is
Add_Actual_Parameter (Remove_Head (Extra_Actuals));
end loop;
+ -- Mark the call as processed build-in-place call; required
+ -- to avoid adding the extra formals twice.
+
+ if Nkind (Call_Node) = N_Function_Call then
+ Set_Is_Expanded_Build_In_Place_Call (Call_Node);
+ end if;
+
Expand_Actuals (Call_Node, Subp, Post_Call);
pragma Assert (Is_Empty_List (Post_Call));
pragma Assert (Check_Number_Of_Actuals (Call_Node, Subp));
@@ -5040,10 +5130,15 @@ package body Exp_Ch6 is
end if;
-- Another optimization: if the returned value is used to initialize an
- -- object, and the secondary stack is not involved in the call, then no
- -- need to copy/readjust/finalize, we can just initialize it in place.
-
- if Nkind (Par) = N_Object_Declaration and then not Use_Sec_Stack then
+ -- object, then no need to copy/readjust/finalize, we can initialize it
+ -- in place. However, if the call returns on the secondary stack or this
+ -- is a special return object, then we need the expansion because we'll
+ -- be renaming the temporary as the (permanent) object.
+
+ if Nkind (Par) = N_Object_Declaration
+ and then not Use_Sec_Stack
+ and then not Is_Special_Return_Object (Defining_Entity (Par))
+ then
return;
end if;
@@ -5200,7 +5295,7 @@ package body Exp_Ch6 is
-- Assert that if F says "return R : T := G(...) do..."
-- then F and G are both b-i-p, or neither b-i-p.
- if Nkind (Exp) = N_Function_Call then
+ if Present (Exp) and then Nkind (Exp) = N_Function_Call then
pragma Assert (Ekind (Current_Subprogram) = E_Function);
pragma Assert
(Is_Build_In_Place_Function (Current_Subprogram) =
@@ -5208,16 +5303,6 @@ package body Exp_Ch6 is
null;
end if;
- -- Ada 2005 (AI95-344): If the result type is class-wide, then insert
- -- a check that the level of the return expression's underlying type
- -- is not deeper than the level of the master enclosing the function.
-
- -- AI12-043: The check is made immediately after the return object
- -- is created.
-
- if Present (Exp) and then Is_Class_Wide_Type (Ret_Typ) then
- Apply_CW_Accessibility_Check (Exp, Func_Id);
- end if;
else
Exp := Empty;
end if;
@@ -6240,7 +6325,7 @@ package body Exp_Ch6 is
-- The object may be a component of some other data structure, in which
-- case this must be handled as an inter-object call.
- if not In_Open_Scopes (Scop)
+ if not Scope_Within_Or_Same (Inner => Current_Scope, Outer => Scop)
or else Is_Entry_Wrapper (Current_Scope)
or else not Is_Entity_Name (Name (N))
then
@@ -6401,8 +6486,13 @@ package body Exp_Ch6 is
if Nkind (Exp) = N_Function_Call then
pragma Assert (Ekind (Scope_Id) = E_Function);
+
+ -- This assertion works fine because Is_Build_In_Place_Function_Call
+ -- returns True for BIP function calls but also for function calls
+ -- that have BIP formals.
+
pragma Assert
- (Is_Build_In_Place_Function (Scope_Id) =
+ (Has_BIP_Formals (Scope_Id) =
Is_Build_In_Place_Function_Call (Exp));
null;
end if;
@@ -6424,23 +6514,10 @@ package body Exp_Ch6 is
-- need to reify the return object, so we can build it "in place", and
-- we need a block statement to hang finalization and tasking stuff.
- -- ??? In order to avoid disruption, we avoid translating to extended
- -- return except in the cases where we really need to (Ada 2005 for
- -- inherently limited). We might prefer to do this translation in all
- -- cases (except perhaps for the case of Ada 95 inherently limited),
- -- in order to fully exercise the Expand_N_Extended_Return_Statement
- -- code. This would also allow us to do the build-in-place optimization
- -- for efficiency even in cases where it is semantically not required.
-
- -- As before, we check the type of the return expression rather than the
- -- return type of the function, because the latter may be a limited
- -- class-wide interface type, which is not a limited type, even though
- -- the type of the expression may be.
-
pragma Assert
(Comes_From_Extended_Return_Statement (N)
or else not Is_Build_In_Place_Function_Call (Exp)
- or else Is_Build_In_Place_Function (Scope_Id));
+ or else Has_BIP_Formals (Scope_Id));
if not Comes_From_Extended_Return_Statement (N)
and then Is_Build_In_Place_Function (Scope_Id)
@@ -6577,22 +6654,25 @@ package body Exp_Ch6 is
-- type Ann is access R_Type;
-- for Ann'Storage_pool use rs_pool;
- -- Rnn : Ann := new Exp_Typ'(Exp);
+ -- Rnn : constant Ann := new Exp_Typ'(Exp);
-- return Rnn.all;
-- but optimize the case where the result is a function call that
-- also needs finalization. In this case the result can directly be
-- allocated on the return stack of the caller and no further
- -- processing is required.
+ -- processing is required. Likewise if this is a return object.
- if Present (Utyp)
+ if Comes_From_Extended_Return_Statement (N) then
+ null;
+
+ elsif Present (Utyp)
and then Needs_Finalization (Utyp)
and then not (Exp_Is_Function_Call
and then Needs_Finalization (Exp_Typ))
then
declare
- Loc : constant Source_Ptr := Sloc (N);
- Acc_Typ : constant Entity_Id := Make_Temporary (Loc, 'A');
+ Acc_Typ : constant Entity_Id := Make_Temporary (Loc, 'A');
+
Alloc_Node : Node_Id;
Temp : Entity_Id;
@@ -6628,6 +6708,7 @@ package body Exp_Ch6 is
Make_Object_Declaration (Loc,
Defining_Identifier => Temp,
+ Constant_Present => True,
Object_Definition => New_Occurrence_Of (Acc_Typ, Loc),
Expression => Alloc_Node)));
@@ -6648,11 +6729,16 @@ package body Exp_Ch6 is
Set_Enclosing_Sec_Stack_Return (N);
+ -- Nothing else to do for a return object
+
+ if Comes_From_Extended_Return_Statement (N) then
+ null;
+
-- 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.
- if Exp_Is_Function_Call
+ elsif Exp_Is_Function_Call
and then Needs_Secondary_Stack (Exp_Typ)
then
-- Remove side effects from the expression now so that other parts
@@ -6677,7 +6763,7 @@ package body Exp_Ch6 is
-- type Ann is access R_Type;
-- for Ann'Storage_pool use ss_pool;
- -- Rnn : Ann := new Exp_Typ'(Exp);
+ -- Rnn : constant Ann := new Exp_Typ'(Exp);
-- return Rnn.all;
-- And we do the same for class-wide types that are not potentially
@@ -6694,14 +6780,13 @@ package body Exp_Ch6 is
and then Needs_Finalization (Exp_Typ))
then
declare
- Loc : constant Source_Ptr := Sloc (N);
- Acc_Typ : constant Entity_Id := Make_Temporary (Loc, 'A');
+ Acc_Typ : constant Entity_Id := Make_Temporary (Loc, 'A');
+
Alloc_Node : Node_Id;
Temp : Entity_Id;
begin
Mutate_Ekind (Acc_Typ, E_Access_Type);
-
Set_Associated_Storage_Pool (Acc_Typ, RTE (RE_SS_Pool));
-- This is an allocator for the secondary stack, and it's fine
@@ -6731,6 +6816,7 @@ package body Exp_Ch6 is
Make_Object_Declaration (Loc,
Defining_Identifier => Temp,
+ Constant_Present => True,
Object_Definition => New_Occurrence_Of (Acc_Typ, Loc),
Expression => Alloc_Node)));
@@ -7044,8 +7130,9 @@ package body Exp_Ch6 is
--------------------------
function Has_BIP_Extra_Formal
- (E : Entity_Id;
- Kind : BIP_Formal_Kind) return Boolean
+ (E : Entity_Id;
+ Kind : BIP_Formal_Kind;
+ Must_Be_Frozen : Boolean := True) return Boolean
is
Extra_Formal : Entity_Id := Extra_Formals (E);
@@ -7055,7 +7142,7 @@ package body Exp_Ch6 is
-- extra formals are added when the target subprogram is frozen; see
-- Expand_Dispatching_Call).
- pragma Assert (Is_Frozen (E)
+ pragma Assert ((Is_Frozen (E) or else not Must_Be_Frozen)
or else (Ekind (E) = E_Subprogram_Type
and then Is_Dispatch_Table_Entity (E))
or else (Is_Dispatching_Operation (E)
@@ -7465,9 +7552,10 @@ package body Exp_Ch6 is
Remove_Side_Effects (A);
- if Is_Controlling_Actual (A)
- and then Etype (F) /= Etype (A)
- then
+ -- Ensure matching types to avoid reporting spurious errors since
+ -- the called helper may have been built for a parent type.
+
+ if Etype (F) /= Etype (A) then
Append_To (Actuals,
Unchecked_Convert_To (Etype (F), New_Copy_Tree (A)));
else
@@ -7684,7 +7772,7 @@ package body Exp_Ch6 is
or else
(Kind = E_Subprogram_Type and then Typ /= Standard_Void_Type))
and then Is_Build_In_Place_Result_Type (Typ)
- and then not (Is_Imported (E) and then Has_Foreign_Convention (E));
+ and then not Has_Foreign_Convention (E);
end Is_Build_In_Place_Function;
-------------------------------------
@@ -7739,12 +7827,29 @@ package body Exp_Ch6 is
raise Program_Error;
end if;
- declare
- Result : constant Boolean := Is_Build_In_Place_Function (Function_Id);
- -- So we can stop here in the debugger
- begin
- return Result;
- end;
+ if Is_Build_In_Place_Function (Function_Id) then
+ return True;
+
+ -- True also if the function has BIP Formals
+
+ else
+ declare
+ Kind : constant Entity_Kind := Ekind (Function_Id);
+
+ begin
+ if (Kind in E_Function | E_Generic_Function
+ or else (Kind = E_Subprogram_Type
+ and then
+ Etype (Function_Id) /= Standard_Void_Type))
+ and then Has_BIP_Formals (Function_Id)
+ then
+ -- So we can stop here in the debugger
+ return True;
+ else
+ return False;
+ end if;
+ end;
+ end if;
end Is_Build_In_Place_Function_Call;
-----------------------------------
@@ -7777,6 +7882,16 @@ package body Exp_Ch6 is
and then Is_Build_In_Place_Function (Return_Applies_To (Scope (E)));
end Is_Build_In_Place_Return_Object;
+ -----------------------------------
+ -- Is_By_Reference_Return_Object --
+ -----------------------------------
+
+ function Is_By_Reference_Return_Object (E : Entity_Id) return Boolean is
+ begin
+ return Is_Return_Object (E)
+ and then Is_By_Reference_Type (Etype (Return_Applies_To (Scope (E))));
+ end Is_By_Reference_Return_Object;
+
-----------------------
-- Is_Null_Procedure --
-----------------------
@@ -7836,6 +7951,28 @@ package body Exp_Ch6 is
end if;
end Is_Null_Procedure;
+ --------------------------------------
+ -- Is_Secondary_Stack_Return_Object --
+ --------------------------------------
+
+ function Is_Secondary_Stack_Return_Object (E : Entity_Id) return Boolean is
+ begin
+ return Is_Return_Object (E)
+ and then Needs_Secondary_Stack (Etype (Return_Applies_To (Scope (E))));
+ end Is_Secondary_Stack_Return_Object;
+
+ ------------------------------
+ -- Is_Special_Return_Object --
+ ------------------------------
+
+ function Is_Special_Return_Object (E : Entity_Id) return Boolean is
+ begin
+ return Is_Build_In_Place_Return_Object (E)
+ or else Is_Secondary_Stack_Return_Object (E)
+ or else (Back_End_Return_Slot
+ and then Is_By_Reference_Return_Object (E));
+ end Is_Special_Return_Object;
+
-------------------------------------------
-- Make_Build_In_Place_Call_In_Allocator --
-------------------------------------------
@@ -8413,6 +8550,11 @@ package body Exp_Ch6 is
-- initialization expression of the object to Empty, which would be
-- illegal Ada, and would cause gigi to misallocate X.
+ Is_OK_Return_Object : constant Boolean :=
+ Is_Return_Object (Obj_Def_Id)
+ and then
+ not Has_Foreign_Convention (Return_Applies_To (Scope (Obj_Def_Id)));
+
-- Start of processing for Make_Build_In_Place_Call_In_Object_Declaration
begin
@@ -8465,7 +8607,7 @@ package body Exp_Ch6 is
-- the result object is in a different (transient) scope, so won't cause
-- freezing.
- if Definite and then not Is_Return_Object (Obj_Def_Id) then
+ if Definite and then not Is_OK_Return_Object then
-- The presence of an address clause complicates the build-in-place
-- expansion because the indicated address must be processed before
@@ -8548,7 +8690,7 @@ package body Exp_Ch6 is
-- really be directly built in place in the aggregate and not in a
-- temporary. ???)
- if Is_Return_Object (Obj_Def_Id) then
+ if Is_OK_Return_Object then
Pass_Caller_Acc := True;
-- When the enclosing function has a BIP_Alloc_Form formal then we
@@ -8733,7 +8875,7 @@ package body Exp_Ch6 is
-- itself the return expression of an enclosing BIP function, then mark
-- the object as having no initialization.
- if Definite and then not Is_Return_Object (Obj_Def_Id) then
+ if Definite and then not Is_OK_Return_Object then
-- The related object declaration is encased in a transient block
-- because the build-in-place function call contains at least one
@@ -9090,7 +9232,7 @@ package body Exp_Ch6 is
and then not No_Run_Time_Mode
and then (Has_Task (Typ)
or else (Is_Class_Wide_Type (Typ)
- and then Is_Limited_Record (Typ)
+ and then Is_Limited_Record (Etype (Typ))
and then not Has_Aspect
(Etype (Typ), Aspect_No_Task_Parts)));
end Might_Have_Tasks;
@@ -9100,7 +9242,6 @@ package body Exp_Ch6 is
----------------------------
function Needs_BIP_Task_Actuals (Func_Id : Entity_Id) return Boolean is
- pragma Assert (Is_Build_In_Place_Function (Func_Id));
Subp_Id : Entity_Id;
Func_Typ : Entity_Id;
@@ -9125,6 +9266,12 @@ package body Exp_Ch6 is
Func_Typ := Underlying_Type (Etype (Subp_Id));
+ -- Functions returning types with foreign convention don't have extra
+ -- formals.
+
+ if Has_Foreign_Convention (Func_Typ) then
+ return False;
+
-- At first sight, for all the following cases, we could add assertions
-- to ensure that if Func_Id is frozen then the computed result matches
-- with the availability of the task master extra formal; unfortunately
@@ -9132,7 +9279,7 @@ package body Exp_Ch6 is
-- (that is, Is_Frozen has been set by Freeze_Entity but it has not
-- completed its work).
- if Has_Task (Func_Typ) then
+ elsif Has_Task (Func_Typ) then
return True;
elsif Ekind (Func_Id) = E_Function then
@@ -9164,8 +9311,6 @@ package body Exp_Ch6 is
Typ : constant Entity_Id := Underlying_Type (Etype (Func_Id));
begin
- pragma Assert (Is_Build_In_Place_Function (Func_Id));
-
-- A formal giving the finalization master is needed for build-in-place
-- functions whose result type needs finalization or is a tagged type.
-- Tagged primitive build-in-place functions need such a formal because
@@ -9177,7 +9322,8 @@ package body Exp_Ch6 is
-- such build-in-place functions, primitive or not.
return not Restriction_Active (No_Finalization)
- and then (Needs_Finalization (Typ) or else Is_Tagged_Type (Typ));
+ and then (Needs_Finalization (Typ) or else Is_Tagged_Type (Typ))
+ and then not Has_Foreign_Convention (Typ);
end Needs_BIP_Finalization_Master;
--------------------------
@@ -9188,8 +9334,6 @@ package body Exp_Ch6 is
Typ : constant Entity_Id := Underlying_Type (Etype (Func_Id));
begin
- pragma Assert (Is_Build_In_Place_Function (Func_Id));
-
-- A formal giving the allocation method is needed for build-in-place
-- functions whose result type is returned on the secondary stack or
-- is a tagged type. Tagged primitive build-in-place functions need
@@ -9201,7 +9345,8 @@ package body Exp_Ch6 is
-- to be passed to all such build-in-place functions, primitive or not.
return not Restriction_Active (No_Secondary_Stack)
- and then (Needs_Secondary_Stack (Typ) or else Is_Tagged_Type (Typ));
+ and then (Needs_Secondary_Stack (Typ) or else Is_Tagged_Type (Typ))
+ and then not Has_Foreign_Convention (Typ);
end Needs_BIP_Alloc_Form;
-------------------------------------
@@ -9496,6 +9641,161 @@ package body Exp_Ch6 is
return Unqual_BIP_Function_Call (Expr);
end Unqual_BIP_Iface_Function_Call;
+ -------------------------------
+ -- Validate_Subprogram_Calls --
+ -------------------------------
+
+ procedure Validate_Subprogram_Calls (N : Node_Id) is
+
+ function Process_Node (Nod : Node_Id) return Traverse_Result;
+ -- Function to traverse the subtree of N using Traverse_Proc.
+
+ ------------------
+ -- Process_Node --
+ ------------------
+
+ function Process_Node (Nod : Node_Id) return Traverse_Result is
+ begin
+ case Nkind (Nod) is
+ when N_Entry_Call_Statement
+ | N_Procedure_Call_Statement
+ | N_Function_Call
+ =>
+ declare
+ Call_Node : Node_Id renames Nod;
+ Subp : Entity_Id;
+
+ begin
+ -- Call using access to subprogram with explicit dereference
+
+ if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
+ Subp := Etype (Name (Call_Node));
+
+ -- Prefix notation calls
+
+ elsif Nkind (Name (Call_Node)) = N_Selected_Component then
+ Subp := Entity (Selector_Name (Name (Call_Node)));
+
+ -- Call to member of entry family, where Name is an indexed
+ -- component, with the prefix being a selected component
+ -- giving the task and entry family name, and the index
+ -- being the entry index.
+
+ elsif Nkind (Name (Call_Node)) = N_Indexed_Component then
+ Subp :=
+ Entity (Selector_Name (Prefix (Name (Call_Node))));
+
+ -- Normal case
+
+ else
+ Subp := Entity (Name (Call_Node));
+ end if;
+
+ pragma Assert (Check_BIP_Actuals (Call_Node, Subp));
+ end;
+
+ -- Skip generic bodies
+
+ when N_Package_Body =>
+ if Ekind (Unique_Defining_Entity (Nod)) = E_Generic_Package then
+ return Skip;
+ end if;
+
+ when N_Subprogram_Body =>
+ if Ekind (Unique_Defining_Entity (Nod)) in E_Generic_Function
+ | E_Generic_Procedure
+ then
+ return Skip;
+ end if;
+
+ -- Nodes we want to ignore
+
+ -- Skip calls placed in the full declaration of record types since
+ -- the call will be performed by their Init Proc; for example,
+ -- calls initializing default values of discriminants or calls
+ -- providing the initial value of record type components. Other
+ -- full type declarations are processed because they may have
+ -- calls that must be checked. For example:
+
+ -- type T is array (1 .. Some_Function_Call (...)) of Some_Type;
+
+ -- ??? More work needed here to handle the following case:
+
+ -- type Rec is record
+ -- F : String (1 .. <some complicated expression>);
+ -- end record;
+
+ when N_Full_Type_Declaration =>
+ if Is_Record_Type (Defining_Entity (Nod)) then
+ return Skip;
+ end if;
+
+ -- Skip calls placed in subprogram specifications since function
+ -- calls initializing default parameter values will be processed
+ -- when the call to the subprogram is found (if the default actual
+ -- parameter is required), and calls found in aspects will be
+ -- processed when their corresponding pragma is found, or in the
+ -- specific case of class-wide pre-/postconditions, when their
+ -- helpers are found.
+
+ when N_Procedure_Specification
+ | N_Function_Specification
+ =>
+ return Skip;
+
+ when N_Abstract_Subprogram_Declaration
+ | N_At_Clause
+ | N_Call_Marker
+ | N_Empty
+ | N_Enumeration_Representation_Clause
+ | N_Enumeration_Type_Definition
+ | N_Function_Instantiation
+ | N_Freeze_Generic_Entity
+ | N_Generic_Function_Renaming_Declaration
+ | N_Generic_Package_Renaming_Declaration
+ | N_Generic_Procedure_Renaming_Declaration
+ | N_Generic_Package_Declaration
+ | N_Generic_Subprogram_Declaration
+ | N_Itype_Reference
+ | N_Number_Declaration
+ | N_Package_Instantiation
+ | N_Package_Renaming_Declaration
+ | N_Pragma
+ | N_Procedure_Instantiation
+ | N_Protected_Type_Declaration
+ | N_Record_Representation_Clause
+ | N_Validate_Unchecked_Conversion
+ | N_Variable_Reference_Marker
+ | N_Use_Package_Clause
+ | N_Use_Type_Clause
+ | N_With_Clause
+ =>
+ return Skip;
+
+ when others =>
+ null;
+ end case;
+
+ return OK;
+ end Process_Node;
+
+ procedure Check_Calls is new Traverse_Proc (Process_Node);
+
+ -- Start of processing for Validate_Subprogram_Calls
+
+ begin
+ -- No action required if we are not generating code or compiling sources
+ -- that have errors.
+
+ if Serious_Errors_Detected > 0
+ or else Operating_Mode /= Generate_Code
+ then
+ return;
+ end if;
+
+ Check_Calls (N);
+ end Validate_Subprogram_Calls;
+
--------------
-- Warn_BIP --
--------------
diff --git a/gcc/ada/exp_ch6.ads b/gcc/ada/exp_ch6.ads
index 19d0bc3..41ddf8d 100644
--- a/gcc/ada/exp_ch6.ads
+++ b/gcc/ada/exp_ch6.ads
@@ -99,6 +99,16 @@ package Exp_Ch6 is
-- Adds Extra_Actual as a named parameter association for the formal
-- Extra_Formal in Subprogram_Call.
+ procedure Apply_CW_Accessibility_Check (Exp : Node_Id; Func : Entity_Id);
+ -- Ada 2005 (AI95-344): If the result type is class-wide, insert a check
+ -- that the level of the return expression's underlying type is not deeper
+ -- than the level of the master enclosing the function. Always generate the
+ -- check when the type of the return expression is class-wide, when it's a
+ -- type conversion, or when it's a formal parameter. Otherwise suppress the
+ -- check in the case where the return expression has a specific type whose
+ -- level is known not to be statically deeper than the result type of the
+ -- function.
+
function BIP_Formal_Suffix (Kind : BIP_Formal_Kind) return String;
-- Ada 2005 (AI-318-02): Returns a string to be used as the suffix of names
-- for build-in-place formal parameters of the given kind.
@@ -121,6 +131,18 @@ package Exp_Ch6 is
-- The returned node is the root of the procedure body which will replace
-- the original function body, which is not needed for the C program.
+ function Has_BIP_Extra_Formal
+ (E : Entity_Id;
+ Kind : BIP_Formal_Kind;
+ Must_Be_Frozen : Boolean := True) return Boolean;
+ -- Given a subprogram, subprogram type, entry or entry family, return True
+ -- if E has the BIP extra formal associated with Kind. In general this
+ -- subprogram must be invoked with a frozen entity or a subprogram type of
+ -- a dispatching call since we can only rely on the availability of extra
+ -- formals on these entities; this requirement can be relaxed using the
+ -- formal Must_Be_Frozen in scenarios where we know that the entity has
+ -- the extra formals.
+
procedure Install_Class_Preconditions_Check (Call_Node : Node_Id);
-- Install check of class-wide preconditions on the caller.
@@ -137,7 +159,8 @@ package Exp_Ch6 is
function Is_Build_In_Place_Function_Call (N : Node_Id) return Boolean;
-- Ada 2005 (AI-318-02): Returns True if N denotes a call to a function
-- that requires handling as a build-in-place call (possibly qualified or
- -- converted).
+ -- converted); that is, BIP function calls, and calls to functions with
+ -- inherited BIP formals.
function Is_Build_In_Place_Result_Type (Typ : Entity_Id) return Boolean;
-- Ada 2005 (AI-318-02): Returns True if functions returning the type use
@@ -145,13 +168,28 @@ package Exp_Ch6 is
-- True in >= Ada 2005 and must be False in Ada 95.
function Is_Build_In_Place_Return_Object (E : Entity_Id) return Boolean;
- -- Ada 2005 (AI-318-02): Return True is E is a return object of a function
+ -- Ada 2005 (AI-318-02): Return True if E is a return object of a function
-- that uses build-in-place protocols.
+ function Is_By_Reference_Return_Object (E : Entity_Id) return Boolean;
+ -- Return True if E is a return object of a function whose return type is
+ -- required to be passed by reference, as defined in (RM 6.2(4-9)).
+
function Is_Null_Procedure (Subp : Entity_Id) return Boolean;
-- Predicate to recognize stubbed procedures and null procedures, which
-- can be inlined unconditionally in all cases.
+ function Is_Secondary_Stack_Return_Object (E : Entity_Id) return Boolean;
+ -- Return True if E is a return object of a function whose return type is
+ -- returned on the secondary stack.
+
+ function Is_Special_Return_Object (E : Entity_Id) return Boolean;
+ -- Return True if E is the return object of a function and is handled in a
+ -- special way by the expander. In most cases, return objects are handled
+ -- like any other variables or constants but, in a few special cases, they
+ -- are further expanded into more elaborate constructs, whose common goal
+ -- is to elide the copy operation associated with the return.
+
procedure Make_Build_In_Place_Call_In_Allocator
(Allocator : Node_Id;
Function_Call : Node_Id);
@@ -265,6 +303,11 @@ package Exp_Ch6 is
-- to reference the secondary dispatch table of an interface; otherwise
-- return Empty.
+ procedure Validate_Subprogram_Calls (N : Node_Id);
+ -- Check that the number of actuals (including extra actuals) of calls in
+ -- the subtree N match their corresponding formals; check also that the
+ -- names of BIP extra actuals and formals match.
+
private
pragma Inline (Is_Build_In_Place_Return_Object);
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index fc4516d..b20d7db 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -4452,7 +4452,7 @@ package body Exp_Ch7 is
begin
if Is_Derived_Type (Typ)
and then Comes_From_Source (E)
- and then not Present (Overridden_Operation (E))
+ and then No (Overridden_Operation (E))
then
-- We know that the explicit operation on the type does not override
-- the inherited operation of the parent, and that the derivation
diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb
index decf617..7d76144 100644
--- a/gcc/ada/exp_ch9.adb
+++ b/gcc/ada/exp_ch9.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Accessibility; use Accessibility;
with Atree; use Atree;
with Aspects; use Aspects;
with Checks; use Checks;
@@ -3207,10 +3208,45 @@ package body Exp_Ch9 is
Find_Enclosing_Context (Par, Context, Context_Id, Decls);
end if;
+ -- When the enclosing context is a BIP function whose result type has
+ -- tasks, the function has an extra formal that is the master of the
+ -- tasks to be created by its returned object (that is, when its
+ -- enclosing context is a return statement). However, if the body of
+ -- the function creates tasks before its return statements, such tasks
+ -- need their own master.
+
+ if Has_Master_Entity (Context_Id)
+ and then Ekind (Context_Id) = E_Function
+ and then Is_Build_In_Place_Function (Context_Id)
+ and then Needs_BIP_Task_Actuals (Context_Id)
+ then
+ -- No need to add it again if previously added
+
+ declare
+ Master_Present : Boolean;
+
+ begin
+ -- Handle transient scopes
+
+ if Context_Id /= Current_Scope then
+ Push_Scope (Context_Id);
+ Master_Present :=
+ Present (Current_Entity_In_Scope (Name_uMaster));
+ Pop_Scope;
+ else
+ Master_Present :=
+ Present (Current_Entity_In_Scope (Name_uMaster));
+ end if;
+
+ if Master_Present then
+ return;
+ end if;
+ end;
+
-- Nothing to do if the context already has a master; internally built
-- finalizers don't need a master.
- if Has_Master_Entity (Context_Id)
+ elsif Has_Master_Entity (Context_Id)
or else Is_Finalizer (Context_Id)
then
return;
diff --git a/gcc/ada/exp_dbug.adb b/gcc/ada/exp_dbug.adb
index 76f08e3..3ab6888 100644
--- a/gcc/ada/exp_dbug.adb
+++ b/gcc/ada/exp_dbug.adb
@@ -415,7 +415,7 @@ package body Exp_Dbug is
| N_Identifier
=>
if No (Entity (Ren))
- or else not Present (Renamed_Entity_Or_Object (Entity (Ren)))
+ or else No (Renamed_Entity_Or_Object (Entity (Ren)))
then
exit;
end if;
diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb
index 3ac4b3b..e0ad27e 100644
--- a/gcc/ada/exp_disp.adb
+++ b/gcc/ada/exp_disp.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Accessibility; use Accessibility;
with Atree; use Atree;
with Checks; use Checks;
with Debug; use Debug;
@@ -1304,17 +1305,24 @@ package body Exp_Disp is
and then Is_Ancestor (Iface_Typ, Opnd, Use_Full_View => True)
then
return;
- end if;
- -- When the type of the operand and the target interface type match,
- -- it is generally safe to skip generating code to displace the
- -- pointer to the object to reference the secondary dispatch table
- -- associated with the target interface type. The exception to this
- -- general rule is when the underlying object of the type conversion
- -- is an object built by means of a dispatching constructor (since in
- -- such case the expansion of the constructor call is a direct call
- -- to an object primitive, i.e. without thunks, and the expansion of
- -- the constructor call adds an explicit conversion to the target
+ -- When the target type is an interface type that is an ancestor of
+ -- the operand type, it is generally safe to skip generating code to
+ -- displace the pointer to the object to reference the secondary
+ -- dispatch table of the target interface type. Two scenarios are
+ -- possible here:
+ -- 1) The operand type is a regular tagged type
+ -- 2) The operand type is an interface type
+ -- In the former case the target interface and the regular tagged
+ -- type share the primary dispatch table of the object; in the latter
+ -- case the operand interface has all the primitives of the ancestor
+ -- interface type (and exactly in the same dispatch table slots).
+ --
+ -- The exception to this general rule is when the underlying object
+ -- is built by means of a dispatching constructor (since in such case
+ -- the expansion of the constructor call is a direct call to an
+ -- object primitive, i.e. without thunks, and the expansion of
+ -- the constructor call adds this explicit conversion to the target
-- interface type to force the displacement of the pointer to the
-- object to reference the corresponding secondary dispatch table
-- (cf. Make_DT and Expand_Dispatching_Constructor_Call)).
@@ -1326,7 +1334,10 @@ package body Exp_Disp is
-- to the object, because generic dispatching constructors are not
-- supported.
- if Opnd = Iface_Typ and then not RTE_Available (RE_Displace) then
+ elsif Is_Interface (Iface_Typ)
+ and then Is_Ancestor (Iface_Typ, Opnd, Use_Full_View => True)
+ and then not RTE_Available (RE_Displace)
+ then
return;
end if;
end;
@@ -4052,8 +4063,7 @@ package body Exp_Disp is
and then not Is_Abstract_Subprogram (Prim)
and then not Is_Eliminated (Prim)
and then not Generate_SCIL
- and then not
- Present (Prim_Table (UI_To_Int (DT_Position (Prim))))
+ and then No (Prim_Table (UI_To_Int (DT_Position (Prim))))
then
if not Build_Thunks then
E := Ultimate_Alias (Prim);
@@ -5269,7 +5279,7 @@ package body Exp_Disp is
E : Entity_Id;
begin
- if not Present (Def)
+ if No (Def)
or else Entity (Name (Def)) /= First_Subtype (Typ)
then
New_Node :=
@@ -5872,8 +5882,7 @@ package body Exp_Disp is
and then not Is_Abstract_Subprogram (Prim)
and then not Is_Eliminated (Prim)
and then not Generate_SCIL
- and then not Present (Prim_Table
- (UI_To_Int (DT_Position (Prim))))
+ and then No (Prim_Table (UI_To_Int (DT_Position (Prim))))
then
E := Ultimate_Alias (Prim);
pragma Assert (not Is_Abstract_Subprogram (E));
@@ -6038,7 +6047,7 @@ package body Exp_Disp is
-- those are only required to build secondary dispatch
-- tables.
- and then not Present (Interface_Alias (Prim))
+ and then No (Interface_Alias (Prim))
-- Skip abstract and eliminated primitives
@@ -7496,7 +7505,7 @@ package body Exp_Disp is
-- Primitive associated with a tagged type
- if not Present (Interface_Alias (Prim)) then
+ if No (Interface_Alias (Prim)) then
Tag_Typ := Scope (DTC_Entity (Prim));
Pos := DT_Position (Prim);
Tag := First_Tag_Component (Tag_Typ);
@@ -8023,7 +8032,7 @@ package body Exp_Disp is
-- same dispatch table slot, but if it renames an operation in a
-- nested package it's a new primitive and will have its own slot.
- elsif not Present (Interface_Alias (Prim))
+ elsif No (Interface_Alias (Prim))
and then Present (Alias (Prim))
and then Chars (Prim) = Chars (Alias (Prim))
and then Nkind (Unit_Declaration_Node (Prim)) /=
@@ -8191,7 +8200,7 @@ package body Exp_Disp is
and then Present (Alias (Prim))
and then not Is_Interface
(Find_Dispatching_Type (Ultimate_Alias (Prim)))
- and then not Present (Interface_Alias (Prim))
+ and then No (Interface_Alias (Prim))
and then Is_Derived_Type (Typ)
and then In_Private_Part (Current_Scope)
and then
diff --git a/gcc/ada/exp_imgv.adb b/gcc/ada/exp_imgv.adb
index 51f1195..398e477 100644
--- a/gcc/ada/exp_imgv.adb
+++ b/gcc/ada/exp_imgv.adb
@@ -938,12 +938,12 @@ package body Exp_Imgv is
-- P3 : constant Natural := call_put_enumN (P1 + 1);
declare
- Add_Node : constant Node_Id := New_Op_Node (N_Op_Add, Loc);
+ Add_Node : constant Node_Id :=
+ Make_Op_Add (Loc,
+ Left_Opnd => New_Occurrence_Of (P1_Id, Loc),
+ Right_Opnd => Make_Integer_Literal (Loc, Uint_1));
begin
- Set_Left_Opnd (Add_Node, New_Occurrence_Of (P1_Id, Loc));
- Set_Right_Opnd (Add_Node, Make_Integer_Literal (Loc, 1));
-
Append_To (Ins_List,
Make_Object_Declaration (Loc,
Defining_Identifier => P3_Id,
@@ -963,12 +963,12 @@ package body Exp_Imgv is
-- P4 : String renames call_put_enumS (P2 .. P3 - 1);
declare
- Sub_Node : constant Node_Id := New_Op_Node (N_Op_Subtract, Loc);
+ Sub_Node : constant Node_Id :=
+ Make_Op_Subtract (Loc,
+ Left_Opnd => New_Occurrence_Of (P3_Id, Loc),
+ Right_Opnd => Make_Integer_Literal (Loc, Uint_1));
begin
- Set_Left_Opnd (Sub_Node, New_Occurrence_Of (P3_Id, Loc));
- Set_Right_Opnd (Sub_Node, Make_Integer_Literal (Loc, 1));
-
Append_To (Ins_List,
Make_Object_Renaming_Declaration (Loc,
Defining_Identifier => P4_Id,
@@ -988,12 +988,12 @@ package body Exp_Imgv is
-- subtype S1 is String (1 .. P3 - P2);
declare
- HB : constant Node_Id := New_Op_Node (N_Op_Subtract, Loc);
+ HB : constant Node_Id :=
+ Make_Op_Subtract (Loc,
+ Left_Opnd => New_Occurrence_Of (P3_Id, Loc),
+ Right_Opnd => New_Occurrence_Of (P2_Id, Loc));
begin
- Set_Left_Opnd (HB, New_Occurrence_Of (P3_Id, Loc));
- Set_Right_Opnd (HB, New_Occurrence_Of (P2_Id, Loc));
-
Append_To (Ins_List,
Make_Subtype_Declaration (Loc,
Defining_Identifier => S1_Id,
@@ -1842,6 +1842,15 @@ package body Exp_Imgv is
return;
end if;
+ -- If Image should be transformed using Put_Image, then do so. See
+ -- Exp_Put_Image for details.
+
+ if Exp_Put_Image.Image_Should_Call_Put_Image (N) then
+ Rewrite (N, Exp_Put_Image.Build_Image_Call (N));
+ Analyze_And_Resolve (N, Standard_Wide_String, Suppress => All_Checks);
+ return;
+ end if;
+
Rtyp := Root_Type (Entity (Pref));
Insert_Actions (N, New_List (
@@ -1942,6 +1951,16 @@ package body Exp_Imgv is
return;
end if;
+ -- If Image should be transformed using Put_Image, then do so. See
+ -- Exp_Put_Image for details.
+
+ if Exp_Put_Image.Image_Should_Call_Put_Image (N) then
+ Rewrite (N, Exp_Put_Image.Build_Image_Call (N));
+ Analyze_And_Resolve
+ (N, Standard_Wide_Wide_String, Suppress => All_Checks);
+ return;
+ end if;
+
Rtyp := Root_Type (Entity (Pref));
Insert_Actions (N, New_List (
diff --git a/gcc/ada/exp_intr.adb b/gcc/ada/exp_intr.adb
index bd987f0..d18ed69 100644
--- a/gcc/ada/exp_intr.adb
+++ b/gcc/ada/exp_intr.adb
@@ -24,13 +24,16 @@
------------------------------------------------------------------------------
with Atree; use Atree;
+with Aspects; use Aspects;
with Checks; use Checks;
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 Expander; use Expander;
with Exp_Atag; use Exp_Atag;
+with Exp_Ch6; use Exp_Ch6;
with Exp_Ch7; use Exp_Ch7;
with Exp_Ch11; use Exp_Ch11;
with Exp_Code; use Exp_Code;
@@ -277,6 +280,50 @@ package body Exp_Intr is
Result_Typ : Entity_Id;
begin
+ pragma Assert (Is_Class_Wide_Type (Etype (Entity (Name (N)))));
+
+ -- Report case where we know that the generated code is wrong; that
+ -- is a dispatching constructor call whose controlling type has tasks
+ -- but its root type does not have tasks. In such case the constructor
+ -- subprogram of the root type does not have extra formals but the
+ -- constructor of the derivation must have extra formals.
+
+ if not Global_No_Tasking
+ and then not No_Run_Time_Mode
+ and then Is_Build_In_Place_Function (Entity (Name (N)))
+ and then not Has_Task (Root_Type (Etype (Entity (Name (N)))))
+ and then not Has_Aspect (Root_Type (Etype (Entity (Name (N)))),
+ Aspect_No_Task_Parts)
+ then
+ -- Case 1: Explicit tag reference (which allows static check)
+
+ if Nkind (Tag_Arg) = N_Identifier
+ and then Present (Entity (Tag_Arg))
+ and then Is_Tag (Entity (Tag_Arg))
+ then
+ if Has_Task (Related_Type (Entity (Tag_Arg))) then
+ Error_Msg_N ("unsupported dispatching constructor call", N);
+ Error_Msg_NE
+ ("\work around this problem by defining task component "
+ & "type& using access-to-task-type",
+ N, Related_Type (Entity (Tag_Arg)));
+ end if;
+
+ -- Case 2: Dynamic tag which may fail at run time
+
+ else
+ Error_Msg_N
+ ("unsupported dispatching constructor call if the type "
+ & "of the built object has task components??", N);
+
+ Error_Msg_Sloc := Sloc (Root_Type (Etype (Entity (Name (N)))));
+ Error_Msg_NE
+ ("\work around this by adding ''with no_task_parts'' to "
+ & "the declaration of the root type& defined#???",
+ N, Root_Type (Etype (Entity (Name (N)))));
+ end if;
+ end if;
+
-- Remove side effects from tag argument early, before rewriting
-- the dispatching constructor call, as Remove_Side_Effects relies
-- on Tag_Arg's Parent link properly attached to the tree (once the
diff --git a/gcc/ada/exp_pakd.adb b/gcc/ada/exp_pakd.adb
index d4a62ac..29735c0 100644
--- a/gcc/ada/exp_pakd.adb
+++ b/gcc/ada/exp_pakd.adb
@@ -671,11 +671,11 @@ package body Exp_Pakd is
return;
end if;
- -- If our immediate ancestor subtype is constrained, and it already
- -- has a packed array type, then just share the same type, since the
- -- bounds must be the same. If the ancestor is not an array type but
- -- a private type, as can happen with multiple instantiations, create
- -- a new packed type, to avoid privacy issues.
+ -- If our immediate ancestor subtype is constrained, and it already has
+ -- a packed array type, and it has the same size, then just share the
+ -- same type, since the bounds must be the same. If the ancestor is not
+ -- an array type but a private type, as can happen with multiple
+ -- instantiations, create a new packed type, to avoid privacy issues.
if Ekind (Typ) = E_Array_Subtype then
Ancest := Ancestor_Subtype (Typ);
@@ -684,6 +684,9 @@ package body Exp_Pakd is
and then Is_Array_Type (Ancest)
and then Is_Constrained (Ancest)
and then Present (Packed_Array_Impl_Type (Ancest))
+ and then Known_Esize (Typ)
+ and then Known_Esize (Ancest)
+ and then Esize (Typ) = Esize (Ancest)
then
Set_Packed_Array_Impl_Type (Typ, Packed_Array_Impl_Type (Ancest));
return;
diff --git a/gcc/ada/exp_prag.adb b/gcc/ada/exp_prag.adb
index 2def83c..cce0aa5 100644
--- a/gcc/ada/exp_prag.adb
+++ b/gcc/ada/exp_prag.adb
@@ -58,6 +58,7 @@ with Stand; use Stand;
with Tbuild; use Tbuild;
with Uintp; use Uintp;
with Validsw; use Validsw;
+with Warnsw; use Warnsw;
package body Exp_Prag is
diff --git a/gcc/ada/exp_put_image.adb b/gcc/ada/exp_put_image.adb
index 50e0569..eaedebe 100644
--- a/gcc/ada/exp_put_image.adb
+++ b/gcc/ada/exp_put_image.adb
@@ -1039,13 +1039,13 @@ package body Exp_Put_Image is
end if;
-- In Ada 2022, T'Image calls T'Put_Image if there is an explicit
- -- aspect_specification for Put_Image, or if U_Type'Image is illegal
- -- in pre-2022 versions of Ada.
+ -- (or inherited) aspect_specification for Put_Image, or if
+ -- U_Type'Image is illegal in pre-2022 versions of Ada.
declare
U_Type : constant Entity_Id := Underlying_Type (Entity (Prefix (N)));
begin
- if Present (TSS (U_Type, TSS_Put_Image)) then
+ if Has_Aspect (U_Type, Aspect_Put_Image) then
return True;
end if;
@@ -1058,12 +1058,14 @@ package body Exp_Put_Image is
----------------------
function Build_Image_Call (N : Node_Id) return Node_Id is
- -- For T'Image (X) Generate an Expression_With_Actions node:
+ -- For T'[[Wide_]Wide_]Image (X) Generate an Expression_With_Actions
+ -- node:
--
-- do
-- S : Buffer;
-- U_Type'Put_Image (S, X);
- -- Result : constant String := Get (S);
+ -- Result : constant [[Wide_]Wide_]String :=
+ -- [[Wide_[Wide_]]Get (S);
-- Destroy (S);
-- in Result end
--
@@ -1091,14 +1093,33 @@ package body Exp_Put_Image is
Image_Prefix));
Result_Entity : constant Entity_Id :=
Make_Temporary (Loc, 'R');
+
+ subtype Image_Name_Id is Name_Id with Static_Predicate =>
+ Image_Name_Id in Name_Image | Name_Wide_Image | Name_Wide_Wide_Image;
+ -- Attribute names that will be mapped to the corresponding result types
+ -- and functions.
+
+ Attribute_Name_Id : constant Name_Id := Attribute_Name (N);
+
+ Result_Typ : constant Entity_Id :=
+ (case Image_Name_Id'(Attribute_Name_Id) is
+ when Name_Image => Stand.Standard_String,
+ when Name_Wide_Image => Stand.Standard_Wide_String,
+ when Name_Wide_Wide_Image => Stand.Standard_Wide_Wide_String);
+ Get_Func_Id : constant RE_Id :=
+ (case Image_Name_Id'(Attribute_Name_Id) is
+ when Name_Image => RE_Get,
+ when Name_Wide_Image => RE_Wide_Get,
+ when Name_Wide_Wide_Image => RE_Wide_Wide_Get);
+
Result_Decl : constant Node_Id :=
Make_Object_Declaration (Loc,
Defining_Identifier => Result_Entity,
Object_Definition =>
- New_Occurrence_Of (Stand.Standard_String, Loc),
+ New_Occurrence_Of (Result_Typ, Loc),
Expression =>
Make_Function_Call (Loc,
- Name => New_Occurrence_Of (RTE (RE_Get), Loc),
+ Name => New_Occurrence_Of (RTE (Get_Func_Id), Loc),
Parameter_Associations => New_List (
New_Occurrence_Of (Sink_Entity, Loc))));
Actions : List_Id;
diff --git a/gcc/ada/exp_put_image.ads b/gcc/ada/exp_put_image.ads
index b2b65aa..d4055d1 100644
--- a/gcc/ada/exp_put_image.ads
+++ b/gcc/ada/exp_put_image.ads
@@ -91,9 +91,9 @@ package Exp_Put_Image is
-- T'Image.
function Build_Image_Call (N : Node_Id) return Node_Id;
- -- N is a call to T'Image, and this translates it into the appropriate code
- -- to call T'Put_Image into a buffer and then extract the string from the
- -- buffer.
+ -- N is a call to T'[[Wide_]Wide_]Image, and this translates it into the
+ -- appropriate code to call T'Put_Image into a buffer and then extract the
+ -- [[wide] wide] string from the buffer.
procedure Preload_Root_Buffer_Type (Compilation_Unit : Node_Id);
-- Call RTE (RE_Root_Buffer_Type) if necessary, to load the packages
diff --git a/gcc/ada/exp_spark.adb b/gcc/ada/exp_spark.adb
index c89d604..ba7bd7fe 100644
--- a/gcc/ada/exp_spark.adb
+++ b/gcc/ada/exp_spark.adb
@@ -895,7 +895,7 @@ package body Exp_SPARK is
procedure SPARK_Freeze_Type (N : Entity_Id) is
Typ : constant Entity_Id := Entity (N);
- Renamed_Eq : Node_Id;
+ Renamed_Eq : Entity_Id;
-- Defining unit name for the predefined equality function in the case
-- where the type has a primitive operation that is a renaming of
-- predefined equality (but only if there is also an overriding
diff --git a/gcc/ada/exp_unst.adb b/gcc/ada/exp_unst.adb
index 9164644..fd4c543 100644
--- a/gcc/ada/exp_unst.adb
+++ b/gcc/ada/exp_unst.adb
@@ -2225,7 +2225,7 @@ package body Exp_Unst is
if No (UPJ.Ref)
or else not Is_Entity_Name (UPJ.Ref)
- or else not Present (Entity (UPJ.Ref))
+ or else No (Entity (UPJ.Ref))
or else not Opt.Generate_C_Code
then
goto Continue;
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index f569d2e..84b0c0e 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -67,6 +67,7 @@ with Stringt; use Stringt;
with Tbuild; use Tbuild;
with Ttypes; use Ttypes;
with Validsw; use Validsw;
+with Warnsw; use Warnsw;
with GNAT.HTable;
package body Exp_Util is
@@ -1700,7 +1701,7 @@ package body Exp_Util is
-- type attributes.
begin
- if not Present (Priv_Typ) and then not Present (Full_Typ) then
+ if No (Priv_Typ) and then No (Full_Typ) then
return;
end if;
@@ -1787,7 +1788,7 @@ package body Exp_Util is
-- full type doesn't have its own DIC, but is inherited from
-- a type with DIC), get the full DIC procedure.
- if not Present (Par_Proc) then
+ if No (Par_Proc) then
Par_Proc := DIC_Procedure (Par_Typ);
end if;
@@ -2745,7 +2746,7 @@ package body Exp_Util is
-- type attributes.
begin
- if not Present (Priv_Typ) and then not Present (Full_Typ) then
+ if No (Priv_Typ) and then No (Full_Typ) then
return;
end if;
@@ -2966,7 +2967,7 @@ package body Exp_Util is
-- Output an info message when inheriting an invariant and the
-- listing option is enabled.
- if Inherited and Opt.List_Inherited_Aspects then
+ if Inherited and List_Inherited_Aspects then
Error_Msg_Sloc := Sloc (Prag);
Error_Msg_N
("info: & inherits `Invariant''Class` aspect from #?.l?", Typ);
@@ -3072,7 +3073,7 @@ package body Exp_Util is
Prag_Typ_Arg : Node_Id;
begin
- if not Present (T) then
+ if No (T) then
return;
end if;
@@ -9165,7 +9166,11 @@ package body Exp_Util is
return
Present (Expr)
and then Nkind (Unqual_Conv (Expr)) = N_Explicit_Dereference
- and then Nkind (Parent (Expr)) = N_Simple_Return_Statement;
+ and then (Nkind (Parent (Expr)) = N_Simple_Return_Statement
+ or else
+ (Nkind (Parent (Expr)) = N_Object_Renaming_Declaration
+ and then
+ Is_Return_Object (Defining_Entity (Parent (Expr)))));
end Is_Related_To_Func_Return;
--------------------------------
@@ -11367,7 +11372,7 @@ package body Exp_Util is
-- Create a label for the block in case the block needs to manage the
-- secondary stack. A label allows for flag Uses_Sec_Stack to be set.
- Add_Block_Identifier (Block_Nod, Block_Id);
+ Add_Block_Identifier (Block_Nod, Block_Id, Scop);
-- When wrapping the statements of an iterator loop, check whether
-- the loop requires secondary stack management and if so, propagate
diff --git a/gcc/ada/fe.h b/gcc/ada/fe.h
index 79a1b58..12ad15b 100644
--- a/gcc/ada/fe.h
+++ b/gcc/ada/fe.h
@@ -366,9 +366,9 @@ extern Boolean Stack_Check_Probes_On_Target;
/* warnsw: */
-#define Warn_On_Questionable_Layout warnsw__warn_on_questionable_layout
+#define Get_Warn_On_Questionable_Layout warnsw__get_warn_on_questionable_layout
-extern Boolean Warn_On_Questionable_Layout;
+extern Boolean Get_Warn_On_Questionable_Layout (void);
// The following corresponds to Ada code in Einfo.Utils.
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 346904e..7f78b43 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -1718,11 +1718,16 @@ package body Freeze is
end;
end if;
- New_Prag := New_Copy_Tree (A_Post);
- Rewrite
- (Expression (First (Pragma_Argument_Associations (New_Prag))),
- Class_Post);
- Append (New_Prag, Decls);
+ -- A_Post can be null here if the postcondition was inlined in the
+ -- called subprogram.
+
+ if Present (A_Post) then
+ New_Prag := New_Copy_Tree (A_Post);
+ Rewrite
+ (Expression (First (Pragma_Argument_Associations (New_Prag))),
+ Class_Post);
+ Append (New_Prag, Decls);
+ end if;
end if;
end Build_Inherited_Condition_Pragmas;
@@ -3183,6 +3188,9 @@ package body Freeze is
if Has_Task (Typ) then
Error_Msg_N
("aspect % applied to task type &", Typ);
+ Error_Msg_N
+ ("\replace task components with access-to-task-type "
+ & "components??", Typ);
end if;
else
@@ -3793,7 +3801,7 @@ package body Freeze is
-- Set component size if not already set by a component
-- size clause.
- if not Present (Comp_Size_C) then
+ if No (Comp_Size_C) then
Set_Component_Size (Arr, Csiz);
end if;
@@ -3805,7 +3813,7 @@ package body Freeze is
-- explicitly, then generate a warning.
if Has_Pragma_Pack (Arr)
- and then not Present (Comp_Size_C)
+ and then No (Comp_Size_C)
and then (Csiz = 7 or else Csiz = 15 or else Csiz = 31)
and then Known_Esize (Base_Type (Ctyp))
and then Esize (Base_Type (Ctyp)) = Csiz + 1
@@ -4979,6 +4987,7 @@ package body Freeze is
and then Convention (Desig) /= Convention_Protected
then
Set_Is_Frozen (Desig);
+ Create_Extra_Formals (Desig);
end if;
end Check_Itype;
@@ -7059,7 +7068,7 @@ package body Freeze is
-- end of a declarative part.
if Is_Library_Level_Tagged_Type (E)
- and then not Present (Full_View (E))
+ and then No (Full_View (E))
then
Set_Is_Frozen (E, False);
goto Leave;
@@ -7126,11 +7135,11 @@ package body Freeze is
Check_Debug_Info_Needed (E);
- -- AI-117 requires that the convention of a partial view be the
- -- same as the convention of the full view. Note that this is a
- -- recognized breach of privacy, but it's essential for logical
- -- consistency of representation, and the lack of a rule in
- -- RM95 was an oversight.
+ -- AI95-117 requires that the convention of a partial view be
+ -- the same as the convention of the full view. Note that this
+ -- is a recognized breach of privacy, but it's essential for
+ -- logical consistency of representation, and the lack of a
+ -- rule in RM95 was an oversight.
Set_Convention (E, Convention (Full_View (E)));
@@ -7355,7 +7364,7 @@ package body Freeze is
if Is_Composite_Type (E) then
- -- AI-117 requires that all new primitives of a tagged type must
+ -- AI95-117 requires that all new primitives of a tagged type must
-- inherit the convention of the full view of the type. Inherited
-- and overriding operations are defined to inherit the convention
-- of their parent or overridden subprogram (also specified in
@@ -7467,7 +7476,7 @@ package body Freeze is
-- If no formal is passed in, then issue an error for a
-- missing formal.
- elsif not Present (Pool_Op_Formal) then
+ elsif No (Pool_Op_Formal) then
Error_Msg_NE
("simple storage pool op missing formal " &
Formal_Name & " of type&", Pool_Op, Expected_Type);
@@ -7599,7 +7608,7 @@ package body Freeze is
-- and no excess formals are present, then this
-- operation has been validated, so record it.
- if not Present (Formal) and then Is_OK then
+ if No (Formal) and then Is_OK then
Found_Op := Op;
end if;
end if;
@@ -7611,7 +7620,7 @@ package body Freeze is
-- so issue an error if none was found.
if Op_Name = Name_Allocate
- and then not Present (Found_Op)
+ and then No (Found_Op)
then
Error_Msg_N ("missing % operation for simple " &
"storage pool type", Pool_Type);
@@ -8263,7 +8272,7 @@ package body Freeze is
if Present (Nam)
and then Ekind (Nam) = E_Function
and then Nkind (Parent (N)) = N_Function_Call
- and then Convention (Nam) = Convention_Ada
+ and then not Has_Foreign_Convention (Nam)
then
Create_Extra_Formals (Nam);
end if;
@@ -9870,77 +9879,11 @@ package body Freeze is
-----------------------
procedure Freeze_Subprogram (E : Entity_Id) is
- function Check_Extra_Formals (E : Entity_Id) return Boolean;
- -- Return True if the decoration of the attributes associated with extra
- -- formals are properly set.
procedure Set_Profile_Convention (Subp_Id : Entity_Id);
-- Set the conventions of all anonymous access-to-subprogram formals and
-- result subtype of subprogram Subp_Id to the convention of Subp_Id.
- -------------------------
- -- Check_Extra_Formals --
- -------------------------
-
- function Check_Extra_Formals (E : Entity_Id) return Boolean is
- Last_Formal : Entity_Id := Empty;
- Formal : Entity_Id;
- Has_Extra_Formals : Boolean := False;
-
- begin
- -- No check required if expansion is disabled because extra
- -- formals are only generated when we are generating code.
- -- See Create_Extra_Formals.
-
- if not Expander_Active then
- return True;
- end if;
-
- -- Check attribute Extra_Formal: If available, it must be set only
- -- on the last formal of E.
-
- Formal := First_Formal (E);
- while Present (Formal) loop
- if Present (Extra_Formal (Formal)) then
- if Has_Extra_Formals then
- return False;
- end if;
-
- Has_Extra_Formals := True;
- end if;
-
- Last_Formal := Formal;
- Next_Formal (Formal);
- end loop;
-
- -- Check attribute Extra_Accessibility_Of_Result
-
- if Ekind (E) in E_Function | E_Subprogram_Type
- and then Needs_Result_Accessibility_Level (E)
- and then No (Extra_Accessibility_Of_Result (E))
- then
- return False;
- end if;
-
- -- Check attribute Extra_Formals: If E has extra formals, then this
- -- attribute must point to the first extra formal of E.
-
- if Has_Extra_Formals then
- return Present (Extra_Formals (E))
- and then Present (Extra_Formal (Last_Formal))
- and then Extra_Formal (Last_Formal) = Extra_Formals (E);
-
- -- When E has no formals, the first extra formal is available through
- -- the Extra_Formals attribute.
-
- elsif Present (Extra_Formals (E)) then
- return No (First_Formal (E));
-
- else
- return True;
- end if;
- end Check_Extra_Formals;
-
----------------------------
-- Set_Profile_Convention --
----------------------------
@@ -10079,30 +10022,26 @@ package body Freeze is
-- that we know the convention.
if not Has_Foreign_Convention (E) then
- if No (Extra_Formals (E)) then
- -- Extra formals are shared by derived subprograms; therefore, if
- -- the ultimate alias of E has been frozen before E then the extra
- -- formals have been added, but the attribute Extra_Formals is
- -- still unset (and must be set now).
+ -- Extra formals of dispatching operations are added later by
+ -- Expand_Freeze_Record_Type, which also adds extra formals to
+ -- internal entities built to handle interface types.
- if Present (Alias (E))
- and then Is_Frozen (Ultimate_Alias (E))
- and then Present (Extra_Formals (Ultimate_Alias (E)))
- and then Last_Formal (Ultimate_Alias (E)) = Last_Formal (E)
- then
- Set_Extra_Formals (E, Extra_Formals (Ultimate_Alias (E)));
+ if not Is_Dispatching_Operation (E) then
+ Create_Extra_Formals (E);
- if Ekind (E) = E_Function then
- Set_Extra_Accessibility_Of_Result (E,
- Extra_Accessibility_Of_Result (Ultimate_Alias (E)));
- end if;
- else
- Create_Extra_Formals (E);
- end if;
+ pragma Assert
+ ((Ekind (E) = E_Subprogram_Type
+ and then Extra_Formals_OK (E))
+ or else
+ (Is_Subprogram (E)
+ and then Extra_Formals_OK (E)
+ and then
+ (No (Overridden_Operation (E))
+ or else Extra_Formals_Match_OK (E,
+ Ultimate_Alias (Overridden_Operation (E))))));
end if;
- pragma Assert (Check_Extra_Formals (E));
Set_Mechanisms (E);
-- If this is convention Ada and a Valued_Procedure, that's odd
diff --git a/gcc/ada/frontend.adb b/gcc/ada/frontend.adb
index 12c91b1..033ecf3 100644
--- a/gcc/ada/frontend.adb
+++ b/gcc/ada/frontend.adb
@@ -30,6 +30,7 @@ with Checks;
with CStand;
with Debug; use Debug;
with Elists;
+with Exp_Ch6;
with Exp_Dbug;
with Exp_Unst;
with Fmap;
@@ -68,6 +69,7 @@ with SCIL_LL;
with Tbuild; use Tbuild;
with Types; use Types;
with VAST;
+with Warnsw; use Warnsw;
procedure Frontend is
begin
@@ -523,6 +525,16 @@ begin
VAST.Check_Tree (Cunit (Main_Unit));
end if;
+ -- Validate all the subprogram calls; this work will be done by VAST; in
+ -- the meantime it is done to check extra formals and it can be disabled
+ -- using -gnatd_X (which also disables all the other assertions on extra
+ -- formals). It is invoked using pragma Debug to avoid adding any cost
+ -- when the compiler is built with assertions disabled.
+
+ if not Debug_Flag_Underscore_XX then
+ pragma Debug (Exp_Ch6.Validate_Subprogram_Calls (Cunit (Main_Unit)));
+ end if;
+
-- Dump the source now. Note that we do this as soon as the analysis
-- of the tree is complete, because it is not just a dump in the case
-- of -gnatD, where it rewrites all source locations in the tree.
diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in
index 02b2d1c..2acd195 100644
--- a/gcc/ada/gcc-interface/Make-lang.in
+++ b/gcc/ada/gcc-interface/Make-lang.in
@@ -399,6 +399,7 @@ GNAT_ADA_OBJS = \
ada/sem_ch12.o \
ada/sem_ch13.o \
ada/sem_ch2.o \
+ ada/accessibility.o \
ada/sem_ch3.o \
ada/sem_ch4.o \
ada/sem_ch5.o \
@@ -601,7 +602,6 @@ GNATBIND_OBJS = \
ada/osint-b.o \
ada/osint.o \
ada/output.o \
- ada/restrict.o \
ada/rident.o \
ada/scans.o \
ada/scil_ll.o \
@@ -629,6 +629,7 @@ GNATBIND_OBJS = \
ada/uintp.o \
ada/uname.o \
ada/urealp.o \
+ ada/warnsw.o \
ada/widechar.o \
ada/gnat.o \
ada/g-dynhta.o \
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index 6b19b8b..5137eba 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -333,7 +333,7 @@ GNATMAKE_OBJS = a-except.o ali.o ali-util.o aspects.o s-casuti.o alloc.o \
s-purexc.o s-htable.o scil_ll.o sem_aux.o sinfo.o sinput.o sinput-c.o \
snames.o stand.o stringt.o styleg.o stylesw.o system.o validsw.o \
switch.o switch-m.o table.o targparm.o tempdir.o types.o uintp.o \
- uname.o urealp.o usage.o widechar.o \
+ uname.o urealp.o usage.o widechar.o warnsw.o \
seinfo.o einfo-entities.o einfo-utils.o sinfo-nodes.o sinfo-utils.o \
$(EXTRA_GNATMAKE_OBJS)
diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc
index f8c7698..c383f9b 100644
--- a/gcc/ada/gcc-interface/decl.cc
+++ b/gcc/ada/gcc-interface/decl.cc
@@ -637,17 +637,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
break;
case E_Constant:
- /* If this is a constant related to a return in a function returning by
- invisible reference without expression, get the return object. */
- if (Is_Related_To_Func_Return (gnat_entity)
- && current_function_decl
- && TREE_ADDRESSABLE (TREE_TYPE (current_function_decl))
- && !gnu_expr)
- {
- gnu_decl = DECL_RESULT (current_function_decl);
- break;
- }
-
/* Ignore constant definitions already marked with the error node. See
the N_Object_Declaration case of gnat_to_gnu for the rationale. */
if (definition
@@ -8363,7 +8352,7 @@ components_to_record (Node_Id gnat_component_list, Entity_Id gnat_record_type,
&& !Debug_Flag_Dot_R);
const bool w_reorder
= (Convention (gnat_record_type) == Convention_Ada
- && Warn_On_Questionable_Layout
+ && Get_Warn_On_Questionable_Layout ()
&& !(No_Reordering (gnat_record_type) && GNAT_Mode));
tree gnu_zero_list = NULL_TREE;
tree gnu_self_list = NULL_TREE;
diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc
index d0ff741..59332f9 100644
--- a/gcc/ada/gcc-interface/trans.cc
+++ b/gcc/ada/gcc-interface/trans.cc
@@ -4400,6 +4400,11 @@ get_storage_model_access (Node_Id gnat_node, Entity_Id *gnat_smo)
return;
}
+ /* Now strip any type conversion from GNAT_NODE. */
+ if (Nkind (gnat_node) == N_Type_Conversion
+ || Nkind (gnat_node) == N_Unchecked_Type_Conversion)
+ gnat_node = Expression (gnat_node);
+
while (node_is_component (gnat_node))
gnat_node = Prefix (gnat_node);
@@ -6482,9 +6487,10 @@ gnat_to_gnu (Node_Id gnat_node)
then elide the temporary by forwarding the return object to Func:
+ result_type *Rnn = (result_type *) <retval>;
*<retval> = Func (); [return slot optimization]
[...]
- return <retval>;
+ return Rnn;
That's necessary if the result type needs finalization because the
temporary would never be adjusted as Expand_Simple_Function_Return
@@ -6496,8 +6502,12 @@ gnat_to_gnu (Node_Id gnat_node)
&& current_function_decl
&& TREE_ADDRESSABLE (TREE_TYPE (current_function_decl)))
{
- gnu_result = gnat_to_gnu_entity (gnat_temp, NULL_TREE, true);
- gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result);
+ gnat_to_gnu_entity (gnat_temp,
+ DECL_RESULT (current_function_decl),
+ true);
+ gnu_result
+ = build_unary_op (INDIRECT_REF, NULL_TREE,
+ DECL_RESULT (current_function_decl));
gnu_result
= Call_to_gnu (Prefix (Expression (gnat_node)),
&gnu_result_type, gnu_result,
@@ -7445,6 +7455,9 @@ gnat_to_gnu (Node_Id gnat_node)
else if (Present (gnat_smo)
&& Present (Storage_Model_Copy_To (gnat_smo)))
{
+ /* We obviously cannot use memset in this case. */
+ gcc_assert (!use_memset_p);
+
tree t = remove_conversions (gnu_rhs, false);
/* If a storage model load is present on the RHS then instantiate
@@ -8460,9 +8473,10 @@ gnat_to_gnu (Node_Id gnat_node)
declaration, return the result unmodified because we want to use the
return slot optimization in this case.
- 5. If this is a reference to an unconstrained array which is used as the
- prefix of an attribute reference that requires an lvalue, return the
- result unmodified because we want to return the original bounds.
+ 5. If this is a reference to an unconstrained array which is used either
+ as the prefix of an attribute reference that requires an lvalue or in
+ a return statement, then return the result unmodified because we want
+ to return the original bounds.
6. Finally, if the type of the result is already correct. */
@@ -8526,8 +8540,9 @@ gnat_to_gnu (Node_Id gnat_node)
else if (TREE_CODE (TREE_TYPE (gnu_result)) == UNCONSTRAINED_ARRAY_TYPE
&& Present (Parent (gnat_node))
- && Nkind (Parent (gnat_node)) == N_Attribute_Reference
- && lvalue_required_for_attribute_p (Parent (gnat_node)))
+ && ((Nkind (Parent (gnat_node)) == N_Attribute_Reference
+ && lvalue_required_for_attribute_p (Parent (gnat_node)))
+ || Nkind (Parent (gnat_node)) == N_Simple_Return_Statement))
;
else if (TREE_TYPE (gnu_result) != gnu_result_type)
diff --git a/gcc/ada/gcc-interface/utils2.cc b/gcc/ada/gcc-interface/utils2.cc
index ef81f8d..80d550c 100644
--- a/gcc/ada/gcc-interface/utils2.cc
+++ b/gcc/ada/gcc-interface/utils2.cc
@@ -2439,8 +2439,8 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc,
tree storage_ptr_type = build_pointer_type (storage_type);
tree lhs, rhs;
- size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (storage_type),
- init);
+ size = TYPE_SIZE_UNIT (storage_type);
+ size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, init);
/* If the size overflows, pass -1 so Storage_Error will be raised. */
if (TREE_CODE (size) == INTEGER_CST && !valid_constant_size_p (size))
@@ -2454,8 +2454,10 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc,
/* If there is an initializing expression, then make a constructor for
the entire object including the bounds and copy it into the object.
- If there is no initializing expression, just set the bounds. */
- if (init)
+ If there is no initializing expression, just set the bounds. Note
+ that, if we have a storage model, we need to copy the initializing
+ expression separately from the bounds. */
+ if (init && !pool_is_storage_model)
{
vec<constructor_elt, va_gc> *v;
vec_alloc (v, 2);
@@ -2472,11 +2474,28 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc,
{
lhs = build_component_ref (storage_deref, TYPE_FIELDS (storage_type),
false);
- rhs = build_template (template_type, type, NULL_TREE);
+ rhs = build_template (template_type, type, init);
}
if (pool_is_storage_model)
- storage_init = build_storage_model_store (gnat_pool, lhs, rhs);
+ {
+ storage_init = build_storage_model_store (gnat_pool, lhs, rhs);
+ if (init)
+ {
+ start_stmt_group ();
+ add_stmt (storage_init);
+ lhs
+ = build_component_ref (storage_deref,
+ DECL_CHAIN (TYPE_FIELDS (storage_type)),
+ false);
+ rhs = init;
+ size = TYPE_SIZE_UNIT (TREE_TYPE (lhs));
+ size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, init);
+ tree t = build_storage_model_store (gnat_pool, lhs, rhs, size);
+ add_stmt (t);
+ storage_init = end_stmt_group ();
+ }
+ }
else
storage_init = build_binary_op (INIT_EXPR, NULL_TREE, lhs, rhs);
@@ -2520,7 +2539,7 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc,
TREE_THIS_NOTRAP (storage_deref) = 1;
if (pool_is_storage_model)
storage_init
- = build_storage_model_store (gnat_pool, storage_deref, init);
+ = build_storage_model_store (gnat_pool, storage_deref, init, size);
else
storage_init
= build_binary_op (INIT_EXPR, NULL_TREE, storage_deref, init);
diff --git a/gcc/ada/gen_il-fields.ads b/gcc/ada/gen_il-fields.ads
index 83c7180..bc424ab 100644
--- a/gcc/ada/gen_il-fields.ads
+++ b/gcc/ada/gen_il-fields.ads
@@ -69,7 +69,6 @@ package Gen_IL.Fields is
Address_Warning_Posted,
Aggregate_Bounds,
Aliased_Present,
- Alloc_For_BIP_Return,
All_Others,
All_Present,
Alternatives,
@@ -98,6 +97,7 @@ package Gen_IL.Fields is
Cleanup_Actions,
Comes_From_Check_Or_Contract,
Comes_From_Extended_Return_Statement,
+ Comes_From_Iterator,
Compile_Time_Known_Aggregate,
Component_Associations,
Component_Clauses,
@@ -188,6 +188,7 @@ package Gen_IL.Fields is
Float_Truncate,
Formal_Type_Definition,
Forwards_OK,
+ For_Special_Return_Object,
From_Aspect_Specification,
From_At_Mod,
From_Conditional_Expression,
diff --git a/gcc/ada/gen_il-gen-gen_nodes.adb b/gcc/ada/gen_il-gen-gen_nodes.adb
index 556326a..ec0eba7 100644
--- a/gcc/ada/gen_il-gen-gen_nodes.adb
+++ b/gcc/ada/gen_il-gen-gen_nodes.adb
@@ -494,7 +494,7 @@ begin -- Gen_IL.Gen.Gen_Nodes
(Sy (Expression, Node_Id, Default_Empty),
Sy (Subpool_Handle_Name, Node_Id, Default_Empty),
Sy (Null_Exclusion_Present, Flag, Default_False),
- Sm (Alloc_For_BIP_Return, Flag),
+ Sm (For_Special_Return_Object, Flag),
Sm (Do_Storage_Check, Flag),
Sm (Is_Dynamic_Coextension, Flag),
Sm (Is_Static_Coextension, Flag),
@@ -906,6 +906,7 @@ begin -- Gen_IL.Gen.Gen_Nodes
Sy (Subtype_Mark, Node_Id, Default_Empty),
Sy (Access_Definition, Node_Id, Default_Empty),
Sy (Name, Node_Id, Default_Empty),
+ Sm (Comes_From_Iterator, Flag),
Sm (Corresponding_Generic_Association, Node_Id)));
Cc (N_Package_Renaming_Declaration, N_Renaming_Declaration,
diff --git a/gcc/ada/gen_il-internals.adb b/gcc/ada/gen_il-internals.adb
index cec5b94..09fe99f 100644
--- a/gcc/ada/gen_il-internals.adb
+++ b/gcc/ada/gen_il-internals.adb
@@ -257,8 +257,6 @@ package body Gen_IL.Internals is
-- Special cases for the same reason as in the above Image
-- function for Opt_Type_Enum.
- when Alloc_For_BIP_Return =>
- return "Alloc_For_BIP_Return";
when Assignment_OK =>
return "Assignment_OK";
when Backwards_OK =>
diff --git a/gcc/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb
index 3217546..0b29c6f 100644
--- a/gcc/ada/gnat1drv.adb
+++ b/gcc/ada/gnat1drv.adb
@@ -562,9 +562,10 @@ procedure Gnat1drv is
-- - suspicious contracts, which are useful for SPARK code
Reset_Style_Check_Options;
- Restore_Warnings (W => (Elab_Warnings => True,
- Warn_On_Suspicious_Contract => True,
- others => False));
+ Restore_Warnings
+ ((Warnings_Package.Elab_Warnings => True,
+ Warnings_Package.Warn_On_Suspicious_Contract => True,
+ others => False));
-- Suppress the generation of name tables for enumerations, which are
-- not needed for formal verification, and fall outside the SPARK
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index e79cdee..ed763f9 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -19,7 +19,7 @@
@copying
@quotation
-GNAT Reference Manual , Oct 04, 2022
+GNAT Reference Manual , Dec 01, 2022
AdaCore
@@ -135,9 +135,9 @@ Implementation Defined Pragmas
* Pragma CPP_Vtable::
* Pragma CPU::
* Pragma Deadline_Floor::
-* Pragma Default_Initial_Condition::
* Pragma Debug::
* Pragma Debug_Policy::
+* Pragma Default_Initial_Condition::
* Pragma Default_Scalar_Storage_Order::
* Pragma Default_Storage_Pool::
* Pragma Depends::
@@ -215,8 +215,8 @@ Implementation Defined Pragmas
* Pragma Ordered::
* Pragma Overflow_Mode::
* Pragma Overriding_Renamings::
-* Pragma Partition_Elaboration_Policy::
* Pragma Part_Of::
+* Pragma Partition_Elaboration_Policy::
* Pragma Passive::
* Pragma Persistent_BSS::
* Pragma Post::
@@ -284,8 +284,8 @@ Implementation Defined Pragmas
* Pragma Unreferenced_Objects::
* Pragma Unreserve_All_Interrupts::
* Pragma Unsuppress::
-* Pragma Use_VADS_Size::
* Pragma Unused::
+* Pragma Use_VADS_Size::
* Pragma Validity_Checks::
* Pragma Volatile::
* Pragma Volatile_Full_Access::
@@ -690,7 +690,7 @@ The GNAT Library
* Ada.Characters.Latin_9 (a-chlat9.ads): Ada Characters Latin_9 a-chlat9 ads.
* Ada.Characters.Wide_Latin_1 (a-cwila1.ads): Ada Characters Wide_Latin_1 a-cwila1 ads.
-* Ada.Characters.Wide_Latin_9 (a-cwila1.ads): Ada Characters Wide_Latin_9 a-cwila1 ads.
+* Ada.Characters.Wide_Latin_9 (a-cwila9.ads): Ada Characters Wide_Latin_9 a-cwila9 ads.
* Ada.Characters.Wide_Wide_Latin_1 (a-chzla1.ads): Ada Characters Wide_Wide_Latin_1 a-chzla1 ads.
* Ada.Characters.Wide_Wide_Latin_9 (a-chzla9.ads): Ada Characters Wide_Wide_Latin_9 a-chzla9 ads.
* Ada.Containers.Bounded_Holders (a-coboho.ads): Ada Containers Bounded_Holders a-coboho ads.
@@ -809,8 +809,8 @@ The GNAT Library
* GNAT.Threads (g-thread.ads): GNAT Threads g-thread ads.
* GNAT.Traceback (g-traceb.ads): GNAT Traceback g-traceb ads.
* GNAT.Traceback.Symbolic (g-trasym.ads): GNAT Traceback Symbolic g-trasym ads.
-* GNAT.UTF_32 (g-table.ads): GNAT UTF_32 g-table ads.
-* GNAT.Wide_Spelling_Checker (g-u3spch.ads): GNAT Wide_Spelling_Checker g-u3spch ads.
+* GNAT.UTF_32 (g-utf_32.ads): GNAT UTF_32 g-utf_32 ads.
+* GNAT.UTF_32_Spelling_Checker (g-u3spch.ads): GNAT UTF_32_Spelling_Checker g-u3spch ads.
* GNAT.Wide_Spelling_Checker (g-wispch.ads): GNAT Wide_Spelling_Checker g-wispch ads.
* GNAT.Wide_String_Split (g-wistsp.ads): GNAT Wide_String_Split g-wistsp ads.
* GNAT.Wide_Wide_Spelling_Checker (g-zspche.ads): GNAT Wide_Wide_Spelling_Checker g-zspche ads.
@@ -1220,9 +1220,9 @@ consideration, the use of these pragmas should be minimized.
* Pragma CPP_Vtable::
* Pragma CPU::
* Pragma Deadline_Floor::
-* Pragma Default_Initial_Condition::
* Pragma Debug::
* Pragma Debug_Policy::
+* Pragma Default_Initial_Condition::
* Pragma Default_Scalar_Storage_Order::
* Pragma Default_Storage_Pool::
* Pragma Depends::
@@ -1300,8 +1300,8 @@ consideration, the use of these pragmas should be minimized.
* Pragma Ordered::
* Pragma Overflow_Mode::
* Pragma Overriding_Renamings::
-* Pragma Partition_Elaboration_Policy::
* Pragma Part_Of::
+* Pragma Partition_Elaboration_Policy::
* Pragma Passive::
* Pragma Persistent_BSS::
* Pragma Post::
@@ -1369,8 +1369,8 @@ consideration, the use of these pragmas should be minimized.
* Pragma Unreferenced_Objects::
* Pragma Unreserve_All_Interrupts::
* Pragma Unsuppress::
-* Pragma Use_VADS_Size::
* Pragma Unused::
+* Pragma Use_VADS_Size::
* Pragma Validity_Checks::
* Pragma Volatile::
* Pragma Volatile_Full_Access::
@@ -2787,7 +2787,7 @@ that is, they never return an object whose type is a descendant of type T.
This pragma is now obsolete and, other than generating a warning if warnings
on obsolescent features are enabled, is completely ignored.
It is retained for compatibility
-purposes. It used to be required to ensure compoatibility with C++, but
+purposes. It used to be required to ensure compatibility with C++, but
is no longer required for that purpose because GNAT generates
the same object layout as the G++ compiler by default.
@@ -2823,7 +2823,7 @@ This pragma is standard in Ada 2012, but is available in all earlier
versions of Ada as an implementation-defined pragma.
See Ada 2012 Reference Manual for details.
-@node Pragma Deadline_Floor,Pragma Default_Initial_Condition,Pragma CPU,Implementation Defined Pragmas
+@node Pragma Deadline_Floor,Pragma Debug,Pragma CPU,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas pragma-deadline-floor}@anchor{4c}
@section Pragma Deadline_Floor
@@ -2838,22 +2838,8 @@ This pragma applies only to protected types and specifies the floor
deadline inherited by a task when the task enters a protected object.
It is effective only when the EDF scheduling policy is used.
-@node Pragma Default_Initial_Condition,Pragma Debug,Pragma Deadline_Floor,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas id8}@anchor{4d}@anchor{gnat_rm/implementation_defined_pragmas pragma-default-initial-condition}@anchor{4e}
-@section Pragma Default_Initial_Condition
-
-
-Syntax:
-
-@example
-pragma Default_Initial_Condition [ (null | boolean_EXPRESSION) ];
-@end example
-
-For the semantics of this pragma, see the entry for aspect
-@code{Default_Initial_Condition} in the SPARK 2014 Reference Manual, section 7.3.3.
-
-@node Pragma Debug,Pragma Debug_Policy,Pragma Default_Initial_Condition,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-debug}@anchor{4f}
+@node Pragma Debug,Pragma Debug_Policy,Pragma Deadline_Floor,Implementation Defined Pragmas
+@anchor{gnat_rm/implementation_defined_pragmas pragma-debug}@anchor{4d}
@section Pragma Debug
@@ -2880,8 +2866,8 @@ pragmas can be enabled either by use of the command line switch `-gnata'
or by use of the pragma @code{Check_Policy} with a first argument of
@code{Debug}.
-@node Pragma Debug_Policy,Pragma Default_Scalar_Storage_Order,Pragma Debug,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-debug-policy}@anchor{50}
+@node Pragma Debug_Policy,Pragma Default_Initial_Condition,Pragma Debug,Implementation Defined Pragmas
+@anchor{gnat_rm/implementation_defined_pragmas pragma-debug-policy}@anchor{4e}
@section Pragma Debug_Policy
@@ -2895,7 +2881,21 @@ This pragma is equivalent to a corresponding @code{Check_Policy} pragma
with a first argument of @code{Debug}. It is retained for historical
compatibility reasons.
-@node Pragma Default_Scalar_Storage_Order,Pragma Default_Storage_Pool,Pragma Debug_Policy,Implementation Defined Pragmas
+@node Pragma Default_Initial_Condition,Pragma Default_Scalar_Storage_Order,Pragma Debug_Policy,Implementation Defined Pragmas
+@anchor{gnat_rm/implementation_defined_pragmas id8}@anchor{4f}@anchor{gnat_rm/implementation_defined_pragmas pragma-default-initial-condition}@anchor{50}
+@section Pragma Default_Initial_Condition
+
+
+Syntax:
+
+@example
+pragma Default_Initial_Condition [ (null | boolean_EXPRESSION) ];
+@end example
+
+For the semantics of this pragma, see the entry for aspect
+@code{Default_Initial_Condition} in the SPARK 2014 Reference Manual, section 7.3.3.
+
+@node Pragma Default_Scalar_Storage_Order,Pragma Default_Storage_Pool,Pragma Default_Initial_Condition,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas pragma-default-scalar-storage-order}@anchor{51}
@section Pragma Default_Scalar_Storage_Order
@@ -3608,16 +3608,19 @@ GNAT User’s Guide.
Syntax:
@example
-pragma Extensions_Allowed (On | Off);
+pragma Extensions_Allowed (On | Off | All);
@end example
-This configuration pragma enables or disables the implementation
-extension mode (the use of Off as a parameter cancels the effect
-of the `-gnatX' command switch).
+This configuration pragma enables (via the “On” or “All” argument) or disables
+(via the “Off” argument) the implementation extension mode; the pragma takes
+precedence over the `-gnatX' and `-gnatX0' command switches.
-In extension mode, the latest version of the Ada language is
-implemented (currently Ada 2022), and in addition a number
-of GNAT specific extensions are recognized as follows:
+If an argument of “All” is specified, the latest version of the Ada language
+is implemented (currently Ada 2022) and, in addition, a number
+of GNAT specific extensions are recognized. These extensions are listed
+below. An argument of “On” has the same effect except that only
+some, not all, of the listed extensions are enabled; those extensions
+are identified below.
@itemize *
@@ -3636,11 +3639,7 @@ The Ada 202x @code{Static} aspect can be specified on Intrinsic imported
functions and the compiler will evaluate some of these intrinsic statically,
in particular the @code{Shift_Left} and @code{Shift_Right} intrinsics.
-@item
-@code{'Reduce} attribute
-
-This attribute part of the Ada 202x language definition is provided for
-now under -gnatX to confirm and potentially refine its usage and syntax.
+An Extensions_Allowed pragma argument of “On” enables this extension.
@item
@code{[]} aggregates
@@ -3785,6 +3784,8 @@ define the same set of bindings and the component subtypes for
for a given identifer must all statically match. Currently, the case
of a binding for a nondiscrete component is not implemented.
+An Extensions_Allowed pragma argument of “On” enables this extension.
+
@item
Fixed lower bounds for array types and subtypes
@@ -3833,6 +3834,8 @@ improve the efficiency of indexing operations, since the compiler statically
knows the lower bound of unconstrained array formals when the formal’s
subtype has index ranges with static fixed lower bounds.
+An Extensions_Allowed pragma argument of “On” enables this extension.
+
@item
Prefixed-view notation for calls to primitive subprograms of untagged types
@@ -3851,6 +3854,8 @@ 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).
+An Extensions_Allowed pragma argument of “On” enables this extension.
+
@item
Expression defaults for generic formal functions
@@ -5384,7 +5389,7 @@ decrease or increase in successive iterations of the loop. In its simplest
form, just one expression is specified, whose value must increase or decrease
on each iteration of the loop.
-In a more complex form, multiple arguments can be given which are intepreted
+In a more complex form, multiple arguments can be given which are interpreted
in a nesting lexicographic manner. For example:
@example
@@ -6101,7 +6106,7 @@ overflow checking, but does not affect the overflow mode.
The pragma @code{Unsuppress (Overflow_Check)} unsuppresses (enables)
overflow checking, but does not affect the overflow mode.
-@node Pragma Overriding_Renamings,Pragma Partition_Elaboration_Policy,Pragma Overflow_Mode,Implementation Defined Pragmas
+@node Pragma Overriding_Renamings,Pragma Part_Of,Pragma Overflow_Mode,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas pragma-overriding-renamings}@anchor{b0}
@section Pragma Overriding_Renamings
@@ -6136,40 +6141,40 @@ even though
RM 8.3 (15) stipulates that an overridden operation is not visible within the
declaration of the overriding operation.
-@node Pragma Partition_Elaboration_Policy,Pragma Part_Of,Pragma Overriding_Renamings,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-partition-elaboration-policy}@anchor{b1}
-@section Pragma Partition_Elaboration_Policy
+@node Pragma Part_Of,Pragma Partition_Elaboration_Policy,Pragma Overriding_Renamings,Implementation Defined Pragmas
+@anchor{gnat_rm/implementation_defined_pragmas id28}@anchor{b1}@anchor{gnat_rm/implementation_defined_pragmas pragma-part-of}@anchor{b2}
+@section Pragma Part_Of
Syntax:
@example
-pragma Partition_Elaboration_Policy (POLICY_IDENTIFIER);
+pragma Part_Of (ABSTRACT_STATE);
-POLICY_IDENTIFIER ::= Concurrent | Sequential
+ABSTRACT_STATE ::= NAME
@end example
-This pragma is standard in Ada 2005, but is available in all earlier
-versions of Ada as an implementation-defined pragma.
-See Ada 2012 Reference Manual for details.
+For the semantics of this pragma, see the entry for aspect @code{Part_Of} in the
+SPARK 2014 Reference Manual, section 7.2.6.
-@node Pragma Part_Of,Pragma Passive,Pragma Partition_Elaboration_Policy,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas id28}@anchor{b2}@anchor{gnat_rm/implementation_defined_pragmas pragma-part-of}@anchor{b3}
-@section Pragma Part_Of
+@node Pragma Partition_Elaboration_Policy,Pragma Passive,Pragma Part_Of,Implementation Defined Pragmas
+@anchor{gnat_rm/implementation_defined_pragmas pragma-partition-elaboration-policy}@anchor{b3}
+@section Pragma Partition_Elaboration_Policy
Syntax:
@example
-pragma Part_Of (ABSTRACT_STATE);
+pragma Partition_Elaboration_Policy (POLICY_IDENTIFIER);
-ABSTRACT_STATE ::= NAME
+POLICY_IDENTIFIER ::= Concurrent | Sequential
@end example
-For the semantics of this pragma, see the entry for aspect @code{Part_Of} in the
-SPARK 2014 Reference Manual, section 7.2.6.
+This pragma is standard in Ada 2005, but is available in all earlier
+versions of Ada as an implementation-defined pragma.
+See Ada 2012 Reference Manual for details.
-@node Pragma Passive,Pragma Persistent_BSS,Pragma Part_Of,Implementation Defined Pragmas
+@node Pragma Passive,Pragma Persistent_BSS,Pragma Partition_Elaboration_Policy,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas pragma-passive}@anchor{b4}
@section Pragma Passive
@@ -6442,7 +6447,7 @@ appear at the start of the declarations in a subprogram body
Note: This pragma is called @code{Post_Class} rather than
@code{Post'Class} because the latter would not be strictly
conforming to the allowed syntax for pragmas. The motivation
-for provinding pragmas equivalent to the aspects is to allow a program
+for providing pragmas equivalent to the aspects is to allow a program
to be written using the pragmas, and then compiled if necessary
using an Ada compiler that does not recognize the pragmas or
aspects, but is prepared to ignore the pragmas. The assertion
@@ -7758,7 +7763,7 @@ replacement of any dots in the unit name by the specified string literal.
Note that Source_File_Name pragmas should not be used if you are using
project files. The reason for this rule is that the project manager is not
-aware of these pragmas, and so other tools that use the projet file would not
+aware of these pragmas, and so other tools that use the project file would not
be aware of the intended naming conventions. If you are using project files,
file naming is controlled by Source_File_Name_Project pragmas, which are
usually supplied automatically by the project manager. A pragma
@@ -8407,7 +8412,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
-include Windows, Solaris, GNU/Linux, and VxWorks 6), this causes each
+include Windows, Solaris, GNU/Linux, and VxWorks), this causes each
thread (and hence each Ada task) to see a distinct copy of the variable.
The variable must not have default initialization, and if there is
@@ -8785,7 +8790,7 @@ For a more general facility for controlling what interrupts can be
handled, see pragma @code{Interrupt_State}, which subsumes the functionality
of the @code{Unreserve_All_Interrupts} pragma.
-@node Pragma Unsuppress,Pragma Use_VADS_Size,Pragma Unreserve_All_Interrupts,Implementation Defined Pragmas
+@node Pragma Unsuppress,Pragma Unused,Pragma Unreserve_All_Interrupts,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas pragma-unsuppress}@anchor{10e}
@section Pragma Unsuppress
@@ -8817,36 +8822,12 @@ pragma Unsuppress (Duplicated_Tag_Check);
This pragma is standard in Ada 2005. It is available in all earlier versions
of Ada as an implementation-defined pragma.
-Note that in addition to the checks defined in the Ada RM, GNAT recogizes a
+Note that in addition to the checks defined in the Ada RM, GNAT recognizes a
number of implementation-defined check names. See the description of pragma
@code{Suppress} for full details.
-@node Pragma Use_VADS_Size,Pragma Unused,Pragma Unsuppress,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-use-vads-size}@anchor{10f}
-@section Pragma Use_VADS_Size
-
-
-@geindex Size
-@geindex VADS compatibility
-
-@geindex Rational profile
-
-Syntax:
-
-@example
-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
-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 id52}@anchor{110}@anchor{gnat_rm/implementation_defined_pragmas pragma-unused}@anchor{111}
+@node Pragma Unused,Pragma Use_VADS_Size,Pragma Unsuppress,Implementation Defined Pragmas
+@anchor{gnat_rm/implementation_defined_pragmas id52}@anchor{10f}@anchor{gnat_rm/implementation_defined_pragmas pragma-unused}@anchor{110}
@section Pragma Unused
@@ -8879,7 +8860,31 @@ are typically to be used in cases where such warnings are expected.
Thus it is never necessary to use @code{pragma Unused} for such
variables, though it is harmless to do so.
-@node Pragma Validity_Checks,Pragma Volatile,Pragma Unused,Implementation Defined Pragmas
+@node Pragma Use_VADS_Size,Pragma Validity_Checks,Pragma Unused,Implementation Defined Pragmas
+@anchor{gnat_rm/implementation_defined_pragmas pragma-use-vads-size}@anchor{111}
+@section Pragma Use_VADS_Size
+
+
+@geindex Size
+@geindex VADS compatibility
+
+@geindex Rational profile
+
+Syntax:
+
+@example
+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
+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 Validity_Checks,Pragma Volatile,Pragma Use_VADS_Size,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas pragma-validity-checks}@anchor{112}
@section Pragma Validity_Checks
@@ -9109,7 +9114,7 @@ expression (which does not exist in Ada 83).
Note if the second argument of @code{DETAILS} is a @code{local_NAME} then the
second form is always understood. If the intention is to use
the fourth form, then you can write @code{NAME & ""} to force the
-intepretation as a `static_string_EXPRESSION'.
+interpretation as a `static_string_EXPRESSION'.
Note: if the first argument is a valid @code{TOOL_NAME}, it will be interpreted
that way. The use of the @code{TOOL_NAME} argument is relevant only to users
@@ -9172,7 +9177,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
@@ -9531,7 +9536,7 @@ This aspect is equivalent to @ref{54,,pragma Depends}.
@geindex Default_Initial_Condition
-This aspect is equivalent to @ref{4e,,pragma Default_Initial_Condition}.
+This aspect is equivalent to @ref{50,,pragma Default_Initial_Condition}.
@node Aspect Dimension,Aspect Dimension_System,Aspect Default_Initial_Condition,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-dimension}@anchor{129}
@@ -9925,7 +9930,7 @@ This aspect is equivalent to @ref{141,,attribute Object_Size}.
@section Aspect Obsolescent
-@geindex Obsolsecent
+@geindex Obsolescent
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
@@ -9938,7 +9943,7 @@ delayed until the freeze point.
@geindex Part_Of
-This aspect is equivalent to @ref{b3,,pragma Part_Of}.
+This aspect is equivalent to @ref{b2,,pragma Part_Of}.
@node Aspect Persistent_BSS,Aspect Predicate,Aspect Part_Of,Implementation Defined Aspects
@anchor{gnat_rm/implementation_defined_aspects aspect-persistent-bss}@anchor{144}
@@ -10981,7 +10986,7 @@ this attribute.
@code{P'Library_Level}, where P is an entity name,
returns a Boolean value which is True if the entity is declared
at the library level, and False otherwise. Note that within a
-generic instantition, the name of the generic unit denotes the
+generic instantiation, the name of the generic unit denotes the
instance, which means that this attribute can be used to test
if a generic is instantiated at the library level, as shown
in this example:
@@ -11707,7 +11712,7 @@ an implicit dependency on this unit.
@geindex System_Allocator_Alignment
@code{Standard'System_Allocator_Alignment} (@code{Standard} is the only
-allowed prefix) provides the observable guaranted to be honored by
+allowed prefix) provides the observable guaranteed to be honored by
the system allocator (malloc). This is a static value that can be used
in user storage pools based on malloc either to reject allocation
with alignment too large or to enable a realignment circuitry if the
@@ -17856,7 +17861,7 @@ a distributed application.
“The range of type System.RPC.Partition_Id. See E.5(14).”
@end itemize
-System.RPC.Partion_ID’Last is Integer’Last. See source file @code{s-rpc.ads}.
+System.RPC.Partition_ID’Last is Integer’Last. See source file @code{s-rpc.ads}.
@itemize *
@@ -20874,7 +20879,7 @@ This package provides operations on directories.
@item @code{Ada.Directories.Hierarchical_File_Names} `(A.16.1)'
This package provides additional directory operations handling
-hiearchical file names.
+hierarchical file names.
@item @code{Ada.Directories.Information} `(A.16)'
@@ -21340,7 +21345,7 @@ only the tag value.
This package provides the capability of associating arbitrary
task-specific data with separate tasks.
-@item @code{Ada.Task_Identifification} `(C.7.1)'
+@item @code{Ada.Task_Identification} `(C.7.1)'
This package provides capabilities for task identification.
@@ -23100,7 +23105,7 @@ of GNAT, and will generate a warning message.
@menu
* Ada.Characters.Latin_9 (a-chlat9.ads): Ada Characters Latin_9 a-chlat9 ads.
* Ada.Characters.Wide_Latin_1 (a-cwila1.ads): Ada Characters Wide_Latin_1 a-cwila1 ads.
-* Ada.Characters.Wide_Latin_9 (a-cwila1.ads): Ada Characters Wide_Latin_9 a-cwila1 ads.
+* Ada.Characters.Wide_Latin_9 (a-cwila9.ads): Ada Characters Wide_Latin_9 a-cwila9 ads.
* Ada.Characters.Wide_Wide_Latin_1 (a-chzla1.ads): Ada Characters Wide_Wide_Latin_1 a-chzla1 ads.
* Ada.Characters.Wide_Wide_Latin_9 (a-chzla9.ads): Ada Characters Wide_Wide_Latin_9 a-chzla9 ads.
* Ada.Containers.Bounded_Holders (a-coboho.ads): Ada Containers Bounded_Holders a-coboho ads.
@@ -23219,8 +23224,8 @@ of GNAT, and will generate a warning message.
* GNAT.Threads (g-thread.ads): GNAT Threads g-thread ads.
* GNAT.Traceback (g-traceb.ads): GNAT Traceback g-traceb ads.
* GNAT.Traceback.Symbolic (g-trasym.ads): GNAT Traceback Symbolic g-trasym ads.
-* GNAT.UTF_32 (g-table.ads): GNAT UTF_32 g-table ads.
-* GNAT.Wide_Spelling_Checker (g-u3spch.ads): GNAT Wide_Spelling_Checker g-u3spch ads.
+* GNAT.UTF_32 (g-utf_32.ads): GNAT UTF_32 g-utf_32 ads.
+* GNAT.UTF_32_Spelling_Checker (g-u3spch.ads): GNAT UTF_32_Spelling_Checker g-u3spch ads.
* GNAT.Wide_Spelling_Checker (g-wispch.ads): GNAT Wide_Spelling_Checker g-wispch ads.
* GNAT.Wide_String_Split (g-wistsp.ads): GNAT Wide_String_Split g-wistsp ads.
* GNAT.Wide_Wide_Spelling_Checker (g-zspche.ads): GNAT Wide_Wide_Spelling_Checker g-zspche ads.
@@ -23261,12 +23266,12 @@ of GNAT, and will generate a warning message.
This child of @code{Ada.Characters}
provides a set of definitions corresponding to those in the
RM-defined package @code{Ada.Characters.Latin_1} but with the
-few modifications required for @code{Latin-9}
+few modifications required for @code{Latin-9}.
The provision of such a package
is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
-@node Ada Characters Wide_Latin_1 a-cwila1 ads,Ada Characters Wide_Latin_9 a-cwila1 ads,Ada Characters Latin_9 a-chlat9 ads,The GNAT Library
+@node Ada Characters Wide_Latin_1 a-cwila1 ads,Ada Characters Wide_Latin_9 a-cwila9 ads,Ada Characters Latin_9 a-chlat9 ads,The GNAT Library
@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-1-a-cwila1-ads}@anchor{2d9}@anchor{gnat_rm/the_gnat_library id3}@anchor{2da}
@section @code{Ada.Characters.Wide_Latin_1} (@code{a-cwila1.ads})
@@ -23283,12 +23288,12 @@ instead of @code{Character}. The provision of such a package
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 ada-characters-wide-latin-9-a-cwila1-ads}@anchor{2db}@anchor{gnat_rm/the_gnat_library id4}@anchor{2dc}
-@section @code{Ada.Characters.Wide_Latin_9} (@code{a-cwila1.ads})
+@node Ada Characters Wide_Latin_9 a-cwila9 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 ada-characters-wide-latin-9-a-cwila9-ads}@anchor{2db}@anchor{gnat_rm/the_gnat_library id4}@anchor{2dc}
+@section @code{Ada.Characters.Wide_Latin_9} (@code{a-cwila9.ads})
-@geindex Ada.Characters.Wide_Latin_9 (a-cwila1.ads)
+@geindex Ada.Characters.Wide_Latin_9 (a-cwila9.ads)
@geindex Latin_9 constants for Wide_Character
@@ -23300,7 +23305,7 @@ instead of @code{Character}. The provision of such a package
is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
-@node Ada Characters Wide_Wide_Latin_1 a-chzla1 ads,Ada Characters Wide_Wide_Latin_9 a-chzla9 ads,Ada Characters Wide_Latin_9 a-cwila1 ads,The GNAT Library
+@node Ada Characters Wide_Wide_Latin_1 a-chzla1 ads,Ada Characters Wide_Wide_Latin_9 a-chzla9 ads,Ada Characters Wide_Latin_9 a-cwila9 ads,The GNAT Library
@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-1-a-chzla1-ads}@anchor{2dd}@anchor{gnat_rm/the_gnat_library id5}@anchor{2de}
@section @code{Ada.Characters.Wide_Wide_Latin_1} (@code{a-chzla1.ads})
@@ -23374,8 +23379,8 @@ where this concept makes sense.
This child of @code{Ada.Command_Line}
provides a mechanism for logically removing
arguments from the argument list. Once removed, an argument is not visible
-to further calls on the subprograms in @code{Ada.Command_Line} will not
-see the removed argument.
+to further calls to the subprograms in @code{Ada.Command_Line}. These calls
+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 ada-command-line-response-file-a-clrefi-ads}@anchor{2e7}@anchor{gnat_rm/the_gnat_library id10}@anchor{2e8}
@@ -24067,7 +24072,7 @@ obtaining information about exceptions provided by Ada 83 compilers.
@geindex Memory corruption debugging
-Provide a debugging storage pools that helps tracking memory corruption
+Provides 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}.
@@ -24280,7 +24285,7 @@ a message from a subprogram in a pure package, since the
necessary types and subprograms are in @code{Ada.Exceptions}
which is not a pure unit. @code{GNAT.Exceptions} provides a
facility for getting around this limitation for a few
-predefined exceptions, and for example allow raising
+predefined exceptions, and for example allows 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
@@ -24335,7 +24340,7 @@ in this package can be used to reestablish the required mode.
@geindex Formatted String
Provides support for C/C++ printf() formatted strings. The format is
-copied from the printf() routine and should therefore gives identical
+copied from the printf() routine and should therefore give identical
output. Some generic routines are provided to be able to use types
derived from Integer, Float or enumerations as values for the
formatted string.
@@ -24552,7 +24557,7 @@ Provides a generator of static minimal perfect hash functions. No
collisions occur and each item can be retrieved from the table in one
probe (perfect property). The hash table size corresponds to the exact
size of the key set and no larger (minimal property). The key set has to
-be know in advance (static property). The hash functions are also order
+be known in advance (static property). The hash functions are also order
preserving. If w2 is inserted after w1 in the generator, their
hashcode are in the same order. These hashing functions are very
convenient for use with realtime applications.
@@ -24637,7 +24642,7 @@ 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
+Provides 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
@@ -24752,7 +24757,7 @@ targets.
A high level and portable interface to develop sockets based applications.
This package is based on the sockets thin binding found in
@code{GNAT.Sockets.Thin}. Currently @code{GNAT.Sockets} is implemented
-on all native GNAT ports and on VxWorks cross prots. It is not implemented for
+on all native GNAT ports and on VxWorks cross ports. It is not implemented for
the LynxOS cross port.
@node GNAT Source_Info g-souinf ads,GNAT Spelling_Checker g-speche ads,GNAT Sockets g-socket ads,The GNAT Library
@@ -25012,7 +25017,7 @@ environment which then accesses Ada code.
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
+@node GNAT Traceback Symbolic g-trasym ads,GNAT UTF_32 g-utf_32 ads,GNAT Traceback g-traceb ads,The GNAT Library
@anchor{gnat_rm/the_gnat_library gnat-traceback-symbolic-g-trasym-ads}@anchor{3c6}@anchor{gnat_rm/the_gnat_library id122}@anchor{3c7}
@section @code{GNAT.Traceback.Symbolic} (@code{g-trasym.ads})
@@ -25021,12 +25026,12 @@ 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 gnat-utf-32-g-table-ads}@anchor{3c8}@anchor{gnat_rm/the_gnat_library id123}@anchor{3c9}
-@section @code{GNAT.UTF_32} (@code{g-table.ads})
+@node GNAT UTF_32 g-utf_32 ads,GNAT UTF_32_Spelling_Checker g-u3spch ads,GNAT Traceback Symbolic g-trasym ads,The GNAT Library
+@anchor{gnat_rm/the_gnat_library gnat-utf-32-g-utf-32-ads}@anchor{3c8}@anchor{gnat_rm/the_gnat_library id123}@anchor{3c9}
+@section @code{GNAT.UTF_32} (@code{g-utf_32.ads})
-@geindex GNAT.UTF_32 (g-table.ads)
+@geindex GNAT.UTF_32 (g-utf_32.ads)
@geindex Wide character codes
@@ -25040,12 +25045,12 @@ lexical rules for identifiers and strings, and also a
lower case to upper case fold routine corresponding to
the Ada 2005 rules for identifier equivalence.
-@node GNAT Wide_Spelling_Checker g-u3spch ads,GNAT Wide_Spelling_Checker g-wispch ads,GNAT UTF_32 g-table ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-u3spch-ads}@anchor{3ca}@anchor{gnat_rm/the_gnat_library id124}@anchor{3cb}
-@section @code{GNAT.Wide_Spelling_Checker} (@code{g-u3spch.ads})
+@node GNAT UTF_32_Spelling_Checker g-u3spch ads,GNAT Wide_Spelling_Checker g-wispch ads,GNAT UTF_32 g-utf_32 ads,The GNAT Library
+@anchor{gnat_rm/the_gnat_library gnat-utf-32-spelling-checker-g-u3spch-ads}@anchor{3ca}@anchor{gnat_rm/the_gnat_library id124}@anchor{3cb}
+@section @code{GNAT.UTF_32_Spelling_Checker} (@code{g-u3spch.ads})
-@geindex GNAT.Wide_Spelling_Checker (g-u3spch.ads)
+@geindex GNAT.UTF_32_Spelling_Checker (g-u3spch.ads)
@geindex Spell checking
@@ -25053,7 +25058,7 @@ Provides a function for determining whether one wide wide string is a plausible
near misspelling of another wide wide string, where the strings are represented
using the UTF_32_String type defined in System.Wch_Cnv.
-@node GNAT Wide_Spelling_Checker g-wispch ads,GNAT Wide_String_Split g-wistsp ads,GNAT Wide_Spelling_Checker g-u3spch ads,The GNAT Library
+@node GNAT Wide_Spelling_Checker g-wispch ads,GNAT Wide_String_Split g-wistsp ads,GNAT UTF_32_Spelling_Checker g-u3spch ads,The GNAT Library
@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-wispch-ads}@anchor{3cc}@anchor{gnat_rm/the_gnat_library id125}@anchor{3cd}
@section @code{GNAT.Wide_Spelling_Checker} (@code{g-wispch.ads})
@@ -29032,11 +29037,122 @@ For each block that is marked as visited, the mechanism checks that at
least one of its predecessors, and at least one of its successors, are
also marked as visited.
-Verification is performed just before returning. Subprogram
-executions that complete by raising or propagating an exception bypass
-verification-and-return points. A subprogram that can only complete
-by raising or propagating an exception may have instrumentation
-disabled altogether.
+Verification is performed just before a subprogram returns. The
+following fragment:
+
+@example
+if X then
+ Y := F (Z);
+ return;
+end if;
+@end example
+
+gets turned into:
+
+@example
+type Visited_Bitmap is array (1..N) of Boolean with Pack;
+Visited : aliased Visited_Bitmap := (others => False);
+-- Bitmap of visited blocks. N is the basic block count.
+[...]
+-- Basic block #I
+Visited(I) := True;
+if X then
+ -- Basic block #J
+ Visited(J) := True;
+ Y := F (Z);
+ CFR.Check (N, Visited'Access, CFG'Access);
+ -- CFR is a hypothetical package whose Check procedure calls
+ -- libgcc's __hardcfr_check, that traps if the Visited bitmap
+ -- does not hold a valid path in CFG, the run-time
+ -- representation of the control flow graph in the enclosing
+ -- subprogram.
+ return;
+end if;
+-- Basic block #K
+Visited(K) := True;
+@end example
+
+Verification would also be performed before tail calls, if any
+front-ends marked them as mandatory or desirable, but none do.
+Regular calls are optimized into tail calls too late for this
+transformation to act on it.
+
+In order to avoid adding verification after potential tail calls,
+which would prevent tail-call optimization, we recognize returning
+calls, i.e., calls whose result, if any, is returned by the calling
+subprogram to its caller immediately after the call returns.
+Verification is performed before such calls, whether or not they are
+ultimately optimized to tail calls. This behavior is enabled by
+default whenever sibcall optimization is enabled (see
+@code{-foptimize-sibling-calls}); it may be disabled with
+@code{-fno-hardcfr-check-returning-calls}, or enabled with
+@code{-fhardcfr-check-returning-calls}, regardless of the
+optimization, but the lack of other optimizations may prevent calls
+from being recognized as returning calls:
+
+@example
+-- CFR.Check here, with -fhardcfr-check-returning-calls.
+P (X);
+-- CFR.Check here, with -fno-hardcfr-check-returning-calls.
+return;
+@end example
+
+or:
+
+@example
+-- CFR.Check here, with -fhardcfr-check-returning-calls.
+R := F (X);
+-- CFR.Check here, with -fno-hardcfr-check-returning-calls.
+return R;
+@end example
+
+Any subprogram from which an exception may escape, i.e., that may
+raise or propagate an exception that isn’t handled internally, is
+conceptually enclosed by a cleanup handler that performs verification,
+unless this is disabled with @code{-fno-hardcfr-check-exceptions}.
+With this feature enabled, a subprogram body containing:
+
+@example
+-- ...
+ Y := F (X); -- May raise exceptions.
+-- ...
+ raise E; -- Not handled internally.
+-- ...
+@end example
+
+gets modified as follows:
+
+@example
+begin
+ -- ...
+ Y := F (X); -- May raise exceptions.
+ -- ...
+ raise E; -- Not handled internally.
+ -- ...
+exception
+ when others =>
+ CFR.Check (N, Visited'Access, CFG'Access);
+ raise;
+end;
+@end example
+
+Verification may also be performed before No_Return calls, whether
+only nothrow ones, with
+@code{-fhardcfr-check-noreturn-calls=nothrow}, or all of them, with
+@code{-fhardcfr-check-noreturn-calls=always}. The default is
+@code{-fhardcfr-check-noreturn-calls=never} for this feature, that
+disables checking before No_Return calls.
+
+When a No_Return call returns control to its caller through an
+exception, verification may have already been performed before the
+call, if @code{-fhardcfr-check-noreturn-calls=always} is in effect.
+The compiler arranges for already-checked No_Return calls without a
+preexisting handler to bypass the implicitly-added cleanup handler and
+thus the redundant check, but a local exception or cleanup handler, if
+present, will modify the set of visited blocks, and checking will take
+place again when the caller reaches the next verification point,
+whether it is a return or reraise statement after the exception is
+otherwise handled, or even another No_Return call.
The instrumentation for hardening with control flow redundancy can be
observed in dump files generated by the command-line option
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index 7d96dbe..dfe44b0 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 5.1.1.@*
+@*Generated by Sphinx 5.2.3.@*
@end ifinfo
@settitle GNAT User's Guide for Native Platforms
@defindex ge
@@ -19,7 +19,7 @@
@copying
@quotation
-GNAT User's Guide for Native Platforms , Sep 26, 2022
+GNAT User's Guide for Native Platforms , Dec 01, 2022
AdaCore
@@ -9881,7 +9881,17 @@ Suppress generation of cross-reference information.
@item @code{-gnatX}
-Enable GNAT implementation extensions and latest Ada version.
+Enable core GNAT implementation extensions and latest Ada version.
+@end table
+
+@geindex -gnatX0 (gcc)
+
+
+@table @asis
+
+@item @code{-gnatX0}
+
+Enable all GNAT implementation extensions and latest Ada version.
@end table
@geindex -gnaty (gcc)
@@ -10723,6 +10733,9 @@ switch are:
@code{-gnatw.q} (questionable layout of record types)
@item
+@code{-gnatw_q} (ignored equality)
+
+@item
@code{-gnatw_r} (out-of-order record representation clauses)
@item
@@ -10912,7 +10925,7 @@ This switch activates warnings for conditional expressions used in
tests that are known to be True or False at compile time. The default
is that such warnings are not generated.
Note that this warning does
-not get issued for the use of boolean variables or constants whose
+not get issued for the use of boolean constants whose
values are known at compile time, since this is a standard technique
for conditional compilation in Ada, and this would generate too many
false positive warnings.
@@ -11087,7 +11100,7 @@ of the pragma @code{Restriction_Warnings}.
`[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
`[enabled by default]'
@@ -11292,8 +11305,13 @@ This switch suppresses warnings on hiding declarations.
This switch activates warnings on component clauses in record
representation clauses that leave holes (gaps) in the record layout.
-If this warning option is active, then record representation clauses
-should specify a contiguous layout, adding unused fill fields if needed.
+If a record representation clause does not specify a location for
+every component of the record type, then the warnings generated (or not
+generated) are unspecified. For example, there may be gaps for which
+either no warning is generated or a warning is generated that
+incorrectly describes the location of the gap. This undesirable situation
+can sometimes be avoided by adding (and specifying the location for) unused
+fill fields.
@end table
@geindex -gnatw.H (gcc)
@@ -11938,6 +11956,34 @@ This switch suppresses warnings for cases where the default layout of
a record type would very likely cause inefficiencies.
@end table
+@geindex -gnatw_q (gcc)
+
+
+@table @asis
+
+@item @code{-gnatw_q}
+
+`Activate warnings for ignored equality operators.'
+
+This switch activates warnings for a user-defined “=” function that does
+not compose (i.e. is ignored for a predefined “=” for a composite type
+containing a component whose type has the user-defined “=” as
+primitive). Note that the user-defined “=” must be a primitive operator
+in order to trigger the warning.
+
+The default is that these warnings are not given.
+@end table
+
+@geindex -gnatw_Q (gcc)
+
+
+@table @asis
+
+@item @code{-gnatw_Q}
+
+`Suppress warnings for ignored equality operators.'
+@end table
+
@geindex -gnatwr (gcc)
@@ -14416,7 +14462,7 @@ This switch directs the compiler to implement the Ada 2022 version of the
language.
@end table
-@geindex -gnatX (gcc)
+@geindex -gnatX0 (gcc)
@geindex Ada language extensions
@@ -14425,7 +14471,7 @@ language.
@table @asis
-@item @code{-gnatX} (Enable GNAT Extensions)
+@item @code{-gnatX0} (Enable GNAT Extensions)
This switch directs the compiler to implement the latest version of the
language (currently Ada 2022) and also to enable certain GNAT implementation
@@ -14433,6 +14479,24 @@ extensions that are not part of any Ada standard. For a full list of these
extensions, see the GNAT reference manual, @code{Pragma Extensions_Allowed}.
@end table
+@geindex -gnatX (gcc)
+
+@geindex Ada language extensions
+
+@geindex GNAT extensions
+
+
+@table @asis
+
+@item @code{-gnatX} (Enable core GNAT Extensions)
+
+This switch is similar to -gnatX0 except that only some, not all, of the
+GNAT-defined language extensions are enabled. For a list of the
+extensions enabled by this switch, see the GNAT reference manual
+@code{Pragma Extensions_Allowed} and the description of that pragma’s
+“On” (as opposed to “All”) argument.
+@end table
+
@node Character Set Control,File Naming Control,Compiling Different Versions of Ada,Compiler Switches
@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
@@ -16689,7 +16753,7 @@ development environments much more flexible.
@subsection Examples of @code{gnatbind} Usage
-Here are some examples of @code{gnatbind} invovations:
+Here are some examples of @code{gnatbind} invocations:
@quotation
@@ -17934,7 +17998,6 @@ instr.ads
-
@c -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit
@node GNAT and Program Execution,Platform-Specific Information,GNAT Utility Programs,Top
@@ -19065,16 +19128,18 @@ bug occurs, and then be able to retrieve the sequence of calls with the same
program compiled with debug information.
However the @code{addr2line} tool does not work with Position-Independent Code
-(PIC), the historical example being Windows DLLs, which nowadays encompasses
-Position-Independent Executables (PIE) on recent Windows versions.
+(PIC), the historical example being Linux dynamic libraries and Windows DLLs,
+which nowadays encompasse Position-Independent Executables (PIE) on recent
+Linux and Windows versions.
-In order to translate addresses into the source lines with Position-Independent
-Executables on recent Windows versions, in other words without using the switch
-@code{-no-pie} during linking, you need to use the @code{gnatsymbolize} tool
-with @code{--load} instead of the @code{addr2line} tool. The main difference
-is that you need to copy the Load Address output in the traceback ahead of the
-sequence of addresses. And the default mode of @code{gnatsymbolize} is equivalent
-to that of @code{addr2line} with the above switches, so none of them is needed:
+In order to translate addresses the source lines with Position-Independent
+Executables on recent Linux and Windows versions, in other words without
+using the switch @code{-no-pie} during linking, you need to use the
+@code{gnatsymbolize} tool with @code{--load} instead of the @code{addr2line}
+tool. The main difference is that you need to copy the Load Address output
+in the traceback ahead of the sequence of addresses. And the default mode
+of @code{gnatsymbolize} is equivalent to that of @code{addr2line} with the above
+switches, so none of them is needed:
@example
$ gnatmake stb -g -bargs -E
@@ -19086,7 +19151,7 @@ Load address: 0x400000
Call stack traceback locations:
0x401373 0x40138b 0x40139c 0x401335 0x4011c4 0x4011f1 0x77e892a4
-$ gnatsymbolize --load stb 0x400000 0x401373 0x40138b 0x40139c 0x401335
+$ gnatsymbolize --load stb 0x400000 0x401373 0x40138b 0x40139c 0x401335 \
0x4011c4 0x4011f1 0x77e892a4
0x00401373 Stb.P1 at stb.adb:5
@@ -19135,13 +19200,9 @@ begin
P2;
end STB;
@end example
-@end quotation
-
-This program will output:
-
-@quotation
@example
+$ gnatmake stb -g -bargs -E -largs -no-pie
$ stb
raised CONSTRAINT_ERROR : stb.adb:12 range check failed
@@ -19171,12 +19232,17 @@ addresses to strings:
with Ada.Text_IO;
with GNAT.Traceback;
with GNAT.Debug_Utilities;
+with System;
procedure STB is
use Ada;
+ use Ada.Text_IO;
use GNAT;
use GNAT.Traceback;
+ use System;
+
+ LA : constant Address := Executable_Load_Address;
procedure P1 is
TB : Tracebacks_Array (1 .. 10);
@@ -19186,14 +19252,14 @@ procedure STB is
begin
Call_Chain (TB, Len);
- Text_IO.Put ("In STB.P1 : ");
+ Put ("In STB.P1 : ");
for K in 1 .. Len loop
- Text_IO.Put (Debug_Utilities.Image (TB (K)));
- Text_IO.Put (' ');
+ Put (Debug_Utilities.Image_C (TB (K)));
+ Put (' ');
end loop;
- Text_IO.New_Line;
+ New_Line;
end P1;
procedure P2 is
@@ -19202,6 +19268,10 @@ procedure STB is
end P2;
begin
+ if LA /= Null_Address then
+ Put_Line ("Load address: " & Debug_Utilities.Image_C (LA));
+ end if;
+
P2;
end STB;
@end example
@@ -19210,8 +19280,9 @@ end STB;
$ gnatmake stb -g
$ stb
-In STB.P1 : 16#0040_F1E4# 16#0040_14F2# 16#0040_170B# 16#0040_171C#
-16#0040_1461# 16#0040_11C4# 16#0040_11F1# 16#77E8_92A4#
+Load address: 0x400000
+In STB.P1 : 0x40F1E4 0x4014F2 0x40170B 0x40171C 0x401461 0x4011C4 \
+ 0x4011F1 0x77E892A4
@end example
@end quotation
@@ -19275,7 +19346,7 @@ end STB;
@end example
@example
-$ gnatmake -g .\stb -bargs -E
+$ gnatmake -g stb -bargs -E
$ stb
0040149F in stb.p1 at stb.adb:8
@@ -19289,15 +19360,6 @@ $ stb
@end example
@end quotation
-In the above example the @code{.\} syntax in the @code{gnatmake} command
-is currently required by @code{addr2line} for files that are in
-the current working directory.
-Moreover, the exact sequence of linker options may vary from platform
-to platform.
-The above @code{-largs} section is for Windows platforms. By contrast,
-under Unix there is no need for the @code{-largs} section.
-Differences across platforms are due to details of linker implementation.
-
@subsubheading Tracebacks From Anywhere in a Program
@@ -19493,10 +19555,10 @@ It is currently supported on the following platforms
@itemize *
@item
-linux x86/x86_64
+Linux x86/x86_64
@item
-windows x86
+Windows x86/x86_64 (without PIE support)
@end itemize
In order to profile a program using @code{gprof}, several steps are needed:
@@ -19555,6 +19617,9 @@ Note that only the objects that were compiled with the @code{-pg} switch will
be profiled; if you need to profile your whole project, use the @code{-f}
gnatmake switch to force full recompilation.
+Note that on Windows, gprof does not support PIE. The @code{-no-pie} switch
+should be added to the linker flags to disable this feature.
+
@node Program execution,Running gprof,Compilation for profiling,Profiling an Ada Program with gprof
@anchor{gnat_ugn/gnat_and_program_execution id23}@anchor{175}@anchor{gnat_ugn/gnat_and_program_execution program-execution}@anchor{176}
@subsubsection Program execution
@@ -20765,7 +20830,7 @@ erroneous, and the compiler would be entitled to assume that
However, in practice, this would cause some existing code that
seems to work with no optimization to start failing at high
-levels of optimzization.
+levels of optimization.
What the compiler does for such cases is to assume that marking
a variable as aliased indicates that some “funny business” may
@@ -21216,7 +21281,7 @@ To deal with the portability issue, and with the problem of
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
+furthermore, permits separate selection of operating modes for
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.
@@ -27296,8 +27361,9 @@ change pragma Elaborate_All for unit "..." to Elaborate in unit "..."
@end example
This tactic is always suggested with the pragma @code{Elaborate_All} elimination
-tactic. It offers a different alernative of guaranteeing that the argument of
-the pragma will still be elaborated prior to the unit containing the pragma.
+tactic. It offers a different alternative of guaranteeing that the argument
+of the pragma will still be elaborated prior to the unit containing the
+pragma.
The programmer should update the pragma as advised, and rebuild the program.
@@ -27670,7 +27736,7 @@ checks. The example above will still fail at run time with an ABE.
A programmer should first compile the program with the default options, using
none of the binder or compiler switches. If the binder succeeds in finding an
-elaboration order, then apart from possible cases involing dispatching calls
+elaboration order, then apart from possible cases involving dispatching calls
and access-to-subprogram types, the program is free of elaboration errors.
If it is important for the program to be portable to compilers other than GNAT,
diff --git a/gcc/ada/gnatbind.adb b/gcc/ada/gnatbind.adb
index 475702a..509b4d3 100644
--- a/gcc/ada/gnatbind.adb
+++ b/gcc/ada/gnatbind.adb
@@ -215,6 +215,9 @@ procedure Gnatbind is
No_Specification_Of_Aspect => False,
-- Requires a parameter value, not a count
+ No_Task_Hierarchy_Implicit => False,
+ -- A compiler implementation artifact, not a documented restriction
+
No_Use_Of_Attribute => False,
-- Requires a parameter value, not a count
diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb
index e3f35da..d33f5b4 100644
--- a/gcc/ada/inline.adb
+++ b/gcc/ada/inline.adb
@@ -3013,14 +3013,10 @@ package body Inline is
Temp_Typ := Etype (A);
end if;
- -- If the actual is a simple name or a literal, no need to
- -- create a temporary, object can be used directly.
-
- -- If the actual is a literal and the formal has its address taken,
- -- we cannot pass the literal itself as an argument, so its value
- -- must be captured in a temporary. Skip this optimization in
- -- GNATprove mode, to make sure any check on a type conversion
- -- will be issued.
+ -- If the actual is a simple name or a literal, no need to create a
+ -- temporary, object can be used directly. Skip this optimization in
+ -- GNATprove mode, to make sure any check on a type conversion will
+ -- be issued.
if (Is_Entity_Name (A)
and then
@@ -3039,6 +3035,10 @@ package body Inline is
and then Formal_Is_Used_Once (F)
and then not GNATprove_Mode)
+ -- If the actual is a literal and the formal has its address taken,
+ -- we cannot pass the literal itself as an argument, so its value
+ -- must be captured in a temporary.
+
or else
(Nkind (A) in
N_Real_Literal | N_Integer_Literal | N_Character_Literal
@@ -4723,8 +4723,8 @@ package body Inline is
--------------------
function Replace_Formal (N : Node_Id) return Traverse_Result is
- A : Entity_Id;
- E : Entity_Id;
+ A : Entity_Id;
+ E : Entity_Id;
begin
if Is_Entity_Name (N) and then Present (Entity (N)) then
diff --git a/gcc/ada/inline.ads b/gcc/ada/inline.ads
index 05aaac7..82d4807 100644
--- a/gcc/ada/inline.ads
+++ b/gcc/ada/inline.ads
@@ -94,7 +94,7 @@ package Inline is
-- This means we have to capture this information from the current scope
-- at the point of instantiation.
- Warnings : Warning_Record;
+ Warnings : Warnings_State;
-- Capture values of warning flags
end record;
diff --git a/gcc/ada/layout.adb b/gcc/ada/layout.adb
index e4187dd..b352c06 100644
--- a/gcc/ada/layout.adb
+++ b/gcc/ada/layout.adb
@@ -40,6 +40,7 @@ with Sinfo.Utils; use Sinfo.Utils;
with Snames; use Snames;
with Ttypes; use Ttypes;
with Uintp; use Uintp;
+with Warnsw; use Warnsw;
package body Layout is
@@ -500,7 +501,7 @@ package body Layout is
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 No (Packed_Array_Impl_Type (E))
and then Has_Pragma_Pack (E)
and then Is_Constrained (E)
and then Compile_Time_Known_Bounds (E)
diff --git a/gcc/ada/lib-xref.adb b/gcc/ada/lib-xref.adb
index 043444c..182ea2f 100644
--- a/gcc/ada/lib-xref.adb
+++ b/gcc/ada/lib-xref.adb
@@ -47,6 +47,7 @@ with Snames; use Snames;
with Stringt; use Stringt;
with Stand; use Stand;
with Table; use Table;
+with Warnsw; use Warnsw;
with GNAT.Heap_Sort_G;
with GNAT.HTable;
@@ -775,7 +776,7 @@ package body Lib.Xref is
Set_Referenced_As_LHS (E, False);
-- For OUT parameter not covered by the above cases, we simply
- -- regard it as a non-reference.
+ -- regard it as a reference.
else
Set_Referenced_As_Out_Parameter (E);
@@ -1271,10 +1272,10 @@ package body Lib.Xref is
XE : Xref_Entry renames Xrefs.Table (F);
type M is mod 2**32;
- H : constant M := M (XE.Key.Ent) + 2 ** 7 * M (abs XE.Key.Loc);
+ H : constant M := 3 * M (XE.Key.Ent) + 5 * M (abs XE.Key.Loc);
-- It would be more natural to write:
--
- -- H : constant M := M'Mod (XE.Key.Ent) + 2**7 * M'Mod (XE.Key.Loc);
+ -- H : constant M := 3 * M'Mod (XE.Key.Ent) + 5 * M'Mod (XE.Key.Loc);
--
-- But we can't use M'Mod, because it prevents bootstrapping with older
-- compilers. Loc can be negative, so we do "abs" before converting.
diff --git a/gcc/ada/libgnarl/s-interr.adb b/gcc/ada/libgnarl/s-interr.adb
index a3d28d6..2fbb140 100644
--- a/gcc/ada/libgnarl/s-interr.adb
+++ b/gcc/ada/libgnarl/s-interr.adb
@@ -54,27 +54,22 @@
with Ada.Exceptions;
with Ada.Task_Identification;
+with Ada.Unchecked_Conversion;
-with System.Task_Primitives;
with System.Interrupt_Management;
-
with System.Interrupt_Management.Operations;
-pragma Elaborate_All (System.Interrupt_Management.Operations);
-
with System.IO;
-
+with System.Parameters;
+with System.Task_Primitives;
with System.Task_Primitives.Operations;
with System.Task_Primitives.Interrupt_Operations;
with System.Storage_Elements;
+with System.Tasking.Initialization;
with System.Tasking.Utilities;
-
with System.Tasking.Rendezvous;
-pragma Elaborate_All (System.Tasking.Rendezvous);
-with System.Tasking.Initialization;
-with System.Parameters;
-
-with Ada.Unchecked_Conversion;
+pragma Elaborate_All (System.Interrupt_Management.Operations);
+pragma Elaborate_All (System.Tasking.Rendezvous);
package body System.Interrupts is
@@ -114,8 +109,8 @@ package body System.Interrupts is
Static : Boolean);
entry Detach_Handler
- (Interrupt : Interrupt_ID;
- Static : Boolean);
+ (Interrupt : Interrupt_ID;
+ Static : Boolean);
entry Bind_Interrupt_To_Entry
(T : Task_Id;
@@ -179,15 +174,14 @@ package body System.Interrupts is
pragma Atomic_Components (Ignored);
-- True iff the corresponding interrupt is blocked in the process level
- Last_Unblocker :
- array (Interrupt_ID'Range) of Task_Id := [others => Null_Task];
+ Last_Unblocker : array (Interrupt_ID'Range) of Task_Id :=
+ [others => Null_Task];
pragma Atomic_Components (Last_Unblocker);
-- Holds the ID of the last Task which Unblocked this Interrupt. It
-- contains Null_Task if no tasks have ever requested the Unblocking
-- operation or the Interrupt is currently Blocked.
- Server_ID : array (Interrupt_ID'Range) of Task_Id :=
- [others => Null_Task];
+ Server_ID : array (Interrupt_ID'Range) of Task_Id := [others => Null_Task];
pragma Atomic_Components (Server_ID);
-- Holds the Task_Id of the Server_Task for each interrupt. Task_Id is
-- needed to accomplish locking per Interrupt base. Also is needed to
diff --git a/gcc/ada/libgnat/a-ngcoar.adb b/gcc/ada/libgnat/a-ngcoar.adb
index 8dfbc3b..1b9118c 100644
--- a/gcc/ada/libgnat/a-ngcoar.adb
+++ b/gcc/ada/libgnat/a-ngcoar.adb
@@ -902,7 +902,7 @@ package body Ada.Numerics.Generic_Complex_Arrays is
function "-"
(Left : Real_Vector;
Right : Complex_Vector) return Complex_Vector
- renames Instantiations."-";
+ renames Instantiations."-";
function "-"
(Left : Complex_Vector;
@@ -956,7 +956,7 @@ package body Ada.Numerics.Generic_Complex_Arrays is
-----------
function "abs" (Right : Complex_Vector) return Real'Base
- renames Instantiations."abs";
+ renames Instantiations."abs";
--------------
-- Argument --
diff --git a/gcc/ada/libgnat/a-ngcoar.ads b/gcc/ada/libgnat/a-ngcoar.ads
index 8f8f37a..05295ca 100644
--- a/gcc/ada/libgnat/a-ngcoar.ads
+++ b/gcc/ada/libgnat/a-ngcoar.ads
@@ -135,7 +135,7 @@ package Ada.Numerics.Generic_Complex_Arrays is
function Compose_From_Cartesian (Re : Real_Matrix) return Complex_Matrix;
function Compose_From_Cartesian
- (Re, Im : Real_Matrix) return Complex_Matrix;
+ (Re, Im : Real_Matrix) return Complex_Matrix;
function Modulus (X : Complex_Matrix) return Real_Matrix;
function "abs" (Right : Complex_Matrix) return Real_Matrix renames Modulus;
@@ -229,7 +229,7 @@ package Ada.Numerics.Generic_Complex_Arrays is
function "*"
(Left : Complex;
- Right : Complex_Matrix) return Complex_Matrix;
+ Right : Complex_Matrix) return Complex_Matrix;
function "*"
(Left : Complex_Matrix;
diff --git a/gcc/ada/libgnat/a-strsup.adb b/gcc/ada/libgnat/a-strsup.adb
index 831a18e..0210b45 100644
--- a/gcc/ada/libgnat/a-strsup.adb
+++ b/gcc/ada/libgnat/a-strsup.adb
@@ -303,6 +303,17 @@ package body Ada.Strings.Superbounded with SPARK_Mode is
return Left <= Super_To_String (Right);
end Less_Or_Equal;
+ ---------------
+ -- Put_Image --
+ ---------------
+
+ procedure Put_Image
+ (S : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class;
+ Source : Super_String) is
+ begin
+ String'Put_Image (S, Super_To_String (Source));
+ end Put_Image;
+
----------------------
-- Set_Super_String --
----------------------
diff --git a/gcc/ada/libgnat/a-strsup.ads b/gcc/ada/libgnat/a-strsup.ads
index 416fa7b..600f097 100644
--- a/gcc/ada/libgnat/a-strsup.ads
+++ b/gcc/ada/libgnat/a-strsup.ads
@@ -49,6 +49,7 @@ pragma Assertion_Policy (Pre => Ignore,
with Ada.Strings.Maps; use type Ada.Strings.Maps.Character_Mapping_Function;
with Ada.Strings.Search;
+with Ada.Strings.Text_Buffers;
package Ada.Strings.Superbounded with SPARK_Mode is
pragma Preelaborate;
@@ -69,7 +70,8 @@ package Ada.Strings.Superbounded with SPARK_Mode is
with
Predicate =>
Current_Length <= Max_Length
- and then Data (1 .. Current_Length)'Initialized;
+ and then Data (1 .. Current_Length)'Initialized,
+ Put_Image => Put_Image;
-- The subprograms defined for Super_String are similar to those
-- defined for Bounded_String, except that they have different names, so
@@ -2695,6 +2697,10 @@ package Ada.Strings.Superbounded with SPARK_Mode is
- (Item.Max_Length - K) mod Super_Length (Item)))),
Global => null;
+ procedure Put_Image
+ (S : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class;
+ Source : Super_String);
+
private
-- Pragma Inline declarations
diff --git a/gcc/ada/libgnat/a-sttebu.adb b/gcc/ada/libgnat/a-sttebu.adb
index d992fee..acca292 100644
--- a/gcc/ada/libgnat/a-sttebu.adb
+++ b/gcc/ada/libgnat/a-sttebu.adb
@@ -29,6 +29,7 @@
-- --
------------------------------------------------------------------------------
+with Ada.Strings.UTF_Encoding.Strings;
with Ada.Strings.UTF_Encoding.Wide_Strings;
with Ada.Strings.UTF_Encoding.Wide_Wide_Strings;
@@ -59,7 +60,7 @@ package body Ada.Strings.Text_Buffers is
procedure Put (Buffer : in out Buffer_Type; Item : String) is
begin
- Put_UTF_8 (Buffer, Item);
+ Put_UTF_8 (Buffer, UTF_Encoding.Strings.Encode (Item));
end Put;
procedure Wide_Put (Buffer : in out Buffer_Type; Item : Wide_String) is
diff --git a/gcc/ada/libgnat/a-stwisu.adb b/gcc/ada/libgnat/a-stwisu.adb
index d325676..cf27ca9 100644
--- a/gcc/ada/libgnat/a-stwisu.adb
+++ b/gcc/ada/libgnat/a-stwisu.adb
@@ -297,6 +297,17 @@ package body Ada.Strings.Wide_Superbounded is
return Left <= Right.Data (1 .. Right.Current_Length);
end Less_Or_Equal;
+ ---------------
+ -- Put_Image --
+ ---------------
+
+ procedure Put_Image
+ (S : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class;
+ Source : Super_String) is
+ begin
+ Wide_String'Put_Image (S, Super_To_String (Source));
+ end Put_Image;
+
----------------------
-- Set_Super_String --
----------------------
diff --git a/gcc/ada/libgnat/a-stwisu.ads b/gcc/ada/libgnat/a-stwisu.ads
index c22c2a2..7437cbd 100644
--- a/gcc/ada/libgnat/a-stwisu.ads
+++ b/gcc/ada/libgnat/a-stwisu.ads
@@ -37,6 +37,7 @@
-- Strings.Wide_Bounded.Generic_Bounded_Length use this type with
-- an appropriate discriminant value set.
+with Ada.Strings.Text_Buffers;
with Ada.Strings.Wide_Maps;
package Ada.Strings.Wide_Superbounded is
@@ -54,7 +55,8 @@ package Ada.Strings.Wide_Superbounded is
-- no longer necessary, because we now special-case this type in the
-- compiler, so "=" composes properly for descendants of this type.
-- Leaving it out is more efficient.
- end record;
+ end record
+ with Put_Image => Put_Image;
-- The subprograms defined for Super_String are similar to those defined
-- for Bounded_Wide_String, except that they have different names, so that
@@ -477,6 +479,10 @@ package Ada.Strings.Wide_Superbounded is
Item : Super_String;
Drop : Truncation := Error) return Super_String;
+ procedure Put_Image
+ (S : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class;
+ Source : Super_String);
+
private
-- Pragma Inline declarations
diff --git a/gcc/ada/libgnat/a-stzsup.adb b/gcc/ada/libgnat/a-stzsup.adb
index 6153bbe..a4fa996 100644
--- a/gcc/ada/libgnat/a-stzsup.adb
+++ b/gcc/ada/libgnat/a-stzsup.adb
@@ -297,6 +297,17 @@ package body Ada.Strings.Wide_Wide_Superbounded is
return Left <= Right.Data (1 .. Right.Current_Length);
end Less_Or_Equal;
+ ---------------
+ -- Put_Image --
+ ---------------
+
+ procedure Put_Image
+ (S : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class;
+ Source : Super_String) is
+ begin
+ Wide_Wide_String'Put_Image (S, Super_To_String (Source));
+ end Put_Image;
+
----------------------
-- Set_Super_String --
----------------------
diff --git a/gcc/ada/libgnat/a-stzsup.ads b/gcc/ada/libgnat/a-stzsup.ads
index 148b972..b50d21a 100644
--- a/gcc/ada/libgnat/a-stzsup.ads
+++ b/gcc/ada/libgnat/a-stzsup.ads
@@ -37,6 +37,7 @@
-- Strings.Wide_Wide_Bounded.Generic_Bounded_Length use this type with
-- an appropriate discriminant value set.
+with Ada.Strings.Text_Buffers;
with Ada.Strings.Wide_Wide_Maps;
package Ada.Strings.Wide_Wide_Superbounded is
@@ -55,7 +56,8 @@ package Ada.Strings.Wide_Wide_Superbounded is
-- no longer necessary, because we now special-case this type in the
-- compiler, so "=" composes properly for descendants of this type.
-- Leaving it out is more efficient.
- end record;
+ end record
+ with Put_Image => Put_Image;
-- The subprograms defined for Super_String are similar to those defined
-- for Bounded_Wide_Wide_String, except that they have different names, so
@@ -486,6 +488,10 @@ package Ada.Strings.Wide_Wide_Superbounded is
Item : Super_String;
Drop : Truncation := Error) return Super_String;
+ procedure Put_Image
+ (S : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class;
+ Source : Super_String);
+
private
-- Pragma Inline declarations
diff --git a/gcc/ada/libgnat/a-tags.adb b/gcc/ada/libgnat/a-tags.adb
index d663a41..a9af942 100644
--- a/gcc/ada/libgnat/a-tags.adb
+++ b/gcc/ada/libgnat/a-tags.adb
@@ -554,13 +554,18 @@ package body Ada.Tags is
-----------------------------
function Interface_Ancestor_Tags (T : Tag) return Tag_Array is
- TSD_Ptr : constant Addr_Ptr :=
- To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
- TSD : constant Type_Specific_Data_Ptr :=
- To_Type_Specific_Data_Ptr (TSD_Ptr.all);
- Iface_Table : constant Interface_Data_Ptr := TSD.Interfaces_Table;
-
+ TSD_Ptr : Addr_Ptr;
+ TSD : Type_Specific_Data_Ptr;
+ Iface_Table : Interface_Data_Ptr;
begin
+ if T = No_Tag then
+ raise Tag_Error;
+ end if;
+
+ TSD_Ptr := To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
+ TSD := To_Type_Specific_Data_Ptr (TSD_Ptr.all);
+ Iface_Table := TSD.Interfaces_Table;
+
if Iface_Table = null then
declare
Table : Tag_Array (1 .. 0);
@@ -731,7 +736,10 @@ package body Ada.Tags is
Ancestor : Tag) return Boolean
is
begin
- if Descendant = Ancestor then
+ if Descendant = No_Tag or else Ancestor = No_Tag then
+ raise Tag_Error;
+
+ elsif Descendant = Ancestor then
return True;
else
diff --git a/gcc/ada/libgnat/g-excact.ads b/gcc/ada/libgnat/g-excact.ads
index 1101546..c2e0b30 100644
--- a/gcc/ada/libgnat/g-excact.ads
+++ b/gcc/ada/libgnat/g-excact.ads
@@ -71,8 +71,7 @@ package GNAT.Exception_Actions is
-- If Action is null, this will in effect cancel all exception actions.
procedure Register_Global_Unhandled_Action (Action : Exception_Action);
- -- Similar to Register_Global_Action, called on unhandled exceptions
- -- only.
+ -- Similar to Register_Global_Action, called on unhandled exceptions only
procedure Register_Id_Action
(Id : Exception_Id;
@@ -90,7 +89,7 @@ package GNAT.Exception_Actions is
-- an exception that is declared within an unlabeled block.
--
-- Note: All non-predefined exceptions will return Null_Id for programs
- -- compiled with pragma Restriction (No_Exception_Registration)
+ -- compiled with pragma Restrictions (No_Exception_Registration).
function Is_Foreign_Exception (E : Exception_Occurrence) return Boolean;
-- Tell whether the exception occurrence E represents a foreign exception,
diff --git a/gcc/ada/libgnat/g-souinf.ads b/gcc/ada/libgnat/g-souinf.ads
index 700f518..6b72a64 100644
--- a/gcc/ada/libgnat/g-souinf.ads
+++ b/gcc/ada/libgnat/g-souinf.ads
@@ -36,7 +36,13 @@
-- and logging purposes. For example, an exception handler can print out
-- the name of the source file in which the exception is handled.
-package GNAT.Source_Info is
+package GNAT.Source_Info with
+ SPARK_Mode,
+ Abstract_State =>
+ (Source_Code_Information with
+ External => (Async_Writers, Async_Readers)),
+ Annotate => (GNATprove, Always_Return)
+is
pragma Preelaborate;
-- Note that this unit is Preelaborate, but not Pure, that's because the
-- functions here such as Line are clearly not pure functions, and normally
@@ -47,6 +53,8 @@ package GNAT.Source_Info is
-- intrinsics as not Pure, even in Pure units, so no problems arose.
function File return String with
+ Volatile_Function,
+ Global => Source_Code_Information,
Import, Convention => Intrinsic;
-- Return the name of the current file, not including the path information.
-- The result is considered to be a static string constant.
@@ -57,6 +65,8 @@ package GNAT.Source_Info is
-- static expression.
function Source_Location return String with
+ Volatile_Function,
+ Global => Source_Code_Information,
Import, Convention => Intrinsic;
-- Return a string literal of the form "name:line", where name is the
-- current source file name without path information, and line is the
@@ -66,6 +76,8 @@ package GNAT.Source_Info is
-- string constant.
function Enclosing_Entity return String with
+ Volatile_Function,
+ Global => Source_Code_Information,
Import, Convention => Intrinsic;
-- Return the name of the current subprogram, package, task, entry or
-- protected subprogram. The string is in exactly the form used for the
@@ -80,15 +92,21 @@ package GNAT.Source_Info is
-- from within generic templates.
function Compilation_ISO_Date return String with
+ Volatile_Function,
+ Global => Source_Code_Information,
Import, Convention => Intrinsic;
-- Returns date of compilation as a static string "yyyy-mm-dd".
function Compilation_Date return String with
+ Volatile_Function,
+ Global => Source_Code_Information,
Import, Convention => Intrinsic;
-- Returns date of compilation as a static string "mmm dd yyyy". This is
-- in local time form, and is exactly compatible with C macro __DATE__.
function Compilation_Time return String with
+ Volatile_Function,
+ Global => Source_Code_Information,
Import, Convention => Intrinsic;
-- Returns GMT time of compilation as a static string "hh:mm:ss". This is
-- in local time form, and is exactly compatible with C macro __TIME__.
diff --git a/gcc/ada/libgnat/g-traceb.ads b/gcc/ada/libgnat/g-traceb.ads
index 074b7a6..163201c 100644
--- a/gcc/ada/libgnat/g-traceb.ads
+++ b/gcc/ada/libgnat/g-traceb.ads
@@ -38,38 +38,36 @@
-- The traceback information is in the form of absolute code locations.
-- These code locations may be converted to corresponding source locations
--- using the external addr2line utility, or from within GDB.
+-- using the addr2line or gnatsymbolize utilities, or from within GDB.
-- In order to use this facility, in some cases the binder must be invoked
-- with -E switch (store the backtrace with exception occurrence). Please
-- refer to gnatbind documentation for more information.
--- To analyze the code locations later using addr2line or gdb, the necessary
--- units must be compiled with the debugging switch -g in the usual manner.
--- Note that it is not necessary to compile with -g to use Call_Chain. In
--- other words, the following sequence of steps can be used:
+-- To analyze the code locations later using addr2line, gnatsymbolize or GDB,
+-- the necessary units must be compiled with the debugging switch -g in the
+-- usual manner. Note that it is not necessary to compile with -g to use
+-- Call_Chain. In other words, the following sequence of steps can be used:
-- Compile without -g
-- Run the program, and call Call_Chain
-- Recompile with -g
--- Use addr2line to interpret the absolute call locations (note that
--- addr2line expects addresses in hexadecimal format).
+-- Use addr2line or gnatsymbolize to interpret the absolute call locations
+-- (note that addr2line expects addresses in hexadecimal format).
-- This capability is currently supported on the following targets:
--- AiX PowerPC
+-- AIX PowerPC
-- GNU/Linux x86
-- GNU/Linux PowerPC
-- LynxOS x86
--- LynxOS 178 xcoff PowerPC
--- LynxOS 178 elf PowerPC
+-- LynxOS-178 PowerPC
-- Solaris x86
--- Solaris sparc
+-- Solaris SPARC
-- VxWorks ARM
--- VxWorks7 ARM
-- VxWorks PowerPC
-- VxWorks x86
--- Windows XP
+-- Windows
-- Note: see also GNAT.Traceback.Symbolic, a child unit in file g-trasym.ads
-- providing symbolic trace back capability for a subset of the above targets.
@@ -101,11 +99,21 @@ package GNAT.Traceback is
function Call_Chain
(Max_Len : Positive;
Skip_Frames : Natural := 1) return Tracebacks_Array;
- -- Returns up to Max_Len tracebacks corresponding to the current call
+ -- Return up to Max_Len tracebacks corresponding to the current call
-- chain. Result array order is the same as in above procedure Call_Chain
-- except that Skip_Frames says how many of the most recent calls should be
-- excluded from the result, starting with this procedure itself: 1 means
-- exclude the frame for this procedure, 2 means 1 + exclude the frame for
-- this procedure's caller, ...
+ function Executable_Load_Address return System.Address;
+ pragma Import (C,
+ Executable_Load_Address,
+ "__gnat_get_executable_load_address");
+ -- Return the load address of the executable or System.Null_Address if the
+ -- executable has been loaded at the address computed by the static linker.
+ -- This address is needed to interpret the absolute call locations given by
+ -- the subprograms of this unit when Position-Independent Executables (PIE)
+ -- are used on recent GNU/Linux and Windows versions.
+
end GNAT.Traceback;
diff --git a/gcc/ada/libgnat/i-c.adb b/gcc/ada/libgnat/i-c.adb
index 4b50d18..2866021 100644
--- a/gcc/ada/libgnat/i-c.adb
+++ b/gcc/ada/libgnat/i-c.adb
@@ -186,7 +186,7 @@ is
(Item : char_array;
Trim_Nul : Boolean := True) return String
is
- Count : Natural;
+ Count : Natural := 0;
From : size_t;
begin
@@ -1177,7 +1177,7 @@ is
To : size_t;
begin
- if Target'Length < Item'Length then
+ if Target'Length < Item'Length + (if Append_Nul then 1 else 0) then
raise Constraint_Error;
else
@@ -1210,17 +1210,14 @@ is
Target'First + (Item'Length - 1))'Initialized);
if Append_Nul then
- if To > Target'Last then
- raise Constraint_Error;
- else
- Target (To) := char32_nul;
- Count := Item'Length + 1;
- end if;
-
+ Target (To) := char32_nul;
+ Count := Item'Length + 1;
else
Count := Item'Length;
end if;
end if;
end To_C;
+ pragma Annotate (CodePeer, False_Positive, "validity check",
+ "Count is only uninitialized on abnormal return.");
end Interfaces.C;
diff --git a/gcc/ada/libgnat/s-regpat.adb b/gcc/ada/libgnat/s-regpat.adb
index 3290f90..3e9f880 100644
--- a/gcc/ada/libgnat/s-regpat.adb
+++ b/gcc/ada/libgnat/s-regpat.adb
@@ -920,18 +920,16 @@ package body System.Regpat is
if Capturing then
Ender := Emit_Node (CLOSE);
Emit (Character'Val (Par_No));
- Link_Tail (IP, Ender);
-
else
- -- Need to keep looking after the closing parenthesis
- Ender := Emit_Ptr;
+ Ender := Emit_Node (NOTHING);
end if;
else
Ender := Emit_Node (EOP);
- Link_Tail (IP, Ender);
end if;
+ Link_Tail (IP, Ender);
+
if Have_Branch and then Emit_Ptr <= PM.Size + 1 then
-- Hook the tails of the branches to the closing node
diff --git a/gcc/ada/libgnat/s-rident.ads b/gcc/ada/libgnat/s-rident.ads
index 9d652a4..1c6f2e7 100644
--- a/gcc/ada/libgnat/s-rident.ads
+++ b/gcc/ada/libgnat/s-rident.ads
@@ -107,7 +107,7 @@ package System.Rident is
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_CPU_Assignment, -- Ada 2022 (RM D.7(10/3))
No_Dynamic_Priorities, -- (RM D.9(9))
No_Enumeration_Maps, -- GNAT
No_Entry_Calls_In_Elaboration_Code, -- GNAT
@@ -152,8 +152,9 @@ package System.Rident is
No_Task_Attributes_Package, -- GNAT
No_Task_At_Interrupt_Priority, -- GNAT
No_Task_Hierarchy, -- (RM D.7(3), H.4(3))
+ No_Task_Hierarchy_Implicit, -- GNAT
No_Task_Termination, -- Ada 2005 (D.7(15.1/2))
- No_Tasks_Unassigned_To_CPU, -- Ada 202x (D.7(10.10/4))
+ No_Tasks_Unassigned_To_CPU, -- Ada 2022 (D.7(10.10/4))
No_Tasking, -- GNAT
No_Terminate_Alternatives, -- (RM D.7(6))
No_Unchecked_Access, -- (RM H.4(18))
diff --git a/gcc/ada/libgnat/system-qnx-arm.ads b/gcc/ada/libgnat/system-qnx-arm.ads
index 038fe6c..749384f 100644
--- a/gcc/ada/libgnat/system-qnx-arm.ads
+++ b/gcc/ada/libgnat/system-qnx-arm.ads
@@ -142,7 +142,7 @@ private
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
+ Support_Atomic_Primitives : constant Boolean := True;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
diff --git a/gcc/ada/libgnat/system-rtems.ads b/gcc/ada/libgnat/system-rtems.ads
index 5959b72..52ee299 100644
--- a/gcc/ada/libgnat/system-rtems.ads
+++ b/gcc/ada/libgnat/system-rtems.ads
@@ -150,6 +150,7 @@ private
Stack_Check_Probes : constant Boolean := False;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
+ Support_Atomic_Primitives : constant Boolean := True;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
diff --git a/gcc/ada/libgnat/system-vxworks7-aarch64-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks7-aarch64-rtp-smp.ads
index ae67cd0..46b740e 100644
--- a/gcc/ada/libgnat/system-vxworks7-aarch64-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-aarch64-rtp-smp.ads
@@ -151,7 +151,7 @@ private
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
+ Support_Atomic_Primitives : constant Boolean := True;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
diff --git a/gcc/ada/libgnat/system-vxworks7-aarch64.ads b/gcc/ada/libgnat/system-vxworks7-aarch64.ads
index a943ecd..1aba15b 100644
--- a/gcc/ada/libgnat/system-vxworks7-aarch64.ads
+++ b/gcc/ada/libgnat/system-vxworks7-aarch64.ads
@@ -148,7 +148,7 @@ private
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
+ Support_Atomic_Primitives : constant Boolean := True;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
diff --git a/gcc/ada/libgnat/system-vxworks7-arm-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks7-arm-rtp-smp.ads
index 49e6e7a..e81348e 100644
--- a/gcc/ada/libgnat/system-vxworks7-arm-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-arm-rtp-smp.ads
@@ -148,7 +148,7 @@ private
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
+ Support_Atomic_Primitives : constant Boolean := True;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
diff --git a/gcc/ada/libgnat/system-vxworks7-arm.ads b/gcc/ada/libgnat/system-vxworks7-arm.ads
index 6d3218f4..4ced0f1 100644
--- a/gcc/ada/libgnat/system-vxworks7-arm.ads
+++ b/gcc/ada/libgnat/system-vxworks7-arm.ads
@@ -146,7 +146,7 @@ private
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
+ Support_Atomic_Primitives : constant Boolean := True;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
diff --git a/gcc/ada/libgnat/system-vxworks7-ppc-kernel.ads b/gcc/ada/libgnat/system-vxworks7-ppc-kernel.ads
index bddf951..ef290c0 100644
--- a/gcc/ada/libgnat/system-vxworks7-ppc-kernel.ads
+++ b/gcc/ada/libgnat/system-vxworks7-ppc-kernel.ads
@@ -146,6 +146,7 @@ private
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
+ Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
diff --git a/gcc/ada/libgnat/system-vxworks7-ppc-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks7-ppc-rtp-smp.ads
index 3ead193..5bab2e8 100644
--- a/gcc/ada/libgnat/system-vxworks7-ppc-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-ppc-rtp-smp.ads
@@ -151,6 +151,7 @@ private
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
+ Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
diff --git a/gcc/ada/libgnat/system-vxworks7-ppc64-kernel.ads b/gcc/ada/libgnat/system-vxworks7-ppc64-kernel.ads
index a1a983b..768fbee 100644
--- a/gcc/ada/libgnat/system-vxworks7-ppc64-kernel.ads
+++ b/gcc/ada/libgnat/system-vxworks7-ppc64-kernel.ads
@@ -148,6 +148,7 @@ private
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
+ Support_Atomic_Primitives : constant Boolean := True;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
diff --git a/gcc/ada/libgnat/system-vxworks7-ppc64-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks7-ppc64-rtp-smp.ads
index afdd820..75abe4c 100644
--- a/gcc/ada/libgnat/system-vxworks7-ppc64-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-ppc64-rtp-smp.ads
@@ -151,6 +151,7 @@ private
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
+ Support_Atomic_Primitives : constant Boolean := True;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
diff --git a/gcc/ada/libgnat/system-vxworks7-x86-kernel.ads b/gcc/ada/libgnat/system-vxworks7-x86-kernel.ads
index e34c22a..42ae983 100644
--- a/gcc/ada/libgnat/system-vxworks7-x86-kernel.ads
+++ b/gcc/ada/libgnat/system-vxworks7-x86-kernel.ads
@@ -146,7 +146,7 @@ private
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
+ Support_Atomic_Primitives : constant Boolean := True;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
diff --git a/gcc/ada/libgnat/system-vxworks7-x86-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks7-x86-rtp-smp.ads
index 68ca423..47dd3ae 100644
--- a/gcc/ada/libgnat/system-vxworks7-x86-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-x86-rtp-smp.ads
@@ -149,7 +149,7 @@ private
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
+ Support_Atomic_Primitives : constant Boolean := True;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
diff --git a/gcc/ada/libgnat/system-vxworks7-x86_64-kernel.ads b/gcc/ada/libgnat/system-vxworks7-x86_64-kernel.ads
index 6504a02..7931241 100644
--- a/gcc/ada/libgnat/system-vxworks7-x86_64-kernel.ads
+++ b/gcc/ada/libgnat/system-vxworks7-x86_64-kernel.ads
@@ -146,7 +146,7 @@ private
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
+ Support_Atomic_Primitives : constant Boolean := True;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
diff --git a/gcc/ada/libgnat/system-vxworks7-x86_64-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks7-x86_64-rtp-smp.ads
index ffcc78f..3c98b4c 100644
--- a/gcc/ada/libgnat/system-vxworks7-x86_64-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-x86_64-rtp-smp.ads
@@ -149,7 +149,7 @@ private
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
+ Support_Atomic_Primitives : constant Boolean := True;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
diff --git a/gcc/ada/mdll.adb b/gcc/ada/mdll.adb
index 2107994..88f8f96 100644
--- a/gcc/ada/mdll.adb
+++ b/gcc/ada/mdll.adb
@@ -448,57 +448,41 @@ package body MDLL is
(Lib_Filename : String;
Def_Filename : String)
is
- procedure Build_Import_Library (Lib_Filename : String);
- -- Build an import library. This is to build only a .a library to link
- -- against a DLL.
+ function Strip_Lib_Prefix (Filename : String) return String;
+ -- Return Filename without the lib prefix if present
- --------------------------
- -- Build_Import_Library --
- --------------------------
-
- procedure Build_Import_Library (Lib_Filename : String) is
-
- function No_Lib_Prefix (Filename : String) return String;
- -- Return Filename without the lib prefix if present
-
- -------------------
- -- No_Lib_Prefix --
- -------------------
-
- function No_Lib_Prefix (Filename : String) return String is
- begin
- if Filename (Filename'First .. Filename'First + 2) = "lib" then
- return Filename (Filename'First + 3 .. Filename'Last);
- else
- return Filename;
- end if;
- end No_Lib_Prefix;
-
- -- Local variables
-
- Def_File : String renames Def_Filename;
- Dll_File : constant String := Get_Dll_Name (Lib_Filename);
- Base_Filename : constant String :=
- MDLL.Fil.Ext_To (No_Lib_Prefix (Lib_Filename));
- Lib_File : constant String := "lib" & Base_Filename & ".dll.a";
-
- -- Start of processing for Build_Import_Library
+ ----------------------
+ -- Strip_Lib_Prefix --
+ ----------------------
+ function Strip_Lib_Prefix (Filename : String) return String is
begin
- if not Quiet then
- Text_IO.Put_Line ("Building import library...");
- Text_IO.Put_Line
- ("make " & Lib_File & " to use dynamic library " & Dll_File);
+ if Filename (Filename'First .. Filename'First + 2) = "lib" then
+ return Filename (Filename'First + 3 .. Filename'Last);
+ else
+ return Filename;
end if;
+ end Strip_Lib_Prefix;
- Utl.Dlltool
- (Def_File, Dll_File, Lib_File, Build_Import => True);
- end Build_Import_Library;
+ -- Local variables
+
+ Def_File : String renames Def_Filename;
+ Dll_File : constant String := Get_Dll_Name (Lib_Filename);
+ Base_Filename : constant String :=
+ MDLL.Fil.Ext_To (Strip_Lib_Prefix (Lib_Filename));
+ Lib_File : constant String := "lib" & Base_Filename & ".dll.a";
-- Start of processing for Build_Import_Library
begin
- Build_Import_Library (Lib_Filename);
+ if not Quiet then
+ Text_IO.Put_Line ("Building import library...");
+ Text_IO.Put_Line
+ ("make " & Lib_File & " to use dynamic library " & Dll_File);
+ end if;
+
+ Utl.Dlltool
+ (Def_File, Dll_File, Lib_File, Build_Import => True);
end Build_Import_Library;
------------------
diff --git a/gcc/ada/mdll.ads b/gcc/ada/mdll.ads
index 110eb31..9f080c0 100644
--- a/gcc/ada/mdll.ads
+++ b/gcc/ada/mdll.ads
@@ -74,7 +74,7 @@ package MDLL is
procedure Build_Import_Library
(Lib_Filename : String;
Def_Filename : String);
- -- Build an import library (.a) from a definition files. An import library
- -- is needed to link against a DLL.
+ -- Build an import library (.a) from definition files. An import library is
+ -- needed to link against a DLL.
end MDLL;
diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads
index 8f903ca..2ae9dd9 100644
--- a/gcc/ada/opt.ads
+++ b/gcc/ada/opt.ads
@@ -73,15 +73,16 @@ package Opt is
-- Ada_xxx) or generate an error (in case of -gnat83/95/xx switches).
type Ada_Version_Type is
- (Ada_83, Ada_95, Ada_2005, Ada_2012, Ada_2022, Ada_With_Extensions);
+ (Ada_83, Ada_95, Ada_2005, Ada_2012, Ada_2022,
+ Ada_With_Core_Extensions, Ada_With_All_Extensions);
pragma Ordered (Ada_Version_Type);
pragma Convention (C, Ada_Version_Type);
-- Versions of Ada for Ada_Version below. Note that these are ordered,
-- so that tests like Ada_Version >= Ada_95 are legitimate and useful.
-- Think twice before using "="; Ada_Version >= Ada_2012 is more likely
-- what you want, because it will apply to future versions of the language.
- -- Note that Ada_With_Extensions should always be last since it should
- -- always be a superset of the latest Ada version.
+ -- Note that Ada_With_All_Extensions should always be last since it should
+ -- always be a superset of the other Ada versions.
-- WARNING: There is a matching C declaration of this type in fe.h
@@ -111,7 +112,7 @@ package Opt is
-- remains set to Ada_Version_Default). This is used in the rare cases
-- (notably pragma Obsolescent) where we want the explicit version set.
- Ada_Version_Runtime : Ada_Version_Type := Ada_With_Extensions;
+ Ada_Version_Runtime : Ada_Version_Type := Ada_With_All_Extensions;
-- GNAT
-- Ada version used to compile the runtime. Used to set Ada_Version (but
-- not Ada_Version_Explicit) when compiling predefined or internal units.
@@ -140,11 +141,6 @@ package Opt is
-- The name of the Ada package generated by the binder (when in Ada mode).
-- This variable may be modified by Gnatbind.Scan_Bind_Arg.
- Address_Clause_Overlay_Warnings : Boolean := True;
- -- GNAT
- -- Set False to disable address clause warnings. Modified by use of
- -- -gnatwo/O.
-
Address_Is_Private : Boolean := False;
-- GNAT, GNATBIND
-- Set True if package System has the line "type Address is private;"
@@ -316,28 +312,11 @@ package Opt is
-- GNATMAKE, GPBUILD
-- Set to True to check compiler options during the make process
- Check_Unreferenced : Boolean := False;
- -- GNAT
- -- Set to True to enable checking for unreferenced entities other
- -- than formal parameters (for which see Check_Unreferenced_Formals)
- -- Modified by use of -gnatwu/U.
-
- Check_Unreferenced_Formals : Boolean := False;
- -- GNAT
- -- Set to True to check for unreferenced formals. This is turned on by
- -- -gnatwa/wf/wu and turned off by -gnatwA/wF/wU.
-
Check_Validity_Of_Parameters : Boolean := False;
-- GNAT
-- Set to True to check for proper scalar initialization of subprogram
-- parameters on both entry and exit. This is turned on by -gnateV.
- Check_Withs : Boolean := False;
- -- GNAT
- -- Set to True to enable checking for unused withs, and also the case
- -- of withing a package and using none of the entities in the package.
- -- Modified by use of -gnatwu/U.
-
CodePeer_Mode : Boolean := False;
-- GNAT, GNATBIND, GPRBUILD
-- Enable full CodePeer mode (SCIL generation, disable switches that
@@ -384,16 +363,15 @@ package Opt is
-- True, or if pragma No_Run_Time is used. See the spec of Rtsfind for
-- details on the handling of the latter pragma.
- Constant_Condition_Warnings : Boolean := False;
- -- GNAT
- -- Set to True to activate warnings on constant conditions. Modified by
- -- use of -gnatwc/C.
-
Create_Mapping_File : Boolean := False;
-- GNATMAKE
-- Set to True (-C switch) to indicate that the compiler will be invoked
-- with a mapping file (-gnatem compiler switch).
+ CUDA_Device_Library_Name : String_Ptr := null;
+ -- GNATBIND
+ -- Non-null only if Enable_CUDA_Expansion is True.
+
subtype Debug_Level_Value is Nat range 0 .. 3;
Debugger_Level : Debug_Level_Value := 0;
-- GNAT, GNATBIND
@@ -520,18 +498,6 @@ package Opt is
-- GNATBIND
-- Set to True to output chosen elaboration order
- Elab_Info_Messages : Boolean := False;
- -- GNAT
- -- Set to True to output info messages for static elabmodel (-gnatel)
-
- Elab_Warnings : Boolean := True;
- -- GNAT
- -- Set to True to generate elaboration warnings (-gnatwl). The warnings are
- -- enabled by default because they carry the same importance as errors. The
- -- compiler cannot emit actual errors because elaboration diagnostics need
- -- dataflow analysis, which is not available. This behavior parallels that
- -- of the old ABE mechanism.
-
Enable_128bit_Types : Boolean := False;
-- GNAT
-- Set to True to enable the support for 128-bit types in the compiler.
@@ -548,9 +514,7 @@ package Opt is
Enable_CUDA_Device_Expansion : Boolean := False;
-- GNATBIND
- -- Set to True to enable CUDA device (as opposed to host) expansion:
- -- - Binder generates elaboration/finalization code that can be
- -- invoked from corresponding binder-generated host-side code.
+ -- Set to True to enable CUDA device (as opposed to host) expansion.
Error_Msg_Line_Length : Nat := 0;
-- GNAT
@@ -630,11 +594,16 @@ package Opt is
-- Set to True to convert nonbinary modular additions into code
-- that relies on the front-end expansion of operator Mod.
- function Extensions_Allowed return Boolean is
- (Ada_Version = Ada_With_Extensions);
+ function All_Extensions_Allowed return Boolean is
+ (Ada_Version = Ada_With_All_Extensions);
-- True if GNAT specific language extensions are allowed. See GNAT RM for
-- details.
+ function Core_Extensions_Allowed return Boolean is
+ (Ada_Version >= Ada_With_Core_Extensions);
+ -- True if some but not all GNAT specific language extensions are allowed.
+ -- See GNAT RM for details.
+
type External_Casing_Type is (
As_Is, -- External names cased as they appear in the Ada source
Uppercase, -- External names forced to all uppercase letters
@@ -846,11 +815,6 @@ package Opt is
-- reflect the starting node of the outermost ignored Ghost region. If a
-- nested ignored Ghost region is entered, the value must remain unchanged.
- Implementation_Unit_Warnings : Boolean := True;
- -- GNAT
- -- Set True to active warnings for use of implementation internal units.
- -- Modified by use of -gnatwi/-gnatwI.
-
Implicit_Packing : Boolean := False;
-- GNAT
-- If set True, then a Size attribute clause on an array is allowed to
@@ -861,14 +825,6 @@ package Opt is
-- GNAT
-- Set True to include the enclosing subprogram in compiler messages.
- Ineffective_Inline_Warnings : Boolean := False;
- -- GNAT
- -- Set True to activate warnings if front-end inlining (-gnatN) is not able
- -- to actually inline a particular call (or all calls). Can be controlled
- -- by use of -gnatwp/-gnatwP. Also set True to activate warnings if
- -- frontend inlining is not able to inline a subprogram expected to
- -- be inlined in GNATprove mode.
-
Init_Or_Norm_Scalars : Boolean := False;
-- GNAT, GNATBIND
-- Set True if a pragma Initialize_Scalars applies to the current unit.
@@ -954,17 +910,6 @@ package Opt is
-- Set to True to skip compile and bind steps (except when Bind_Only is
-- set to True).
- List_Body_Required_Info : Boolean := False;
- -- GNATMAKE
- -- List info messages about why a package requires a body. Modified by use
- -- of -gnatw.y/.Y.
-
- List_Inherited_Aspects : Boolean := False;
- -- GNAT
- -- List inherited invariants, preconditions, and postconditions from
- -- Invariant'Class, Pre'Class, and Post'Class aspects. Also list inherited
- -- subtype predicates. Modified by use of -gnatw.l/.L.
-
List_Restrictions : Boolean := False;
-- GNATBIND
-- Set to True to list restrictions pragmas that could apply to partition
@@ -1711,214 +1656,6 @@ package Opt is
-- In High Verbosity, additional lines are output when the ALI file
-- is part of an Ada library, is read-only or is part of the runtime.
- Warn_On_Ada_2005_Compatibility : Boolean := True;
- -- GNAT
- -- Set to True to generate all warnings on Ada 2005 compatibility issues,
- -- including warnings on Ada 2005 obsolescent features used in Ada 2005
- -- mode. Set by default, modified by use of -gnatwy/Y.
-
- Warn_On_Ada_2012_Compatibility : Boolean := True;
- -- GNAT
- -- Set to True to generate all warnings on Ada 2012 compatibility issues,
- -- including warnings on Ada 2012 obsolescent features used in Ada 2012
- -- mode. Modified by use of -gnatwy/Y.
-
- Warn_On_Ada_2022_Compatibility : Boolean := True;
- -- GNAT
- -- Set to True to generate all warnings on Ada 2022 compatibility issues,
- -- including warnings on Ada 2022 obsolescent features used in Ada 2022
- -- mode.
-
- Warn_On_All_Unread_Out_Parameters : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings in all cases where a variable is
- -- modified by being passed as to an OUT formal, but the resulting value is
- -- never read. The default is that this warning is suppressed. Modified
- -- by use of gnatw.o/.O.
-
- Warn_On_Assertion_Failure : Boolean := True;
- -- GNAT
- -- Set to True to activate warnings on assertions that can be determined
- -- at compile time will always fail. Modified by use of -gnatw.a/.A.
-
- Warn_On_Assumed_Low_Bound : Boolean := True;
- -- GNAT
- -- Set to True to activate warnings for string parameters that are indexed
- -- with literals or S'Length, presumably assuming a lower bound of one.
- -- Modified by use of -gnatww/W.
-
- Warn_On_Atomic_Synchronization : Boolean := False;
- -- GNAT
- -- Set to True to generate information messages for atomic synchronization.
- -- Modified by use of -gnatw.n/.N.
-
- Warn_On_Bad_Fixed_Value : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings for static fixed-point expression
- -- values that are not an exact multiple of the small value of the type.
- -- Odd by default, modified by use of -gnatwb/B.
-
- Warn_On_Biased_Representation : Boolean := True;
- -- GNAT
- -- Set to True to generate warnings for size clauses, component clauses
- -- and component_size clauses that force biased representation. Modified
- -- by use of -gnatw.b/.B.
-
- Warn_On_Constant : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings for variables that could be declared
- -- as constants. Modified by use of -gnatwk/K.
-
- Warn_On_Deleted_Code : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings for code deleted by the front end
- -- for conditional statements whose outcome is known at compile time.
- -- Modified by use of -gnatwt/T.
-
- Warn_On_Dereference : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings for implicit dereferences for array
- -- indexing and record component access. Modified by use of -gnatwd/D.
-
- Warn_On_Export_Import : Boolean := True;
- -- GNAT
- -- Set to True to generate warnings for suspicious use of export or
- -- import pragmas. Modified by use of -gnatwx/X.
-
- Warn_On_Elab_Access : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings for P'Access in the case where
- -- subprogram P is in the same package as the P'Access, and the P'Access is
- -- evaluated at package elaboration time, and occurs before the body of P
- -- has been elaborated.
-
- Warn_On_Hiding : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings if a declared entity hides another
- -- entity. The default is that this warning is suppressed. Modified by
- -- use of -gnatwh/H.
-
- Warn_On_Modified_Unread : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings if a variable is assigned but is never
- -- read. Also controls warnings for similar cases involving out parameters,
- -- but only if there is only one out parameter for the procedure involved.
- -- The default is that this warning is suppressed, modified by use of
- -- -gnatwm/M.
-
- Warn_On_No_Value_Assigned : Boolean := True;
- -- GNAT
- -- Set to True to generate warnings if no value is ever assigned to a
- -- variable that is at least partially uninitialized. Set to false to
- -- suppress such warnings. The default is that such warnings are enabled.
- -- Modified by use of -gnatwv/V.
-
- Warn_On_Non_Local_Exception : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings for non-local exception raises and also
- -- handlers that can never handle a local raise. This warning is only ever
- -- generated if pragma Restrictions (No_Exception_Propagation) is set. The
- -- default is not to generate the warnings except that if the source has
- -- at least one exception handler, and this restriction is set, and the
- -- warning was not explicitly turned off, then it is turned on by default.
- -- Modified by use of -gnatw.x/.X.
-
- No_Warn_On_Non_Local_Exception : Boolean := False;
- -- GNAT
- -- This is set to True if the above warning is explicitly suppressed. We
- -- use this to avoid turning it on by default when No_Exception_Propagation
- -- restriction is set and an exception handler is present.
-
- Warn_On_Object_Renames_Function : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings when a function result is renamed as
- -- an object. The default is that this warning is disabled. Modified by
- -- use of -gnatw.r/.R.
-
- Warn_On_Obsolescent_Feature : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings on use of any feature in Annex or if a
- -- subprogram is called for which a pragma Obsolescent applies. Modified
- -- by use of -gnatwj/J.
-
- Warn_On_Overlap : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings when a writable actual overlaps with
- -- another actual in a subprogram call. This applies only in modes before
- -- Ada 2012. Starting with Ada 2012, such overlaps are illegal.
- -- Modified by use of -gnatw.i/.I.
-
- Warn_On_Questionable_Missing_Parens : Boolean := True;
- -- GNAT
- -- Set to True to generate warnings for cases where parentheses are missing
- -- and the usage is questionable, because the intent is unclear. On by
- -- default, modified by use of -gnatwq/Q.
-
- Warn_On_Parameter_Order : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings for cases where the argument list for
- -- a call is a sequence of identifiers that match the formal identifiers,
- -- but are in the wrong order.
-
- Warn_On_Redundant_Constructs : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings for redundant constructs (e.g. useless
- -- assignments/conversions). The default is that this warning is disabled.
- -- Modified by use of -gnatwr/R.
-
- Warn_On_Reverse_Bit_Order : Boolean := True;
- -- GNAT
- -- Set to True to generate warning (informational) messages for component
- -- clauses that are affected by non-standard bit-order. The default is
- -- that this warning is enabled. Modified by -gnatw.v/.V.
-
- Warn_On_Suspicious_Contract : Boolean := True;
- -- GNAT
- -- Set to True to generate warnings for suspicious contracts expressed as
- -- pragmas or aspects precondition and postcondition, as well as other
- -- suspicious cases of expressions typically found in contracts like
- -- quantified expressions and uses of Update attribute. The default is that
- -- this warning is enabled. Modified by use of -gnatw.t/.T.
-
- Warn_On_Suspicious_Modulus_Value : Boolean := True;
- -- GNAT
- -- Set to True to generate warnings for suspicious modulus values, as well
- -- as negative literals of a modular type. The default is that this warning
- -- is enabled. Modified by -gnatw.m/.M.
-
- Warn_On_Unchecked_Conversion : Boolean := True;
- -- GNAT
- -- Set to True to generate warnings for unchecked conversions that may have
- -- non-portable semantics (e.g. because sizes of types differ). Modified
- -- by use of -gnatwz/Z.
-
- Warn_On_Unordered_Enumeration_Type : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings for inappropriate uses (comparisons
- -- and explicit ranges) on unordered enumeration types (which includes
- -- all enumeration types for which pragma Ordered is not given). The
- -- default is that this warning is disabled. Modified by -gnat.u/.U.
-
- Warn_On_Unrecognized_Pragma : Boolean := True;
- -- GNAT
- -- Set to True to generate warnings for unrecognized pragmas. The default
- -- is that this warning is enabled. Modified by use of -gnatwg/G.
-
- Warn_On_Unrepped_Components : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings for the case of components of record
- -- which have a record representation clause but this component does not
- -- have a component clause. Modified by use of -gnatw.c/.C.
-
- Warn_On_Warnings_Off : Boolean := False;
- -- GNAT
- -- Set to True to generate warnings for use of Pragma Warnings (Off, ent),
- -- where either the pragma is never used, or it could be replaced by a
- -- pragma Unmodified or Unreferenced. Also generates warnings for pragma
- -- Warning (Off, string) which either has no matching pragma Warning On,
- -- or where no warning has been suppressed by the use of the pragma.
- -- Modified by use of -gnatw.w/.W.
-
type Warning_Mode_Type is
(Suppress, Normal, Treat_As_Error, Treat_Run_Time_Warnings_As_Errors);
Warning_Mode : Warning_Mode_Type := Normal;
diff --git a/gcc/ada/par-ch3.adb b/gcc/ada/par-ch3.adb
index 5684839..483f96d 100644
--- a/gcc/ada/par-ch3.adb
+++ b/gcc/ada/par-ch3.adb
@@ -2839,7 +2839,8 @@ package body Ch3 is
else
P_Index_Subtype_Def_With_Fixed_Lower_Bound (Subtype_Mark_Node);
- Error_Msg_GNAT_Extension ("fixed-lower-bound array", Token_Ptr);
+ Error_Msg_GNAT_Extension ("fixed-lower-bound array", Token_Ptr,
+ Is_Core_Extension => True);
end if;
exit when Token in Tok_Right_Paren | Tok_Of;
@@ -2909,7 +2910,8 @@ package body Ch3 is
(Subtype_Mark_Node);
Error_Msg_GNAT_Extension
- ("fixed-lower-bound array", Token_Ptr);
+ ("fixed-lower-bound array", Token_Ptr,
+ Is_Core_Extension => True);
end if;
exit when Token in Tok_Right_Paren | Tok_Of;
@@ -3412,7 +3414,8 @@ package body Ch3 is
-- later during analysis), and scan to the next token.
if Token = Tok_Box then
- Error_Msg_GNAT_Extension ("fixed-lower-bound array", Token_Ptr);
+ Error_Msg_GNAT_Extension ("fixed-lower-bound array", Token_Ptr,
+ Is_Core_Extension => True);
Expr_Node := Empty;
Scan;
@@ -4679,7 +4682,7 @@ package body Ch3 is
when Tok_With =>
Check_Bad_Layout;
- if Aspect_Specifications_Present then
+ if Aspect_Specifications_Present (Strict => True) then
-- If we are after a semicolon, complain that it was ignored.
-- But we don't really ignore it, since we dump the aspects,
diff --git a/gcc/ada/par-ch4.adb b/gcc/ada/par-ch4.adb
index 0dc6c8a..82b09b2 100644
--- a/gcc/ada/par-ch4.adb
+++ b/gcc/ada/par-ch4.adb
@@ -1775,7 +1775,7 @@ package body Ch4 is
if Token = Tok_Identifier then
Id := P_Defining_Identifier;
if Token = Tok_Greater then
- if Extensions_Allowed then
+ if Core_Extensions_Allowed then
Set_Box_Present (Assoc_Node);
Set_Binding_Chars (Assoc_Node, Chars (Id));
Box_Present := True;
@@ -1813,7 +1813,7 @@ package body Ch4 is
if Token = Tok_Identifier then
Id := P_Defining_Identifier;
- if not Extensions_Allowed then
+ if not Core_Extensions_Allowed then
Error_Msg_GNAT_Extension
("IS following component association", Token_Ptr);
elsif Box_With_Identifier_Present then
diff --git a/gcc/ada/par-prag.adb b/gcc/ada/par-prag.adb
index e1cf5ba..0adb702 100644
--- a/gcc/ada/par-prag.adb
+++ b/gcc/ada/par-prag.adb
@@ -73,10 +73,12 @@ function Prag (Pragma_Node : Node_Id; Semi : Source_Ptr) return Node_Id is
-- Check the expression of the specified argument to make sure that it
-- is a string literal. If not give error and raise Error_Resync.
- procedure Check_Arg_Is_On_Or_Off (Arg : Node_Id);
+ procedure Check_Arg_Is_On_Or_Off
+ (Arg : Node_Id; All_OK_Too : Boolean := False);
-- Check the expression of the specified argument to make sure that it
-- is an identifier which is either ON or OFF, and if not, then issue
- -- an error message and raise Error_Resync.
+ -- an error message and raise Error_Resync. If All_OK_Too is True,
+ -- then an ALL identifer is also acceptable.
procedure Check_No_Identifier (Arg : Node_Id);
-- Checks that the given argument does not have an identifier. If
@@ -167,17 +169,26 @@ function Prag (Pragma_Node : Node_Id; Semi : Source_Ptr) return Node_Id is
-- Check_Arg_Is_On_Or_Off --
----------------------------
- procedure Check_Arg_Is_On_Or_Off (Arg : Node_Id) is
+ procedure Check_Arg_Is_On_Or_Off
+ (Arg : Node_Id; All_OK_Too : Boolean := False)
+ is
Argx : constant Node_Id := Expression (Arg);
-
+ Error : Boolean := Nkind (Expression (Arg)) /= N_Identifier;
begin
- if Nkind (Expression (Arg)) /= N_Identifier
- or else Chars (Argx) not in Name_On | Name_Off
- then
+ if not Error then
+ Error := (Chars (Argx) not in Name_On | Name_Off)
+ and then not (All_OK_Too and Chars (Argx) = Name_All);
+ end if;
+ if Error then
Error_Msg_Name_2 := Name_On;
Error_Msg_Name_3 := Name_Off;
- Error_Msg_N ("argument for pragma% must be% or%", Argx);
+ if All_OK_Too then
+ Error_Msg_Name_4 := Name_All;
+ Error_Msg_N ("argument for pragma% must be% or% or%", Argx);
+ else
+ Error_Msg_N ("argument for pragma% must be% or%", Argx);
+ end if;
raise Error_Resync;
end if;
end Check_Arg_Is_On_Or_Off;
@@ -414,7 +425,7 @@ begin
-- Extensions_Allowed (GNAT) --
-------------------------------
- -- pragma Extensions_Allowed (Off | On)
+ -- pragma Extensions_Allowed (Off | On | All)
-- The processing for pragma Extensions_Allowed must be done at
-- parse time, since extensions mode may affect what is accepted.
@@ -422,10 +433,12 @@ begin
when Pragma_Extensions_Allowed =>
Check_Arg_Count (1);
Check_No_Identifier (Arg1);
- Check_Arg_Is_On_Or_Off (Arg1);
+ Check_Arg_Is_On_Or_Off (Arg1, All_OK_Too => True);
if Chars (Expression (Arg1)) = Name_On then
- Ada_Version := Ada_With_Extensions;
+ Ada_Version := Ada_With_Core_Extensions;
+ elsif Chars (Expression (Arg1)) = Name_All then
+ Ada_Version := Ada_With_All_Extensions;
else
Ada_Version := Ada_Version_Explicit;
end if;
diff --git a/gcc/ada/pprint.adb b/gcc/ada/pprint.adb
index 983a90b..43939a2 100644
--- a/gcc/ada/pprint.adb
+++ b/gcc/ada/pprint.adb
@@ -114,7 +114,7 @@ package body Pprint is
Num : Natural := 1) return String
is
begin
- if not Present (List) then
+ if No (List) then
if First or else not Add_Paren then
return "";
else
@@ -229,7 +229,7 @@ package body Pprint is
-- is not prepared to deal with a zero-length result.
elsif Null_Record_Present (Expr)
- or else not Present (First (Component_Associations (Expr)))
+ or else No (First (Component_Associations (Expr)))
then
return ("(null record)");
diff --git a/gcc/ada/restrict.adb b/gcc/ada/restrict.adb
index cf43ca9..9965321 100644
--- a/gcc/ada/restrict.adb
+++ b/gcc/ada/restrict.adb
@@ -41,6 +41,7 @@ with Sinput; use Sinput;
with Stand; use Stand;
with Targparm; use Targparm;
with Uname; use Uname;
+with Warnsw; use Warnsw;
package body Restrict is
@@ -896,7 +897,10 @@ package body Restrict is
declare
S : constant String := Restriction_Id'Image (J);
begin
- if S = Name_Buffer (1 .. Name_Len) then
+ if S = Name_Buffer (1 .. Name_Len)
+ -- users cannot name the N_T_H_Implicit restriction
+ and then J /= No_Task_Hierarchy_Implicit
+ then
return J;
end if;
end;
@@ -1103,7 +1107,12 @@ package body Restrict is
function Restriction_Active (R : All_Restrictions) return Boolean is
begin
- return Restrictions.Set (R) and then not Restriction_Warnings (R);
+ if Restrictions.Set (R) and then not Restriction_Warnings (R) then
+ return True;
+ else
+ return R = No_Task_Hierarchy
+ and then Restriction_Active (No_Task_Hierarchy_Implicit);
+ end if;
end Restriction_Active;
--------------------------------
diff --git a/gcc/ada/rtsfind.adb b/gcc/ada/rtsfind.adb
index cda13d4..2c22938 100644
--- a/gcc/ada/rtsfind.adb
+++ b/gcc/ada/rtsfind.adb
@@ -1668,7 +1668,7 @@ package body Rtsfind is
-- Load unit if unit not previously loaded
- if not Present (U.Entity) then
+ if No (U.Entity) then
Load_RTU (U_Id, Id => E);
end if;
@@ -1687,7 +1687,7 @@ package body Rtsfind is
E1 := First_Entity (Pkg_Ent);
while Present (E1) loop
if Ename = Chars (E1) then
- pragma Assert (not Present (Found_E));
+ pragma Assert (No (Found_E));
Found_E := E1;
end if;
diff --git a/gcc/ada/rtsfind.ads b/gcc/ada/rtsfind.ads
index 24aca2c..ce49e2d 100644
--- a/gcc/ada/rtsfind.ads
+++ b/gcc/ada/rtsfind.ads
@@ -609,6 +609,8 @@ package Rtsfind is
RE_Buffer_Type, -- Ada.Strings.Text_Buffers.Unbounded
RE_Get, -- Ada.Strings.Text_Buffers.Unbounded
+ RE_Wide_Get, -- Ada.Strings.Text_Buffers.Unbounded
+ RE_Wide_Wide_Get, -- Ada.Strings.Text_Buffers.Unbounded
RE_Wait_For_Release, -- Ada.Synchronous_Barriers
@@ -2245,6 +2247,8 @@ package Rtsfind is
RE_Buffer_Type => Ada_Strings_Text_Buffers_Unbounded,
RE_Get => Ada_Strings_Text_Buffers_Unbounded,
+ RE_Wide_Get => Ada_Strings_Text_Buffers_Unbounded,
+ RE_Wide_Wide_Get => Ada_Strings_Text_Buffers_Unbounded,
RE_Wait_For_Release => Ada_Synchronous_Barriers,
diff --git a/gcc/ada/sa_messages.adb b/gcc/ada/sa_messages.adb
deleted file mode 100644
index b9b4e93..0000000
--- a/gcc/ada/sa_messages.adb
+++ /dev/null
@@ -1,539 +0,0 @@
-------------------------------------------------------------------------------
--- C O D E P E E R / S P A R K --
--- --
--- Copyright (C) 2015-2022, AdaCore --
--- --
--- This 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. This software is distributed in the hope that it will be useful, --
--- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
--- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --
--- License for more details. You should have received a copy of the GNU --
--- General Public License distributed with this software; see file --
--- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy --
--- of the license. --
--- --
-------------------------------------------------------------------------------
-
-pragma Ada_2012;
-
-with Ada.Directories; use Ada.Directories;
-with Ada.Strings.Unbounded.Hash;
-
-with Ada.Text_IO; use Ada.Text_IO;
-with GNATCOLL.JSON; use GNATCOLL.JSON;
-
-package body SA_Messages is
-
- -----------------------
- -- Local subprograms --
- -----------------------
-
- function "<" (Left, Right : SA_Message) return Boolean is
- (if Left.Kind /= Right.Kind then
- Left.Kind < Right.Kind
- else
- Left.Kind in Check_Kind
- and then Left.Check_Result < Right.Check_Result);
-
- function "<" (Left, Right : Simple_Source_Location) return Boolean is
- (if Left.File_Name /= Right.File_Name then
- Left.File_Name < Right.File_Name
- elsif Left.Line /= Right.Line then
- Left.Line < Right.Line
- else
- Left.Column < Right.Column);
-
- function "<" (Left, Right : Source_Locations) return Boolean is
- (if Left'Length /= Right'Length then
- Left'Length < Right'Length
- elsif Left'Length = 0 then
- False
- elsif Left (Left'Last) /= Right (Right'Last) then
- Left (Left'Last) < Right (Right'Last)
- else
- Left (Left'First .. Left'Last - 1) <
- Right (Right'First .. Right'Last - 1));
-
- function "<" (Left, Right : Source_Location) return Boolean is
- (Left.Locations < Right.Locations);
-
- function Base_Location
- (Location : Source_Location) return Simple_Source_Location is
- (Location.Locations (1));
-
- function Hash (Key : SA_Message) return Hash_Type;
- function Hash (Key : Source_Location) return Hash_Type;
-
- ---------
- -- "<" --
- ---------
-
- function "<" (Left, Right : Message_And_Location) return Boolean is
- (if Left.Message = Right.Message
- then Left.Location < Right.Location
- else Left.Message < Right.Message);
-
- ------------
- -- Column --
- ------------
-
- function Column (Location : Source_Location) return Column_Number is
- (Base_Location (Location).Column);
-
- ---------------
- -- File_Name --
- ---------------
-
- function File_Name (Location : Source_Location) return String is
- (To_String (Base_Location (Location).File_Name));
-
- function File_Name (Location : Source_Location) return Unbounded_String is
- (Base_Location (Location).File_Name);
-
- ------------------------
- -- Enclosing_Instance --
- ------------------------
-
- function Enclosing_Instance
- (Location : Source_Location) return Source_Location_Or_Null is
- (Count => Location.Count - 1,
- Locations => Location.Locations (2 .. Location.Count));
-
- ----------
- -- Hash --
- ----------
-
- function Hash (Key : Message_And_Location) return Hash_Type is
- (Hash (Key.Message) + Hash (Key.Location));
-
- function Hash (Key : SA_Message) return Hash_Type is
- begin
- return Result : Hash_Type :=
- Hash_Type'Mod (Message_Kind'Pos (Key.Kind))
- do
- if Key.Kind in Check_Kind then
- Result := Result +
- Hash_Type'Mod (SA_Check_Result'Pos (Key.Check_Result));
- end if;
- end return;
- end Hash;
-
- function Hash (Key : Source_Location) return Hash_Type is
- begin
- return Result : Hash_Type := Hash_Type'Mod (Key.Count) do
- for Loc of Key.Locations loop
- Result := Result + Hash (Loc.File_Name);
- Result := Result + Hash_Type'Mod (Loc.Line);
- Result := Result + Hash_Type'Mod (Loc.Column);
- end loop;
- end return;
- end Hash;
-
- ---------------
- -- Iteration --
- ---------------
-
- function Iteration (Location : Source_Location) return Iteration_Id is
- (Base_Location (Location).Iteration);
-
- ----------
- -- Line --
- ----------
-
- function Line (Location : Source_Location) return Line_Number is
- (Base_Location (Location).Line);
-
- --------------
- -- Location --
- --------------
-
- function Location
- (Item : Message_And_Location) return Source_Location is
- (Item.Location);
-
- ----------
- -- Make --
- ----------
-
- function Make
- (File_Name : String;
- Line : Line_Number;
- Column : Column_Number;
- Iteration : Iteration_Id;
- Enclosing_Instance : Source_Location_Or_Null) return Source_Location
- is
- begin
- return Result : Source_Location
- (Count => Enclosing_Instance.Count + 1)
- do
- Result.Locations (1) :=
- (File_Name => To_Unbounded_String (File_Name),
- Line => Line,
- Column => Column,
- Iteration => Iteration);
-
- Result.Locations (2 .. Result.Count) := Enclosing_Instance.Locations;
- end return;
- end Make;
-
- ------------------
- -- Make_Msg_Loc --
- ------------------
-
- function Make_Msg_Loc
- (Msg : SA_Message;
- Loc : Source_Location) return Message_And_Location
- is
- begin
- return Message_And_Location'(Count => Loc.Count,
- Message => Msg,
- Location => Loc);
- end Make_Msg_Loc;
-
- -------------
- -- Message --
- -------------
-
- function Message (Item : Message_And_Location) return SA_Message is
- (Item.Message);
-
- package Field_Names is
-
- -- A Source_Location value is represented in JSON as a two or three
- -- field value having fields Message_Kind (a string) and Locations (an
- -- array); if the Message_Kind indicates a check kind, then a third
- -- field is present: Check_Result (a string). The element type of the
- -- Locations array is a value having at least 4 fields:
- -- File_Name (a string), Line (an integer), Column (an integer),
- -- and Iteration_Kind (an integer); if the Iteration_Kind field
- -- has the value corresponding to the enumeration literal Numbered,
- -- then two additional integer fields are present, Iteration_Number
- -- and Iteration_Of_Total.
-
- Check_Result : constant String := "Check_Result";
- Column : constant String := "Column";
- File_Name : constant String := "File_Name";
- Iteration_Kind : constant String := "Iteration_Kind";
- Iteration_Number : constant String := "Iteration_Number";
- Iteration_Of_Total : constant String := "Iteration_Total";
- Line : constant String := "Line";
- Locations : constant String := "Locations";
- Message_Kind : constant String := "Message_Kind";
- Messages : constant String := "Messages";
- end Field_Names;
-
- package body Writing is
- File : File_Type;
- -- The file to which output will be written (in Close, not in Write)
-
- Messages : JSON_Array;
- -- Successive calls to Write append messages to this list
-
- -----------------------
- -- Local subprograms --
- -----------------------
-
- function To_JSON_Array
- (Locations : Source_Locations) return JSON_Array;
- -- Represent a Source_Locations array as a JSON_Array
-
- function To_JSON_Value
- (Location : Simple_Source_Location) return JSON_Value;
- -- Represent a Simple_Source_Location as a JSON_Value
-
- -----------
- -- Close --
- -----------
-
- procedure Close is
- Value : constant JSON_Value := Create_Object;
-
- begin
- -- only one field for now
- Set_Field (Value, Field_Names.Messages, Messages);
- Put_Line (File, Write (Item => Value, Compact => False));
- Clear (Messages);
- Close (File => File);
- end Close;
-
- -------------
- -- Is_Open --
- -------------
-
- function Is_Open return Boolean is (Is_Open (File));
-
- ----------
- -- Open --
- ----------
-
- procedure Open (File_Name : String) is
- begin
- Create (File => File, Mode => Out_File, Name => File_Name);
- Clear (Messages);
- end Open;
-
- -------------------
- -- To_JSON_Array --
- -------------------
-
- function To_JSON_Array
- (Locations : Source_Locations) return JSON_Array
- is
- begin
- return Result : JSON_Array := Empty_Array do
- for Location of Locations loop
- Append (Result, To_JSON_Value (Location));
- end loop;
- end return;
- end To_JSON_Array;
-
- -------------------
- -- To_JSON_Value --
- -------------------
-
- function To_JSON_Value
- (Location : Simple_Source_Location) return JSON_Value
- is
- begin
- return Result : constant JSON_Value := Create_Object do
- Set_Field (Result, Field_Names.File_Name, Location.File_Name);
- Set_Field (Result, Field_Names.Line, Integer (Location.Line));
- Set_Field (Result, Field_Names.Column, Integer (Location.Column));
- Set_Field (Result, Field_Names.Iteration_Kind, Integer'(
- Iteration_Kind'Pos (Location.Iteration.Kind)));
-
- if Location.Iteration.Kind = Numbered then
- Set_Field (Result, Field_Names.Iteration_Number,
- Location.Iteration.Number);
- Set_Field (Result, Field_Names.Iteration_Of_Total,
- Location.Iteration.Of_Total);
- end if;
- end return;
- end To_JSON_Value;
-
- -----------
- -- Write --
- -----------
-
- procedure Write (Message : SA_Message; Location : Source_Location) is
- Value : constant JSON_Value := Create_Object;
-
- begin
- Set_Field (Value, Field_Names.Message_Kind, Message.Kind'Img);
-
- if Message.Kind in Check_Kind then
- Set_Field
- (Value, Field_Names.Check_Result, Message.Check_Result'Img);
- end if;
-
- Set_Field
- (Value, Field_Names.Locations, To_JSON_Array (Location.Locations));
- Append (Messages, Value);
- end Write;
- end Writing;
-
- package body Reading is
- File : File_Type;
- -- The file from which messages are read (in Open, not in Read)
-
- Messages : JSON_Array;
- -- The list of messages that were read in from File
-
- Next_Index : Positive;
- -- The index of the message in Messages which will be returned by the
- -- next call to Get.
-
- Parse_Full_Path : Boolean := True;
- -- if the full path or only the base name of the file should be parsed
-
- -----------
- -- Close --
- -----------
-
- procedure Close is
- begin
- Clear (Messages);
- Close (File);
- end Close;
-
- ----------
- -- Done --
- ----------
-
- function Done return Boolean is (Next_Index > Length (Messages));
-
- ---------
- -- Get --
- ---------
-
- function Get return Message_And_Location is
- Value : constant JSON_Value := Get (Messages, Next_Index);
-
- function Get_Message (Kind : Message_Kind) return SA_Message;
- -- Return SA_Message of given kind, filling in any non-discriminant
- -- by reading from Value.
-
- function Make
- (Location : Source_Location;
- Message : SA_Message) return Message_And_Location;
- -- Constructor
-
- function To_Location
- (Encoded : JSON_Array;
- Full_Path : Boolean) return Source_Location;
- -- Decode a Source_Location from JSON_Array representation
-
- function To_Simple_Location
- (Encoded : JSON_Value;
- Full_Path : Boolean) return Simple_Source_Location;
- -- Decode a Simple_Source_Location from JSON_Value representation
-
- -----------------
- -- Get_Message --
- -----------------
-
- function Get_Message (Kind : Message_Kind) return SA_Message is
- begin
- -- If we had AI12-0086, then we could use aggregates here (which
- -- would be better than field-by-field assignment for the usual
- -- maintainability reasons). But we don't, so we won't.
-
- return Result : SA_Message (Kind => Kind) do
- if Kind in Check_Kind then
- Result.Check_Result :=
- SA_Check_Result'Value
- (Get (Value, Field_Names.Check_Result));
- end if;
- end return;
- end Get_Message;
-
- ----------
- -- Make --
- ----------
-
- function Make
- (Location : Source_Location;
- Message : SA_Message) return Message_And_Location
- is
- (Count => Location.Count, Message => Message, Location => Location);
-
- -----------------
- -- To_Location --
- -----------------
-
- function To_Location
- (Encoded : JSON_Array;
- Full_Path : Boolean) return Source_Location is
- begin
- return Result : Source_Location (Count => Length (Encoded)) do
- for I in Result.Locations'Range loop
- Result.Locations (I) :=
- To_Simple_Location (Get (Encoded, I), Full_Path);
- end loop;
- end return;
- end To_Location;
-
- ------------------------
- -- To_Simple_Location --
- ------------------------
-
- function To_Simple_Location
- (Encoded : JSON_Value;
- Full_Path : Boolean) return Simple_Source_Location
- is
- function Get_Iteration_Id
- (Kind : Iteration_Kind) return Iteration_Id;
- -- Given the discriminant for an Iteration_Id value, return the
- -- entire value.
-
- ----------------------
- -- Get_Iteration_Id --
- ----------------------
-
- function Get_Iteration_Id (Kind : Iteration_Kind)
- return Iteration_Id
- is
- begin
- -- Initialize non-discriminant fields, if any
-
- return Result : Iteration_Id (Kind => Kind) do
- if Kind = Numbered then
- Result :=
- (Kind => Numbered,
- Number =>
- Get (Encoded, Field_Names.Iteration_Number),
- Of_Total =>
- Get (Encoded, Field_Names.Iteration_Of_Total));
- end if;
- end return;
- end Get_Iteration_Id;
-
- -- Local variables
-
- FN : constant Unbounded_String :=
- Get (Encoded, Field_Names.File_Name);
-
- -- Start of processing for To_Simple_Location
-
- begin
- return
- (File_Name =>
- (if Full_Path then
- FN
- else
- To_Unbounded_String (Simple_Name (To_String (FN)))),
- Line =>
- Line_Number (Integer'(Get (Encoded, Field_Names.Line))),
- Column =>
- Column_Number (Integer'(Get (Encoded, Field_Names.Column))),
- Iteration =>
- Get_Iteration_Id
- (Kind => Iteration_Kind'Val (Integer'(Get
- (Encoded, Field_Names.Iteration_Kind)))));
- end To_Simple_Location;
-
- -- Start of processing for Get
-
- begin
- Next_Index := Next_Index + 1;
-
- return Make
- (Message =>
- Get_Message
- (Message_Kind'Value (Get (Value, Field_Names.Message_Kind))),
- Location =>
- To_Location
- (Get (Value, Field_Names.Locations), Parse_Full_Path));
- end Get;
-
- -------------
- -- Is_Open --
- -------------
-
- function Is_Open return Boolean is (Is_Open (File));
-
- ----------
- -- Open --
- ----------
-
- procedure Open (File_Name : String; Full_Path : Boolean := True) is
- File_Text : Unbounded_String := Null_Unbounded_String;
-
- begin
- Parse_Full_Path := Full_Path;
- Open (File => File, Mode => In_File, Name => File_Name);
-
- -- File read here, not in Get, but that's an implementation detail
-
- while not End_Of_File (File) loop
- Append (File_Text, Get_Line (File));
- end loop;
-
- Messages := Get (Read (File_Text), Field_Names.Messages);
- Next_Index := 1;
- end Open;
- end Reading;
-
-end SA_Messages;
diff --git a/gcc/ada/sa_messages.ads b/gcc/ada/sa_messages.ads
deleted file mode 100644
index c448397..0000000
--- a/gcc/ada/sa_messages.ads
+++ /dev/null
@@ -1,267 +0,0 @@
-------------------------------------------------------------------------------
--- C O D E P E E R / S P A R K --
--- --
--- Copyright (C) 2015-2022, AdaCore --
--- --
--- This 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. This software is distributed in the hope that it will be useful, --
--- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
--- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --
--- License for more details. You should have received a copy of the GNU --
--- General Public License distributed with this software; see file --
--- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy --
--- of the license. --
--- --
-------------------------------------------------------------------------------
-
-pragma Ada_2012;
-
-with Ada.Containers; use Ada.Containers;
-with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
-
-package SA_Messages is
-
- -- This package can be used for reading/writing a file containing a
- -- sequence of static anaysis results. Each element can describe a runtime
- -- check whose outcome has been statically determined, or it might be a
- -- warning or diagnostic message. It is expected that typically CodePeer
- -- will do the writing and SPARK will do the reading; this will allow SPARK
- -- to get the benefit of CodePeer's analysis.
- --
- -- Each item is represented as a pair consisting of a message and an
- -- associated source location. Source locations may refer to a location
- -- within the expansion of an instance of a generic; this is represented
- -- by combining the corresponding location within the generic with the
- -- location of the instance (repeated if the instance itself occurs within
- -- a generic). In addition, the type Iteration_Id is intended for use in
- -- distinguishing messages which refer to a specific iteration of a loop
- -- (this case can arise, for example, if CodePeer chooses to unroll a
- -- for-loop). This data structure is only general enough to support the
- -- kinds of unrolling that are currently planned for CodePeer. For
- -- example, an Iteration_Id can only identify an iteration of the nearest
- -- enclosing loop of the associated File/Line/Column source location.
- -- This is not a problem because CodePeer doesn't unroll loops which
- -- contain other loops.
-
- type Message_Kind is (
-
- -- Check kinds
-
- Array_Index_Check,
- Divide_By_Zero_Check,
- Tag_Check,
- Discriminant_Check,
- Range_Check,
- Overflow_Check,
- Assertion_Check,
-
- -- Warning kinds
-
- Suspicious_Range_Precondition_Warning,
- Suspicious_First_Precondition_Warning,
- Suspicious_Input_Warning,
- Suspicious_Constant_Operation_Warning,
- Unread_In_Out_Parameter_Warning,
- Unassigned_In_Out_Parameter_Warning,
- Non_Analyzed_Call_Warning,
- Procedure_Does_Not_Return_Warning,
- Check_Fails_On_Every_Call_Warning,
- Unknown_Call_Warning,
- Dead_Store_Warning,
- Dead_Outparam_Store_Warning,
- Potentially_Dead_Store_Warning,
- Same_Value_Dead_Store_Warning,
- Dead_Block_Warning,
- Infinite_Loop_Warning,
- Dead_Edge_Warning,
- Plain_Dead_Edge_Warning,
- True_Dead_Edge_Warning,
- False_Dead_Edge_Warning,
- True_Condition_Dead_Edge_Warning,
- False_Condition_Dead_Edge_Warning,
- Unrepeatable_While_Loop_Warning,
- Dead_Block_Continuation_Warning,
- Local_Lock_Of_Global_Object_Warning,
- Analyzed_Module_Warning,
- Non_Analyzed_Module_Warning,
- Non_Analyzed_Procedure_Warning,
- Incompletely_Analyzed_Procedure_Warning);
-
- -- Assertion_Check includes checks for user-defined PPCs (both specific
- -- and class-wide), Assert pragma checks, subtype predicate checks,
- -- type invariant checks (specific and class-wide), and checks for
- -- implementation-defined assertions such as Assert_And_Cut, Assume,
- -- Contract_Cases, Default_Initial_Condition, Initial_Condition,
- -- Loop_Invariant, Loop_Variant, Refined_Post, and Subprogram_Variant.
- --
- -- It might be nice to distinguish these different kinds of assertions
- -- as is done in SPARK's VC_Kind enumeration type, but any distinction
- -- which isn't already present in CP's BE_Message_Subkind enumeration type
- -- would require more work on the CP side.
- --
- -- The warning kinds are pretty much a copy of the set of
- -- Be_Message_Subkind values for which CP's Is_Warning predicate returns
- -- True; see descriptive comment for each in CP's message_kinds.ads .
-
- subtype Check_Kind is Message_Kind
- range Array_Index_Check .. Assertion_Check;
- subtype Warning_Kind is Message_Kind
- range Message_Kind'Succ (Check_Kind'Last) .. Message_Kind'Last;
-
- -- Possible outcomes of the static analysis of a runtime check
- --
- -- Not_Statically_Known_With_Low_Severity could be used instead of of
- -- Not_Statically_Known if there is some reason to believe that (although
- -- the tool couldn't prove it) the check is likely to always pass (in CP
- -- terms, if the corresponding CP message has severity Low as opposed to
- -- Medium). It's not clear yet whether SPARK will care about this
- -- distinction.
-
- type SA_Check_Result is
- (Statically_Known_Success,
- Not_Statically_Known_With_Low_Severity,
- Not_Statically_Known,
- Statically_Known_Failure);
-
- type SA_Message (Kind : Message_Kind := Message_Kind'Last) is record
- case Kind is
- when Check_Kind =>
- Check_Result : SA_Check_Result;
-
- when Warning_Kind =>
- null;
- end case;
- end record;
-
- type Source_Location_Or_Null (<>) is private;
- Null_Location : constant Source_Location_Or_Null;
- subtype Source_Location is Source_Location_Or_Null with
- Dynamic_Predicate => Source_Location /= Null_Location;
-
- type Line_Number is new Positive;
- type Column_Number is new Positive;
-
- function File_Name (Location : Source_Location) return String;
- function File_Name (Location : Source_Location) return Unbounded_String;
- function Line (Location : Source_Location) return Line_Number;
- function Column (Location : Source_Location) return Column_Number;
-
- type Iteration_Kind is (None, Initial, Subsequent, Numbered);
- -- None is for the usual no-unrolling case.
- -- Initial and Subsequent are for use in the case where only the first
- -- iteration of a loop (or some part thereof, such as the termination
- -- test of a while-loop) is unrolled.
- -- Numbered is for use in the case where a for-loop with a statically
- -- known number of iterations is fully unrolled.
-
- subtype Iteration_Number is Integer range 1 .. 255;
- subtype Iteration_Total is Integer range 2 .. 255;
-
- type Iteration_Id (Kind : Iteration_Kind := None) is record
- case Kind is
- when Numbered =>
- Number : Iteration_Number;
- Of_Total : Iteration_Total;
- when others =>
- null;
- end case;
- end record;
-
- function Iteration (Location : Source_Location) return Iteration_Id;
-
- function Enclosing_Instance
- (Location : Source_Location) return Source_Location_Or_Null;
- -- For a source location occurring within the expansion of an instance of a
- -- generic unit, the Line, Column, and File_Name selectors will indicate a
- -- location within the generic; the Enclosing_Instance selector yields the
- -- location of the declaration of the instance.
-
- function Make
- (File_Name : String;
- Line : Line_Number;
- Column : Column_Number;
- Iteration : Iteration_Id;
- Enclosing_Instance : Source_Location_Or_Null) return Source_Location;
- -- Constructor
-
- type Message_And_Location (<>) is private;
-
- function Location (Item : Message_And_Location) return Source_Location;
- function Message (Item : Message_And_Location) return SA_Message;
-
- function Make_Msg_Loc
- (Msg : SA_Message;
- Loc : Source_Location) return Message_And_Location;
- -- Selectors
-
- function "<" (Left, Right : Message_And_Location) return Boolean;
- function Hash (Key : Message_And_Location) return Hash_Type;
- -- Actuals for container instances
-
- File_Extension : constant String; -- ".json" (but could change in future)
- -- Clients may wish to use File_Extension in constructing
- -- File_Name parameters for calls to Open.
-
- package Writing is
- function Is_Open return Boolean;
-
- procedure Open (File_Name : String) with
- Precondition => not Is_Open,
- Postcondition => Is_Open;
- -- Behaves like Text_IO.Create with respect to error cases
-
- procedure Write (Message : SA_Message; Location : Source_Location);
-
- procedure Close with
- Precondition => Is_Open,
- Postcondition => not Is_Open;
- -- Behaves like Text_IO.Close with respect to error cases
- end Writing;
-
- package Reading is
- function Is_Open return Boolean;
-
- procedure Open (File_Name : String; Full_Path : Boolean := True) with
- Precondition => not Is_Open,
- Postcondition => Is_Open;
- -- Behaves like Text_IO.Open with respect to error cases
-
- function Done return Boolean with
- Precondition => Is_Open;
-
- function Get return Message_And_Location with
- Precondition => not Done;
-
- procedure Close with
- Precondition => Is_Open,
- Postcondition => not Is_Open;
- -- Behaves like Text_IO.Close with respect to error cases
- end Reading;
-
-private
- type Simple_Source_Location is record
- File_Name : Unbounded_String := Null_Unbounded_String;
- Line : Line_Number := Line_Number'Last;
- Column : Column_Number := Column_Number'Last;
- Iteration : Iteration_Id := (Kind => None);
- end record;
-
- type Source_Locations is
- array (Natural range <>) of Simple_Source_Location;
-
- type Source_Location_Or_Null (Count : Natural) is record
- Locations : Source_Locations (1 .. Count);
- end record;
-
- Null_Location : constant Source_Location_Or_Null :=
- (Count => 0, Locations => (others => <>));
-
- type Message_And_Location (Count : Positive) is record
- Message : SA_Message;
- Location : Source_Location (Count => Count);
- end record;
-
- File_Extension : constant String := ".json";
-end SA_Messages;
diff --git a/gcc/ada/scans.ads b/gcc/ada/scans.ads
index dbe9e5a..ddb4c3e 100644
--- a/gcc/ada/scans.ads
+++ b/gcc/ada/scans.ads
@@ -358,38 +358,35 @@ package Scans is
-- Note: these variables can only be referenced during the parsing of a
-- file. Reference to any of them from Sem or the expander is wrong.
- -- These variables are initialized as required by Scn.Initialize_Scanner,
- -- and should not be referenced before such a call. However, there are
- -- situations in which these variables are saved and restored, and this
- -- may happen before the first Initialize_Scanner call, resulting in the
- -- assignment of invalid values. To avoid this, and allow building with
- -- the -gnatVa switch, we initialize some variables to known valid values.
-
- Scan_Ptr : Source_Ptr := No_Location; -- init for -gnatVa
+ -- These variables are initialized by Scn.Initialize_Scanner, and should
+ -- not be referenced before such a call, except for saving and restoring
+ -- them.
+
+ Scan_Ptr : Source_Ptr := No_Location;
-- Current scan pointer location. After a call to Scan, this points
-- just past the end of the token just scanned.
- Token : Token_Type := No_Token; -- init for -gnatVa
+ Token : Token_Type := No_Token;
-- Type of current token
- Token_Ptr : Source_Ptr := No_Location; -- init for -gnatVa
+ Token_Ptr : Source_Ptr := No_Location;
-- Pointer to first character of current token
- Current_Line_Start : Source_Ptr := No_Location; -- init for -gnatVa
+ Current_Line_Start : Source_Ptr := No_Location;
-- Pointer to first character of line containing current token
- Start_Column : Column_Number := No_Column_Number; -- init for -gnatVa
+ Start_Column : Column_Number := No_Column_Number;
-- Starting column number (zero origin) of the first non-blank character
-- on the line containing the current token. This is used for error
-- recovery circuits which depend on looking at the column line up.
- Type_Token_Location : Source_Ptr := No_Location; -- init for -gnatVa
+ Type_Token_Location : Source_Ptr := No_Location;
-- Within a type declaration, gives the location of the TYPE keyword that
-- opened the type declaration. Used in checking the end column of a record
-- declaration, which can line up either with the TYPE keyword, or with the
-- start of the line containing the RECORD keyword.
- Checksum : Word := 0; -- init for -gnatVa
+ Checksum : Word := 0;
-- Used to accumulate a CRC representing the tokens in the source
-- file being compiled. This CRC includes only program tokens, and
-- excludes comments.
@@ -399,7 +396,7 @@ package Scans is
-- limited view of a package, i.e. visible type names and related
-- tagged indicators.
- First_Non_Blank_Location : Source_Ptr := No_Location; -- init for -gnatVa
+ First_Non_Blank_Location : Source_Ptr := No_Location;
-- Location of first non-blank character on the line containing the
-- current token (i.e. the location of the character whose column number
-- is stored in Start_Column).
diff --git a/gcc/ada/scn.adb b/gcc/ada/scn.adb
index f8f0301..35d6981 100644
--- a/gcc/ada/scn.adb
+++ b/gcc/ada/scn.adb
@@ -26,7 +26,6 @@
with Atree; use Atree;
with Csets; use Csets;
with Namet; use Namet;
-with Opt; use Opt;
with Restrict; use Restrict;
with Rident; use Rident;
with Scans; use Scans;
@@ -34,6 +33,7 @@ with Sinfo; use Sinfo;
with Sinfo.Nodes; use Sinfo.Nodes;
with Sinput; use Sinput;
with Uintp; use Uintp;
+with Warnsw; use Warnsw;
package body Scn is
diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
index 5db1fce..433f1ac 100644
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -70,6 +70,7 @@ with Targparm; use Targparm;
with Tbuild; use Tbuild;
with Ttypes; use Ttypes;
with Uintp; use Uintp;
+with Warnsw; use Warnsw;
package body Sem_Aggr is
@@ -1052,7 +1053,7 @@ package body Sem_Aggr is
elsif Is_Array_Type (Typ) and then Null_Record_Present (N) then
Error_Msg_N ("null record forbidden in array aggregate", N);
- elsif Present (Find_Aspect (Typ, Aspect_Aggregate))
+ elsif Has_Aspect (Typ, Aspect_Aggregate)
and then Ekind (Typ) /= E_Record_Type
and then Ada_Version >= Ada_2022
then
@@ -2355,7 +2356,7 @@ package body Sem_Aggr is
-- duplicate the expression tree to analyze the copy and
-- perform the required check.
- elsif not Present (Etype (Expression (Assoc))) then
+ elsif No (Etype (Expression (Assoc))) then
declare
Save_Analysis : constant Boolean := Full_Analysis;
Expr : constant Node_Id :=
@@ -3241,7 +3242,7 @@ package body Sem_Aggr is
end loop;
end;
- else
+ elsif Present (Assign_Indexed_Subp) then
-- Indexed Aggregate. Positional or indexed component
-- can be present, but not both. Choices must be static
-- values or ranges with static bounds.
@@ -3421,6 +3422,18 @@ package body Sem_Aggr is
Analyze_And_Resolve (Base, Typ);
if Is_Array_Type (Typ) then
+ -- For an array_delta_aggregate, the base_expression and each
+ -- expression in every array_component_association shall be of a
+ -- nonlimited type; RM 4.3.4(13/5). However, to prevent repeated
+ -- errors we only check the base expression and not array component
+ -- associations.
+
+ if Is_Limited_Type (Etype (Base)) then
+ Error_Msg_N
+ ("array delta aggregate shall be of a nonlimited type", Base);
+ Explain_Limited_Type (Etype (Base), Base);
+ end if;
+
Resolve_Delta_Array_Aggregate (N, Typ);
else
@@ -3432,6 +3445,11 @@ package body Sem_Aggr is
("delta aggregates for record types must use (), not '[']", N);
end if;
+ -- The base_expression of a record_delta_aggregate can be of a
+ -- limited type only if it is newly constructed; RM 7.5(2.1/5).
+
+ Check_Expr_OK_In_Limited_Aggregate (Base);
+
Resolve_Delta_Record_Aggregate (N, Typ);
end if;
@@ -3531,7 +3549,18 @@ package body Sem_Aggr is
Next (Choice);
end loop;
- Analyze_And_Resolve (Expression (Assoc), Component_Type (Typ));
+ -- For an array_delta_aggregate, the array_component_association
+ -- shall not use the box symbol <>; RM 4.3.4(11/5).
+
+ pragma Assert
+ (Box_Present (Assoc) xor Present (Expression (Assoc)));
+
+ if Box_Present (Assoc) then
+ Error_Msg_N
+ ("'<'> in array delta aggregate is not allowed", Assoc);
+ else
+ Analyze_And_Resolve (Expression (Assoc), Component_Type (Typ));
+ end if;
end if;
Next (Assoc);
@@ -3735,7 +3764,17 @@ package body Sem_Aggr is
("'<'> in record delta aggregate is not allowed", Assoc);
else
Analyze_And_Resolve (Expression (Assoc), Comp_Type);
+
+ -- The expression must not be of a limited type; RM 4.3.1(17.4/5)
+
+ if Is_Limited_Type (Etype (Expression (Assoc))) then
+ Error_Msg_N
+ ("expression of a limited type in record delta aggregate " &
+ "is not allowed",
+ Expression (Assoc));
+ end if;
end if;
+
Next (Assoc);
end loop;
end Resolve_Delta_Record_Aggregate;
@@ -5747,7 +5786,7 @@ package body Sem_Aggr is
-- Ignore hidden components associated with the position of the
-- interface tags: these are initialized dynamically.
- if not Present (Related_Type (Component)) then
+ if No (Related_Type (Component)) then
Error_Msg_NE
("no value supplied for component &!", N, Component);
end if;
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index d27d956..7c76f0f 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -25,6 +25,7 @@
with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
+with Accessibility; use Accessibility;
with Aspects; use Aspects;
with Atree; use Atree;
with Casing; use Casing;
@@ -84,6 +85,7 @@ with Tbuild; use Tbuild;
with Uintp; use Uintp;
with Uname; use Uname;
with Urealp; use Urealp;
+with Warnsw; use Warnsw;
with System.CRC32; use System.CRC32;
@@ -1138,7 +1140,7 @@ package body Sem_Attr is
-- pointer can be used to modify the variable, and we might
-- not detect this, leading to some junk warnings.
- -- We only do this for source references, since otherwise
+ -- We do this only for source references, since otherwise
-- we can suppress warnings, e.g. from the unrestricted
-- access generated for validity checks in -gnatVa mode.
@@ -3429,7 +3431,34 @@ package body Sem_Attr is
Check_E0;
Address_Checks;
Check_Not_Incomplete_Type;
- Set_Etype (N, RTE (RE_Address));
+
+ -- If the prefix is a dereference of a value whose associated access
+ -- type has been specified with aspect Designated_Storage_Model, then
+ -- use the associated Storage_Model_Type's address type as the type
+ -- of the attribute. Otherwise we use System.Address as usual. This
+ -- isn't normally legit for a predefined attribute, but this is for
+ -- our own extension to addressing and currently requires extensions
+ -- to be enabled (such as with -gnatX0).
+
+ declare
+ Prefix_Obj : constant Node_Id := Get_Referenced_Object (P);
+ Addr_Type : Entity_Id := RTE (RE_Address);
+ begin
+ if Nkind (Prefix_Obj) = N_Explicit_Dereference then
+ declare
+ P_Type : constant Entity_Id := Etype (Prefix (Prefix_Obj));
+
+ use Storage_Model_Support;
+ begin
+ if Has_Designated_Storage_Model_Aspect (P_Type) then
+ Addr_Type := Storage_Model_Address_Type
+ (Storage_Model_Object (P_Type));
+ end if;
+ end;
+ end if;
+
+ Set_Etype (N, Addr_Type);
+ end;
------------------
-- Address_Size --
@@ -3888,7 +3917,7 @@ package body Sem_Attr is
elsif (Is_Generic_Type (P_Type)
or else Is_Generic_Actual_Type (P_Type))
- and then Extensions_Allowed
+ and then All_Extensions_Allowed
then
return;
end if;
@@ -5996,8 +6025,8 @@ package body Sem_Attr is
-- Verify that prefix can be iterated upon.
if Is_Array_Type (Typ)
- or else Present (Find_Aspect (Typ, Aspect_Default_Iterator))
- or else Present (Find_Aspect (Typ, Aspect_Iterable))
+ or else Has_Aspect (Typ, Aspect_Default_Iterator)
+ or else Has_Aspect (Typ, Aspect_Iterable)
then
null;
else
@@ -6425,7 +6454,7 @@ package body Sem_Attr is
-- type to the pool object's type.
else
- if not Present (Get_Rep_Pragma (Etype (Entity (N)),
+ if No (Get_Rep_Pragma (Etype (Entity (N)),
Name_Simple_Storage_Pool_Type))
then
Error_Attr_P
@@ -9203,13 +9232,15 @@ package body Sem_Attr is
-- Image is a scalar attribute, but is never static, because it is
-- not a static function (having a non-scalar argument (RM 4.9(22))
-- However, we can constant-fold the image of an enumeration literal
- -- if names are available.
+ -- if names are available and default Image implementation has not
+ -- been overridden.
when Attribute_Image =>
if Is_Entity_Name (E1)
and then Ekind (Entity (E1)) = E_Enumeration_Literal
and then not Discard_Names (First_Subtype (Etype (E1)))
and then not Global_Discard_Names
+ and then not Has_Aspect (Etype (E1), Aspect_Put_Image)
then
declare
Lit : constant Entity_Id := Entity (E1);
@@ -10906,72 +10937,12 @@ package body Sem_Attr is
It : Interp;
Nom_Subt : Entity_Id;
- procedure Accessibility_Message;
- -- Error, or warning within an instance, if the static accessibility
- -- rules of 3.10.2 are violated.
-
function Declared_Within_Generic_Unit
(Entity : Entity_Id;
Generic_Unit : Node_Id) return Boolean;
-- Returns True if Declared_Entity is declared within the declarative
-- region of Generic_Unit; otherwise returns False.
- function Prefix_With_Safe_Accessibility_Level return Boolean;
- -- Return True if the prefix does not have a value conversion of an
- -- array because a value conversion is like an aggregate with respect
- -- to determining accessibility level (RM 3.10.2); even if evaluation
- -- of a value conversion is guaranteed to not create a new object,
- -- accessibility rules are defined as if it might.
-
- ---------------------------
- -- Accessibility_Message --
- ---------------------------
-
- procedure Accessibility_Message is
- Indic : Node_Id := Parent (Parent (N));
-
- begin
- -- In an instance, this is a runtime check, but one we
- -- know will fail, so generate an appropriate warning.
-
- if In_Instance_Body then
- Error_Msg_Warn := SPARK_Mode /= On;
- Error_Msg_F
- ("non-local pointer cannot point to local object<<", P);
- Error_Msg_F ("\Program_Error [<<", P);
- Rewrite (N,
- Make_Raise_Program_Error (Loc,
- Reason => PE_Accessibility_Check_Failed));
- Set_Etype (N, Typ);
- return;
-
- else
- Error_Msg_F ("non-local pointer cannot point to local object", P);
-
- -- Check for case where we have a missing access definition
-
- if Is_Record_Type (Current_Scope)
- and then
- Nkind (Parent (N)) in N_Discriminant_Association
- | N_Index_Or_Discriminant_Constraint
- then
- Indic := Parent (Parent (N));
- while Present (Indic)
- and then Nkind (Indic) /= N_Subtype_Indication
- loop
- Indic := Parent (Indic);
- end loop;
-
- if Present (Indic) then
- Error_Msg_NE
- ("\use an access definition for" &
- " the access discriminant of&",
- N, Entity (Subtype_Mark (Indic)));
- end if;
- end if;
- end if;
- end Accessibility_Message;
-
----------------------------------
-- Declared_Within_Generic_Unit --
----------------------------------
@@ -10999,70 +10970,6 @@ package body Sem_Attr is
return False;
end Declared_Within_Generic_Unit;
- ------------------------------------------
- -- Prefix_With_Safe_Accessibility_Level --
- ------------------------------------------
-
- function Prefix_With_Safe_Accessibility_Level return Boolean is
- function Safe_Value_Conversions return Boolean;
- -- Return False if the prefix has a value conversion of an array type
-
- ----------------------------
- -- Safe_Value_Conversions --
- ----------------------------
-
- function Safe_Value_Conversions return Boolean is
- PP : Node_Id := P;
-
- begin
- loop
- if Nkind (PP) in N_Selected_Component | N_Indexed_Component then
- PP := Prefix (PP);
-
- elsif Comes_From_Source (PP)
- and then Nkind (PP) in N_Type_Conversion
- | N_Unchecked_Type_Conversion
- and then Is_Array_Type (Etype (PP))
- then
- return False;
-
- elsif Comes_From_Source (PP)
- and then Nkind (PP) = N_Qualified_Expression
- and then Is_Array_Type (Etype (PP))
- and then Nkind (Original_Node (Expression (PP))) in
- N_Aggregate | N_Extension_Aggregate
- then
- return False;
-
- else
- exit;
- end if;
- end loop;
-
- return True;
- end Safe_Value_Conversions;
-
- -- Start of processing for Prefix_With_Safe_Accessibility_Level
-
- begin
- -- No check required for unchecked and unrestricted access
-
- if Attr_Id = Attribute_Unchecked_Access
- or else Attr_Id = Attribute_Unrestricted_Access
- then
- return True;
-
- -- Check value conversions
-
- elsif Ekind (Btyp) = E_General_Access_Type
- and then not Safe_Value_Conversions
- then
- return False;
- end if;
-
- return True;
- end Prefix_With_Safe_Accessibility_Level;
-
-- Start of processing for Resolve_Attribute
begin
@@ -11748,7 +11655,7 @@ package body Sem_Attr is
Intval (Accessibility_Level (P, Dynamic_Level))
> Deepest_Type_Access_Level (Btyp)
then
- Accessibility_Message;
+ Accessibility_Message (N, Typ);
return;
end if;
end;
@@ -11774,7 +11681,7 @@ package body Sem_Attr is
and then Ekind (Btyp) = E_Access_Protected_Subprogram_Type
and then Attr_Id /= Attribute_Unrestricted_Access
then
- Accessibility_Message;
+ Accessibility_Message (N, Typ);
return;
-- AI05-0225: If the context is not an access to protected
@@ -11933,8 +11840,8 @@ package body Sem_Attr is
-- array type since a value conversion is like an aggregate with
-- respect to determining accessibility level (RM 3.10.2).
- if not Prefix_With_Safe_Accessibility_Level then
- Accessibility_Message;
+ if not Prefix_With_Safe_Accessibility_Level (N, Typ) then
+ Accessibility_Message (N, Typ);
return;
end if;
diff --git a/gcc/ada/sem_aux.ads b/gcc/ada/sem_aux.ads
index 66cbcfb..004aadb 100644
--- a/gcc/ada/sem_aux.ads
+++ b/gcc/ada/sem_aux.ads
@@ -279,7 +279,7 @@ package Sem_Aux is
-- or subtype. This is true if Suppress_Initialization is set either for
-- the subtype itself, or for the corresponding base type.
- function Is_Body (N : Node_Id) return Boolean;
+ function Is_Body (N : Node_Id) return Boolean with Inline;
-- Determine whether an arbitrary node denotes a body
function Is_By_Copy_Type (Ent : Entity_Id) return Boolean;
diff --git a/gcc/ada/sem_case.adb b/gcc/ada/sem_case.adb
index 2810d3e..9577921 100644
--- a/gcc/ada/sem_case.adb
+++ b/gcc/ada/sem_case.adb
@@ -48,6 +48,7 @@ with Stringt; use Stringt;
with Table;
with Tbuild; use Tbuild;
with Uintp; use Uintp;
+with Warnsw; use Warnsw;
with Ada.Unchecked_Deallocation;
@@ -192,8 +193,13 @@ package body Sem_Case is
record
Low, High : Uint;
end record;
+ function "=" (X, Y : Discrete_Range_Info) return Boolean is abstract;
+ -- Here (and below), we don't use "=", which is a good thing,
+ -- because it wouldn't work, because the user-defined "=" on
+ -- Uint does not compose according to Ada rules.
type Composite_Range_Info is array (Part_Id) of Discrete_Range_Info;
+ function "=" (X, Y : Composite_Range_Info) return Boolean is abstract;
type Choice_Range_Info (Is_Others : Boolean := False) is
record
@@ -204,6 +210,9 @@ package body Sem_Case is
null;
end case;
end record;
+ pragma Annotate (CodePeer, False_Positive, "raise exception",
+ "function is abstract, hence never called");
+ function "=" (X, Y : Choice_Range_Info) return Boolean is abstract;
type Choices_Range_Info is array (Choice_Id) of Choice_Range_Info;
@@ -1611,7 +1620,7 @@ package body Sem_Case is
begin
while Present (Comp) loop
if Chars (First (Choices (Comp))) = Orig_Name then
- pragma Assert (not Present (Matching_Comp));
+ pragma Assert (No (Matching_Comp));
Matching_Comp := Comp;
end if;
@@ -3581,7 +3590,7 @@ package body Sem_Case is
-- Hold on, maybe it isn't a complete mess after all.
- if Extensions_Allowed and then Subtyp /= Any_Type then
+ if Core_Extensions_Allowed and then Subtyp /= Any_Type then
Check_Composite_Case_Selector;
Check_Case_Pattern_Choices;
end if;
@@ -3864,7 +3873,7 @@ package body Sem_Case is
function Is_Case_Choice_Pattern (Expr : Node_Id) return Boolean is
E : Node_Id := Expr;
begin
- if not Extensions_Allowed then
+ if not Core_Extensions_Allowed then
return False;
end if;
diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb
index 8c1c00c..a938083 100644
--- a/gcc/ada/sem_ch10.adb
+++ b/gcc/ada/sem_ch10.adb
@@ -74,6 +74,7 @@ with Style; use Style;
with Stylesw; use Stylesw;
with Tbuild; use Tbuild;
with Uname; use Uname;
+with Warnsw; use Warnsw;
package body Sem_Ch10 is
diff --git a/gcc/ada/sem_ch11.adb b/gcc/ada/sem_ch11.adb
index 339edd3..ea6f9c8 100644
--- a/gcc/ada/sem_ch11.adb
+++ b/gcc/ada/sem_ch11.adb
@@ -50,6 +50,7 @@ with Sinfo; use Sinfo;
with Sinfo.Nodes; use Sinfo.Nodes;
with Sinfo.Utils; use Sinfo.Utils;
with Stand; use Stand;
+with Warnsw; use Warnsw;
package body Sem_Ch11 is
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index ab2e182..1ea9584 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -1151,7 +1151,7 @@ package body Sem_Ch12 is
-- in which case the predefined operations will be used. This merits
-- a warning because of the special semantics of fixed point ops.
- procedure Check_Overloaded_Formal_Subprogram (Formal : Entity_Id);
+ procedure Check_Overloaded_Formal_Subprogram (Formal : Node_Id);
-- Apply RM 12.3(9): if a formal subprogram is overloaded, the instance
-- cannot have a named association for it. AI05-0025 extends this rule
-- to formals of formal packages by AI05-0025, and it also applies to
@@ -1203,12 +1203,31 @@ package body Sem_Ch12 is
-------------------------------
procedure Build_Subprogram_Wrappers is
+ function Adjust_Aspect_Sloc (N : Node_Id) return Traverse_Result;
+ -- Adjust sloc so that errors located at N will be reported with
+ -- information about the instance and not just about the generic.
+
+ ------------------------
+ -- Adjust_Aspect_Sloc --
+ ------------------------
+
+ function Adjust_Aspect_Sloc (N : Node_Id) return Traverse_Result is
+ begin
+ Adjust_Instantiation_Sloc (N, S_Adjustment);
+ return OK;
+ end Adjust_Aspect_Sloc;
+
+ procedure Adjust_Aspect_Slocs is new
+ Traverse_Proc (Adjust_Aspect_Sloc);
+
Formal : constant Entity_Id :=
Defining_Unit_Name (Specification (Analyzed_Formal));
Aspect_Spec : Node_Id;
Decl_Node : Node_Id;
Actual_Name : Node_Id;
+ -- Start of processing for Build_Subprogram_Wrappers
+
begin
-- Create declaration for wrapper subprogram
-- The actual can be overloaded, in which case it will be
@@ -1247,6 +1266,7 @@ package body Sem_Ch12 is
Aspect_Spec := First (Aspect_Specifications (Decl_Node));
while Present (Aspect_Spec) loop
+ Adjust_Aspect_Slocs (Aspect_Spec);
Set_Analyzed (Aspect_Spec, False);
Next (Aspect_Spec);
end loop;
@@ -1259,15 +1279,15 @@ package body Sem_Ch12 is
-- actuals.
Append_To (Assoc_List,
- Build_Subprogram_Body_Wrapper (Formal, Actual_Name));
+ Build_Subprogram_Body_Wrapper (Formal, Actual_Name));
end Build_Subprogram_Wrappers;
----------------------------------------
-- Check_Overloaded_Formal_Subprogram --
----------------------------------------
- procedure Check_Overloaded_Formal_Subprogram (Formal : Entity_Id) is
- Temp_Formal : Entity_Id;
+ procedure Check_Overloaded_Formal_Subprogram (Formal : Node_Id) is
+ Temp_Formal : Node_Id;
begin
Temp_Formal := First (Formals);
@@ -1449,8 +1469,8 @@ package body Sem_Ch12 is
(F : Entity_Id;
A_F : Entity_Id) return Node_Id
is
- Prev : Node_Id;
- Act : Node_Id;
+ Prev : Node_Id;
+ Act : Node_Id;
begin
Is_Named_Assoc := False;
@@ -1937,7 +1957,7 @@ package body Sem_Ch12 is
-- take place e.g. within an enclosing generic unit.
if Has_Contracts (Analyzed_Formal)
- and then Expander_Active
+ and then (Expander_Active or GNATprove_Mode)
then
Build_Subprogram_Wrappers;
end if;
@@ -3121,7 +3141,6 @@ package body Sem_Ch12 is
if Present (Aspect_Specifications (Gen_Decl)) then
if No (Aspect_Specifications (N)) then
Set_Aspect_Specifications (N, New_List);
- Set_Has_Aspects (N);
end if;
declare
@@ -6253,7 +6272,7 @@ package body Sem_Ch12 is
while Present (Act) loop
Append_To (Actuals,
- Make_Identifier (Loc, Chars (Defining_Identifier (Act))));
+ Make_Identifier (Loc, Chars (Defining_Identifier (Act))));
Next (Act);
end loop;
@@ -6274,8 +6293,8 @@ package body Sem_Ch12 is
Specification => Spec_Node,
Declarations => New_List,
Handled_Statement_Sequence =>
- Make_Handled_Sequence_Of_Statements (Loc,
- Statements => New_List (Stmt)));
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_List (Stmt)));
return Body_Node;
end Build_Subprogram_Body_Wrapper;
@@ -7024,7 +7043,7 @@ package body Sem_Ch12 is
Astype := First_Subtype (E);
end if;
- Set_Size_Info (E, (Astype));
+ Set_Size_Info (E, Astype);
Copy_RM_Size (To => E, From => Astype);
Set_First_Rep_Item (E, First_Rep_Item (Astype));
@@ -7055,12 +7074,10 @@ package body Sem_Ch12 is
elsif Present (Associated_Formal_Package (E))
and then not Is_Generic_Formal (E)
then
- if Box_Present (Parent (Associated_Formal_Package (E))) then
- Check_Generic_Actuals (Renamed_Entity (E), True);
-
- else
- Check_Generic_Actuals (Renamed_Entity (E), False);
- end if;
+ Check_Generic_Actuals
+ (Renamed_Entity (E),
+ Is_Formal_Box =>
+ Box_Present (Parent (Associated_Formal_Package (E))));
Set_Is_Hidden (E, False);
end if;
@@ -11091,6 +11108,8 @@ package body Sem_Ch12 is
Set_Convention (Defining_Unit_Name (New_Spec), Convention_Intrinsic);
+ Copy_Ghost_Aspect (Formal, To => Decl_Node);
+
-- Eliminate the calls to it when optimization is enabled
Set_Is_Inlined (Defining_Unit_Name (New_Spec));
@@ -11873,7 +11892,7 @@ package body Sem_Ch12 is
Saved_SM : constant SPARK_Mode_Type := SPARK_Mode;
Saved_SMP : constant Node_Id := SPARK_Mode_Pragma;
Saved_SS : constant Suppress_Record := Scope_Suppress;
- Saved_Warn : constant Warning_Record := Save_Warnings;
+ Saved_Warn : constant Warnings_State := Save_Warnings;
Act_Body : Node_Id;
Act_Body_Id : Entity_Id;
@@ -12410,7 +12429,7 @@ package body Sem_Ch12 is
Saved_SM : constant SPARK_Mode_Type := SPARK_Mode;
Saved_SMP : constant Node_Id := SPARK_Mode_Pragma;
Saved_SS : constant Suppress_Record := Scope_Suppress;
- Saved_Warn : constant Warning_Record := Save_Warnings;
+ Saved_Warn : constant Warnings_State := Save_Warnings;
Act_Body : Node_Id;
Act_Body_Id : Entity_Id;
@@ -14086,7 +14105,7 @@ package body Sem_Ch12 is
-- a full view, then we'll retrieve that.
if Ekind (A_Gen_T) = E_Incomplete_Type
- and then not Present (Full_View (Act_T))
+ and then No (Full_View (Act_T))
then
null;
@@ -14413,7 +14432,7 @@ package body Sem_Ch12 is
is
Comp_Unit : constant Node_Id := Cunit (Get_Source_Unit (Spec));
Saved_Style_Check : constant Boolean := Style_Check;
- Saved_Warnings : constant Warning_Record := Save_Warnings;
+ Saved_Warn : constant Warnings_State := Save_Warnings;
True_Parent : Node_Id;
Inst_Node : Node_Id;
OK : Boolean;
@@ -14744,7 +14763,7 @@ package body Sem_Ch12 is
Expander_Mode_Save_And_Set (True);
Load_Needed_Body (Comp_Unit, OK);
Opt.Style_Check := Saved_Style_Check;
- Restore_Warnings (Saved_Warnings);
+ Restore_Warnings (Saved_Warn);
Expander_Mode_Restore;
if not OK
@@ -15458,7 +15477,7 @@ package body Sem_Ch12 is
end loop;
end if;
- Exchange_Declarations (Node (M));
+ Exchange_Declarations (Typ);
Next_Elmt (M);
end loop;
@@ -17306,13 +17325,11 @@ package body Sem_Ch12 is
else
declare
- Act_Iface_List : Elist_Id;
- Iface : Node_Id;
- Iface_Ent : Entity_Id;
+ Iface : Node_Id;
+ Iface_Ent : Entity_Id;
begin
Iface := First (Abstract_Interface_List (Formal));
- Collect_Interfaces (Def_Sub, Act_Iface_List);
while Present (Iface) loop
Iface_Ent := Entity (Iface);
diff --git a/gcc/ada/sem_ch12.ads b/gcc/ada/sem_ch12.ads
index 58a9455..69c9d64 100644
--- a/gcc/ada/sem_ch12.ads
+++ b/gcc/ada/sem_ch12.ads
@@ -27,15 +27,15 @@ with Inline; use Inline;
with Types; use Types;
package Sem_Ch12 is
- procedure Analyze_Generic_Package_Declaration (N : Node_Id);
- procedure Analyze_Generic_Subprogram_Declaration (N : Node_Id);
- procedure Analyze_Package_Instantiation (N : Node_Id);
- procedure Analyze_Procedure_Instantiation (N : Node_Id);
- procedure Analyze_Function_Instantiation (N : Node_Id);
- procedure Analyze_Formal_Object_Declaration (N : Node_Id);
- procedure Analyze_Formal_Type_Declaration (N : Node_Id);
- procedure Analyze_Formal_Subprogram_Declaration (N : Node_Id);
- procedure Analyze_Formal_Package_Declaration (N : Node_Id);
+ procedure Analyze_Generic_Package_Declaration (N : Node_Id);
+ procedure Analyze_Generic_Subprogram_Declaration (N : Node_Id);
+ procedure Analyze_Package_Instantiation (N : Node_Id);
+ procedure Analyze_Procedure_Instantiation (N : Node_Id);
+ procedure Analyze_Function_Instantiation (N : Node_Id);
+ procedure Analyze_Formal_Object_Declaration (N : Node_Id);
+ procedure Analyze_Formal_Type_Declaration (N : Node_Id);
+ procedure Analyze_Formal_Subprogram_Declaration (N : Node_Id);
+ procedure Analyze_Formal_Package_Declaration (N : Node_Id);
procedure Start_Generic;
-- Must be invoked before starting to process a generic spec or body
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index 54b10dd..618f935 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Accessibility; use Accessibility;
with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
@@ -1271,7 +1272,7 @@ package body Sem_Ch13 is
| Aspect_Full_Access_Only
| Aspect_Import
and then (A_Id /= Aspect_Preelaborable_Initialization
- or else not Present (Expression (ASN)))
+ or else No (Expression (ASN)))
then
Make_Pragma_From_Boolean_Aspect (ASN);
end if;
@@ -1327,7 +1328,7 @@ package body Sem_Ch13 is
if not Is_Entity_Name (Expression (ASN))
or else not Is_Object (Entity (Expression (ASN)))
or else
- not Present (Find_Aspect (Etype (Expression (ASN)),
+ No (Find_Aspect (Etype (Expression (ASN)),
Aspect_Storage_Model_Type))
then
Error_Msg_N
@@ -1915,7 +1916,7 @@ package body Sem_Ch13 is
-- aspects are replaced with pragmas at the freeze point in
-- Make_Pragma_From_Boolean_Aspect.
- if not Present (Expr)
+ if No (Expr)
or else Is_True (Static_Boolean (Expr))
then
if A_Id = Aspect_Import then
@@ -2399,16 +2400,17 @@ package body Sem_Ch13 is
if not Is_Expression_Function (E)
and then
- not (Extensions_Allowed and then Is_Imported_Intrinsic)
+ not (All_Extensions_Allowed and then Is_Imported_Intrinsic)
then
- if Extensions_Allowed then
+ if All_Extensions_Allowed then
Error_Msg_N
("aspect % requires intrinsic or expression function",
Aspect);
elsif Is_Imported_Intrinsic then
Error_Msg_GNAT_Extension
- ("aspect % on intrinsic function", Sloc (Aspect));
+ ("aspect % on intrinsic function", Sloc (Aspect),
+ Is_Core_Extension => True);
else
Error_Msg_N
@@ -4212,7 +4214,7 @@ package body Sem_Ch13 is
goto Continue;
when Aspect_Designated_Storage_Model =>
- if not Extensions_Allowed then
+ if not All_Extensions_Allowed then
Error_Msg_GNAT_Extension ("aspect %", Sloc (Aspect));
elsif not Is_Type (E)
@@ -4227,7 +4229,7 @@ package body Sem_Ch13 is
goto Continue;
when Aspect_Storage_Model_Type =>
- if not Extensions_Allowed then
+ if not All_Extensions_Allowed then
Error_Msg_GNAT_Extension ("aspect %", Sloc (Aspect));
elsif not Is_Type (E)
@@ -7309,6 +7311,21 @@ package body Sem_Ch13 is
Set_Esize (U_Ent, Size);
end if;
+ -- As of RM 13.1, only confirming size
+ -- (i.e. (Size = Esize (Etyp))) for aliased object of
+ -- elementary type must be supported.
+ -- GNAT rejects nonconfirming size for such object.
+
+ if Is_Aliased (U_Ent)
+ and then Is_Elementary_Type (Etyp)
+ and then Known_Esize (U_Ent)
+ and then Size /= Esize (Etyp)
+ then
+ Error_Msg_N
+ ("nonconfirming Size for aliased object is not "
+ & "supported", N);
+ end if;
+
Set_Has_Size_Clause (U_Ent);
end;
end if;
@@ -7547,7 +7564,7 @@ package body Sem_Ch13 is
else
Analyze_And_Resolve (Expr);
- if not Present (Get_Rep_Pragma
+ if No (Get_Rep_Pragma
(Etype (Expr), Name_Simple_Storage_Pool_Type))
then
Error_Msg_N
@@ -9927,9 +9944,9 @@ package body Sem_Ch13 is
-- generally suppress the message in instantiations, and also
-- if it involves internal names.
- if Opt.List_Inherited_Aspects
+ if List_Inherited_Aspects
and then not Is_Generic_Actual_Type (Typ)
- and then Instantiation_Depth (Sloc (Typ)) = 0
+ and then Instantiation_Location (Sloc (Typ)) = No_Location
and then not Is_Internal_Name (Chars (T))
and then not Is_Internal_Name (Chars (Typ))
then
@@ -15713,6 +15730,12 @@ package body Sem_Ch13 is
return;
end if;
+ elsif No (Add_Named_Subp)
+ and then No (Add_Unnamed_Subp)
+ and then No (Assign_Indexed_Subp)
+ then
+ Error_Msg_N ("incomplete specification for aggregate", N);
+
elsif Present (New_Indexed_Subp) /= Present (Assign_Indexed_Subp) then
Error_Msg_N ("incomplete specification for indexed aggregate", N);
end if;
@@ -16511,7 +16534,7 @@ package body Sem_Ch13 is
begin
for FP of Profiles loop
- if not Present (Formal) then
+ if No (Formal) then
Is_Error := True;
Report_Argument_Error ("missing formal of }", Subt => FP.Subt);
exit;
@@ -16582,7 +16605,7 @@ package body Sem_Ch13 is
-- If Addr_Type is not present as the first association, then we default
-- it to System.Address.
- elsif not Present (Addr_Type) then
+ elsif No (Addr_Type) then
Addr_Type := RTE (RE_Address);
end if;
@@ -17251,7 +17274,7 @@ package body Sem_Ch13 is
Param_Type := Standard_String;
end if;
- if not Overloaded and then not Present (Entity (Func_Name)) then
+ if not Overloaded and then No (Entity (Func_Name)) then
-- The aspect is specified by a subprogram name, which
-- may be an operator name given originally by a string.
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index 00c2e67..5334e48 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Accessibility; use Accessibility;
with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
@@ -87,6 +88,7 @@ with Tbuild; use Tbuild;
with Ttypes; use Ttypes;
with Uintp; use Uintp;
with Urealp; use Urealp;
+with Warnsw; use Warnsw;
package body Sem_Ch3 is
@@ -1318,7 +1320,8 @@ package body Sem_Ch3 is
Check_Restriction (No_Access_Subprograms, T_Def);
- Create_Extra_Formals (Desig_Type);
+ -- Addition of extra formals must be delayed till the freeze point so
+ -- that we know the convention.
end Access_Subprogram_Declaration;
----------------------------
@@ -2668,7 +2671,7 @@ package body Sem_Ch3 is
-- Is_Conjunction_Of_Formal_Preelab_Init_Attributes goes to
-- Original_Node if needed, hence test for Standard_False.)
- if not Present (Expr)
+ if No (Expr)
or else (Is_Entity_Name (Expr)
and then Entity (Expr) = Standard_True)
or else
@@ -2940,7 +2943,8 @@ package body Sem_Ch3 is
-- Verify that all abstract states found in any package declared in
-- the input declarative list have proper refinements. The check is
-- performed only when the context denotes a block, entry, package,
- -- protected, subprogram, or task body (SPARK RM 7.2.2(3)).
+ -- protected, subprogram, or task body (SPARK RM 7.1.4(4) and SPARK
+ -- RM 7.2.2(3)).
Check_State_Refinements (Context);
@@ -3519,7 +3523,7 @@ package body Sem_Ch3 is
-- Initialize the list of primitive operations to an empty list,
-- to cover tagged types as well as untagged types. For untagged
-- types this is used either to analyze the call as legal when
- -- Extensions_Allowed is True, or to issue a better error message
+ -- Core_Extensions_Allowed is True, or to issue a better error message
-- otherwise.
Set_Direct_Primitive_Operations (T, New_Elmt_List);
@@ -3777,6 +3781,11 @@ package body Sem_Ch3 is
-- Obj_Decl carrying type Obj_Typ has explicit initialization. Emit
-- a compile-time warning if this is not the case.
+ procedure Check_Return_Subtype_Indication (Obj_Decl : Node_Id);
+ -- Check that the return subtype indication properly matches the result
+ -- subtype of the function in an extended return object declaration, as
+ -- required by RM 6.5(5.1/2-5.3/2).
+
function Count_Tasks (T : Entity_Id) return Uint;
-- This function is called when a non-generic library level object of a
-- task type is declared. Its function is to count the static number of
@@ -3950,6 +3959,134 @@ package body Sem_Ch3 is
Check_Component (Obj_Typ, Obj_Decl);
end Check_For_Null_Excluding_Components;
+ -------------------------------------
+ -- Check_Return_Subtype_Indication --
+ -------------------------------------
+
+ procedure Check_Return_Subtype_Indication (Obj_Decl : Node_Id) is
+ Obj_Id : constant Entity_Id := Defining_Identifier (Obj_Decl);
+ Obj_Typ : constant Entity_Id := Etype (Obj_Id);
+ Func_Id : constant Entity_Id := Return_Applies_To (Scope (Obj_Id));
+ R_Typ : constant Entity_Id := Etype (Func_Id);
+ Indic : constant Node_Id :=
+ Object_Definition (Original_Node (Obj_Decl));
+
+ procedure Error_No_Match (N : Node_Id);
+ -- Output error messages for case where types do not statically
+ -- match. N is the location for the messages.
+
+ --------------------
+ -- Error_No_Match --
+ --------------------
+
+ procedure Error_No_Match (N : Node_Id) is
+ begin
+ Error_Msg_N
+ ("subtype must statically match function result subtype", N);
+
+ if not Predicates_Match (Obj_Typ, R_Typ) then
+ Error_Msg_Node_2 := R_Typ;
+ Error_Msg_NE
+ ("\predicate of& does not match predicate of&",
+ N, Obj_Typ);
+ end if;
+ end Error_No_Match;
+
+ -- Start of processing for Check_Return_Subtype_Indication
+
+ begin
+ -- First, avoid cascaded errors
+
+ if Error_Posted (Obj_Decl) or else Error_Posted (Indic) then
+ return;
+ end if;
+
+ -- "return access T" case; check that the return statement also has
+ -- "access T", and that the subtypes statically match:
+ -- if this is an access to subprogram the signatures must match.
+
+ if Is_Anonymous_Access_Type (R_Typ) then
+ if Is_Anonymous_Access_Type (Obj_Typ) then
+ if Ekind (Designated_Type (Obj_Typ)) /= E_Subprogram_Type
+ then
+ if Base_Type (Designated_Type (Obj_Typ)) /=
+ Base_Type (Designated_Type (R_Typ))
+ or else not Subtypes_Statically_Match (Obj_Typ, R_Typ)
+ then
+ Error_No_Match (Subtype_Mark (Indic));
+ end if;
+
+ else
+ -- For two anonymous access to subprogram types, the types
+ -- themselves must be type conformant.
+
+ if not Conforming_Types
+ (Obj_Typ, R_Typ, Fully_Conformant)
+ then
+ Error_No_Match (Indic);
+ end if;
+ end if;
+
+ else
+ Error_Msg_N ("must use anonymous access type", Indic);
+ end if;
+
+ -- If the return object is of an anonymous access type, then report
+ -- an error if the function's result type is not also anonymous.
+
+ elsif Is_Anonymous_Access_Type (Obj_Typ) then
+ pragma Assert (not Is_Anonymous_Access_Type (R_Typ));
+ Error_Msg_N
+ ("anonymous access not allowed for function with named access "
+ & "result", Indic);
+
+ -- Subtype indication case: check that the return object's type is
+ -- covered by the result type, and that the subtypes statically match
+ -- when the result subtype is constrained. Also handle record types
+ -- with unknown discriminants for which we have built the underlying
+ -- record view. Coverage is needed to allow specific-type return
+ -- objects when the result type is class-wide (see AI05-32).
+
+ elsif Covers (Base_Type (R_Typ), Base_Type (Obj_Typ))
+ or else (Is_Underlying_Record_View (Base_Type (Obj_Typ))
+ and then
+ Covers
+ (Base_Type (R_Typ),
+ Underlying_Record_View (Base_Type (Obj_Typ))))
+ then
+ -- A null exclusion may be present on the return type, on the
+ -- function specification, on the object declaration or on the
+ -- subtype itself.
+
+ if Is_Access_Type (R_Typ)
+ and then
+ (Can_Never_Be_Null (R_Typ)
+ or else Null_Exclusion_Present (Parent (Func_Id))) /=
+ Can_Never_Be_Null (Obj_Typ)
+ then
+ Error_No_Match (Indic);
+ end if;
+
+ -- AI05-103: for elementary types, subtypes must statically match
+
+ if Is_Constrained (R_Typ) or else Is_Access_Type (R_Typ) then
+ if not Subtypes_Statically_Match (Obj_Typ, R_Typ) then
+ Error_No_Match (Indic);
+ end if;
+ end if;
+
+ -- All remaining cases are illegal
+
+ -- Note: previous versions of this subprogram allowed the return
+ -- value to be the ancestor of the return type if the return type
+ -- was a null extension. This was plainly incorrect.
+
+ else
+ Error_Msg_N
+ ("wrong type for return_subtype_indication", Indic);
+ end if;
+ end Check_Return_Subtype_Indication;
+
-----------------
-- Count_Tasks --
-----------------
@@ -4721,6 +4858,26 @@ package body Sem_Ch3 is
Expand_Sliding_Conversion (E, T);
end if;
+ if In_Spec_Expression and then In_Declare_Expr > 0 then
+ -- It is too early to be doing expansion-ish things,
+ -- so exit early. But we have to set Ekind (Id) now so
+ -- that subsequent uses of this entity are not rejected
+ -- via the same mechanism that (correctly) rejects
+ -- "X : Integer := X;".
+
+ if Constant_Present (N) then
+ Mutate_Ekind (Id, E_Constant);
+ Set_Is_True_Constant (Id);
+ else
+ Mutate_Ekind (Id, E_Variable);
+ if Present (E) then
+ Set_Has_Initial_Value (Id);
+ end if;
+ end if;
+
+ goto Leave;
+ end if;
+
Expand_Subtype_From_Expr
(N => N,
Unc_Type => T,
@@ -5023,6 +5180,12 @@ package body Sem_Ch3 is
end if;
end if;
+ -- Check specific legality rules for a return object
+
+ if Is_Return_Object (Id) then
+ Check_Return_Subtype_Indication (N);
+ end if;
+
-- Some simple constant-propagation: if the expression is a constant
-- string initialized with a literal, share the literal. This avoids
-- a run-time copy.
@@ -5730,7 +5893,7 @@ package body Sem_Ch3 is
-- operations to an empty list.
if Is_Tagged_Type (Id)
- or else Extensions_Allowed
+ or else Core_Extensions_Allowed
then
Set_Direct_Primitive_Operations (Id, New_Elmt_List);
end if;
@@ -11050,7 +11213,7 @@ package body Sem_Ch3 is
-- with the aliased entity (otherwise we generate a duplicated
-- error message).
- and then not Present (Interface_Alias (Subp))
+ and then No (Interface_Alias (Subp))
then
if Present (Alias_Subp) then
@@ -11768,11 +11931,9 @@ package body Sem_Ch3 is
Insert_Before (Typ_Decl, Decl);
Analyze (Decl);
- -- If an access to subprogram, create the extra formals
-
- if Present (Acc_Def) then
- Create_Extra_Formals (Designated_Type (Anon_Access));
- end if;
+ -- At first sight we could add here the extra formals of an access to
+ -- subprogram; however, it must delayed till the freeze point so that
+ -- we know the convention.
if Nkind (Comp_Def) = N_Component_Definition then
Rewrite (Comp_Def,
@@ -14541,7 +14702,7 @@ package body Sem_Ch3 is
-- in various places for an Empty upper bound, and in any case it
-- accurately characterizes the index's range of values.
- if Nkind (S) = N_Range and then not Present (High_Bound (S)) then
+ if Nkind (S) = N_Range and then No (High_Bound (S)) then
Is_FLB_Index := True;
Set_High_Bound (S, Type_High_Bound (T));
end if;
@@ -16033,12 +16194,12 @@ package body Sem_Ch3 is
Next_Formal (Formal);
end loop;
- -- Extra formals are shared between the parent subprogram and the
- -- derived subprogram (implicit in the above copy of formals), unless
- -- the parent type is a limited interface type; hence we must inherit
- -- also the reference to the first extra formal. When the parent type is
- -- an interface the extra formals will be added when the subprogram is
- -- frozen (see Freeze.Freeze_Subprogram).
+ -- Extra formals are shared between the parent subprogram and this
+ -- internal entity built by Derive_Subprogram (implicit in the above
+ -- copy of formals), unless the parent type is a limited interface type;
+ -- hence we must inherit also the reference to the first extra formal.
+ -- When the parent type is an interface, the extra formals will be added
+ -- when the tagged type is frozen (see Expand_Freeze_Record_Type).
if not Is_Limited_Interface (Parent_Type) then
Set_Extra_Formals (New_Subp, Extra_Formals (Parent_Subp));
@@ -16079,7 +16240,7 @@ package body Sem_Ch3 is
Copy_Strub_Mode (New_Subp, Alias (New_Subp));
-- Derived subprograms of a tagged type must inherit the convention
- -- of the parent subprogram (a requirement of AI-117). Derived
+ -- of the parent subprogram (a requirement of AI95-117). Derived
-- subprograms of untagged types simply get convention Ada by default.
-- If the derived type is a tagged generic formal type with unknown
@@ -16497,15 +16658,15 @@ package body Sem_Ch3 is
-- Local variables
- Alias_Subp : Entity_Id;
- Act_List : Elist_Id;
- Act_Elmt : Elmt_Id;
- Act_Subp : Entity_Id := Empty;
- Elmt : Elmt_Id;
- Need_Search : Boolean := False;
- New_Subp : Entity_Id := Empty;
- Parent_Base : Entity_Id;
- Subp : Entity_Id;
+ Alias_Subp : Entity_Id;
+ Act_List : Elist_Id;
+ Act_Elmt : Elmt_Id;
+ Act_Subp : Entity_Id := Empty;
+ Elmt : Elmt_Id;
+ Need_Search : Boolean := False;
+ New_Subp : Entity_Id;
+ Parent_Base : Entity_Id;
+ Subp : Entity_Id;
-- Start of processing for Derive_Subprograms
@@ -16720,9 +16881,9 @@ package body Sem_Ch3 is
(Is_Generic_Unit
(Scope (Find_Dispatching_Type (Alias_Subp)))
or else
- Instantiation_Depth
- (Sloc (Find_Dispatching_Type (Alias_Subp))) > 0);
-
+ Instantiation_Location
+ (Sloc (Find_Dispatching_Type (Alias_Subp)))
+ /= No_Location);
declare
Iface_Prim_Loc : constant Source_Ptr :=
Original_Location (Sloc (Alias_Subp));
@@ -16784,7 +16945,7 @@ package body Sem_Ch3 is
-- have such primitives.
if Present (Generic_Actual)
- and then not Present (Act_Subp)
+ and then No (Act_Subp)
and then Is_Limited_Interface (Parent_Base)
and then Is_Predefined_Interface_Primitive (Subp)
then
@@ -20145,6 +20306,7 @@ package body Sem_Ch3 is
case Nkind (Original_Node (Exp)) is
when N_Aggregate
+ | N_Delta_Aggregate
| N_Extension_Aggregate
| N_Function_Call
| N_Op
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index 6824941..da5aa5f 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Accessibility; use Accessibility;
with Aspects; use Aspects;
with Atree; use Atree;
with Debug; use Debug;
@@ -43,6 +44,7 @@ with Opt; use Opt;
with Output; use Output;
with Restrict; use Restrict;
with Rident; use Rident;
+with Rtsfind; use Rtsfind;
with Sem; use Sem;
with Sem_Aux; use Sem_Aux;
with Sem_Case; use Sem_Case;
@@ -65,6 +67,7 @@ with Sinfo.Utils; use Sinfo.Utils;
with Snames; use Snames;
with Tbuild; use Tbuild;
with Uintp; use Uintp;
+with Warnsw; use Warnsw;
package body Sem_Ch4 is
@@ -731,43 +734,16 @@ package body Sem_Ch4 is
end;
end if;
- -- Check for missing initialization. Skip this check if we already
- -- had errors on analyzing the allocator, since in that case these
- -- are probably cascaded errors.
+ -- Check for missing initialization. Skip this check if the allocator
+ -- is made for a special return object or if we already had errors on
+ -- analyzing the allocator since, in that case, these are very likely
+ -- cascaded errors.
if not Is_Definite_Subtype (Type_Id)
+ and then not For_Special_Return_Object (N)
and then Serious_Errors_Detected = Sav_Errs
then
- -- The build-in-place machinery may produce an allocator when
- -- the designated type is indefinite but the underlying type is
- -- not. In this case the unknown discriminants are meaningless
- -- and should not trigger error messages. Check the parent node
- -- because the allocator is marked as coming from source.
-
- if Present (Underlying_Type (Type_Id))
- and then Is_Definite_Subtype (Underlying_Type (Type_Id))
- and then not Comes_From_Source (Parent (N))
- then
- null;
-
- -- An unusual case arises when the parent of a derived type is
- -- a limited record extension with unknown discriminants, and
- -- its full view has no discriminants.
- --
- -- A more general fix might be to create the proper underlying
- -- type for such a derived type, but it is a record type with
- -- no private attributes, so this required extending the
- -- meaning of this attribute. ???
-
- elsif Ekind (Etype (Type_Id)) = E_Record_Type_With_Private
- and then Present (Underlying_Type (Etype (Type_Id)))
- and then
- not Has_Discriminants (Underlying_Type (Etype (Type_Id)))
- and then not Comes_From_Source (Parent (N))
- then
- null;
-
- elsif Is_Class_Wide_Type (Type_Id) then
+ if Is_Class_Wide_Type (Type_Id) then
Error_Msg_N
("initialization required in class-wide allocation", N);
@@ -840,6 +816,27 @@ package body Sem_Ch4 is
Error_Msg_N ("cannot allocate abstract object", E);
end if;
+ Set_Etype (N, Acc_Type);
+
+ -- If this is an allocator for the return stack, then no restriction may
+ -- be violated since it's just a low-level access to the primary stack.
+
+ if Nkind (Parent (N)) = N_Object_Declaration
+ and then Is_Entity_Name (Object_Definition (Parent (N)))
+ and then Is_Access_Type (Entity (Object_Definition (Parent (N))))
+ then
+ declare
+ Pool : constant Entity_Id :=
+ Associated_Storage_Pool
+ (Root_Type (Entity (Object_Definition (Parent (N)))));
+
+ begin
+ if Present (Pool) and then Is_RTE (Pool, RE_RS_Pool) then
+ goto Leave;
+ end if;
+ end;
+ end if;
+
if Has_Task (Designated_Type (Acc_Type)) then
Check_Restriction (No_Tasking, N);
Check_Restriction (Max_Tasks, N);
@@ -891,12 +888,11 @@ package body Sem_Ch4 is
end if;
end if;
- Set_Etype (N, Acc_Type);
-
if not Is_Library_Level_Entity (Acc_Type) then
Check_Restriction (No_Local_Allocators, N);
end if;
+ <<Leave>>
if Serious_Errors_Detected > Sav_Errs then
Set_Error_Posted (N);
Set_Etype (N, Any_Type);
@@ -1740,6 +1736,70 @@ package body Sem_Ch4 is
return;
end if;
+ -- The expression must be of a discrete type which must be determinable
+ -- independently of the context in which the expression occurs, but
+ -- using the fact that the expression must be of a discrete type.
+ -- Moreover, the type this expression must not be a character literal
+ -- (which is always ambiguous).
+
+ -- If error already reported by Resolve, nothing more to do
+
+ if Exp_Btype = Any_Discrete or else Exp_Btype = Any_Type then
+ return;
+
+ -- Special case message for character literal
+
+ elsif Exp_Btype = Any_Character then
+ Error_Msg_N
+ ("character literal as case expression is ambiguous", Expr);
+ return;
+ end if;
+
+ -- If the case expression is a formal object of mode in out, then
+ -- treat it as having a nonstatic subtype by forcing use of the base
+ -- type (which has to get passed to Check_Case_Choices below). Also
+ -- use base type when the case expression is parenthesized.
+
+ if Paren_Count (Expr) > 0
+ or else (Is_Entity_Name (Expr)
+ and then Ekind (Entity (Expr)) = E_Generic_In_Out_Parameter)
+ then
+ Exp_Type := Exp_Btype;
+ end if;
+
+ -- The case expression alternatives cover the range of a static subtype
+ -- subject to aspect Static_Predicate. Do not check the choices when the
+ -- case expression has not been fully analyzed yet because this may lead
+ -- to bogus errors.
+
+ if Is_OK_Static_Subtype (Exp_Type)
+ and then Has_Static_Predicate_Aspect (Exp_Type)
+ and then In_Spec_Expression
+ then
+ null;
+
+ -- Call Analyze_Choices and Check_Choices to do the rest of the work
+
+ else
+ Analyze_Choices (Alternatives (N), Exp_Type);
+ Check_Choices (N, Alternatives (N), Exp_Type, Others_Present);
+
+ if Exp_Type = Universal_Integer and then not Others_Present then
+ Error_Msg_N
+ ("case on universal integer requires OTHERS choice", Expr);
+ return;
+ end if;
+ end if;
+
+ -- RM 4.5.7(10/3): If the case_expression is the operand of a type
+ -- conversion, the type of the case_expression is the target type
+ -- of the conversion.
+
+ if Nkind (Parent (N)) = N_Type_Conversion then
+ Set_Etype (N, Etype (Parent (N)));
+ return;
+ end if;
+
-- Loop through the interpretations of the first expression and check
-- the other expressions if present.
@@ -1763,25 +1823,6 @@ package body Sem_Ch4 is
end loop;
end if;
- -- The expression must be of a discrete type which must be determinable
- -- independently of the context in which the expression occurs, but
- -- using the fact that the expression must be of a discrete type.
- -- Moreover, the type this expression must not be a character literal
- -- (which is always ambiguous).
-
- -- If error already reported by Resolve, nothing more to do
-
- if Exp_Btype = Any_Discrete or else Exp_Btype = Any_Type then
- return;
-
- -- Special casee message for character literal
-
- elsif Exp_Btype = Any_Character then
- Error_Msg_N
- ("character literal as case expression is ambiguous", Expr);
- return;
- end if;
-
-- If no possible interpretation has been found, the type of the wrong
-- alternative doesn't match any interpretation of the FIRST expression.
@@ -1829,43 +1870,6 @@ package body Sem_Ch4 is
Etype (Second_Expr));
end if;
end if;
-
- return;
- end if;
-
- -- If the case expression is a formal object of mode in out, then
- -- treat it as having a nonstatic subtype by forcing use of the base
- -- type (which has to get passed to Check_Case_Choices below). Also
- -- use base type when the case expression is parenthesized.
-
- if Paren_Count (Expr) > 0
- or else (Is_Entity_Name (Expr)
- and then Ekind (Entity (Expr)) = E_Generic_In_Out_Parameter)
- then
- Exp_Type := Exp_Btype;
- end if;
-
- -- The case expression alternatives cover the range of a static subtype
- -- subject to aspect Static_Predicate. Do not check the choices when the
- -- case expression has not been fully analyzed yet because this may lead
- -- to bogus errors.
-
- if Is_OK_Static_Subtype (Exp_Type)
- and then Has_Static_Predicate_Aspect (Exp_Type)
- and then In_Spec_Expression
- then
- null;
-
- -- Call Analyze_Choices and Check_Choices to do the rest of the work
-
- else
- Analyze_Choices (Alternatives (N), Exp_Type);
- Check_Choices (N, Alternatives (N), Exp_Type, Others_Present);
-
- if Exp_Type = Universal_Integer and then not Others_Present then
- Error_Msg_N
- ("case on universal integer requires OTHERS choice", Expr);
- end if;
end if;
end Analyze_Case_Expression;
@@ -2555,6 +2559,15 @@ package body Sem_Ch4 is
Analyze_Expression (Else_Expr);
end if;
+ -- RM 4.5.7(10/3): If the if_expression is the operand of a type
+ -- conversion, the type of the if_expression is the target type
+ -- of the conversion.
+
+ if Nkind (Parent (N)) = N_Type_Conversion then
+ Set_Etype (N, Etype (Parent (N)));
+ return;
+ end if;
+
-- Loop through the interpretations of the THEN expression and check the
-- ELSE expression if present.
@@ -4323,16 +4336,14 @@ package body Sem_Ch4 is
----------------------------------
procedure Analyze_Qualified_Expression (N : Node_Id) is
- Mark : constant Entity_Id := Subtype_Mark (N);
Expr : constant Node_Id := Expression (N);
+ Mark : constant Entity_Id := Subtype_Mark (N);
+
I : Interp_Index;
It : Interp;
T : Entity_Id;
begin
- Analyze_Expression (Expr);
-
- Set_Etype (N, Any_Type);
Find_Type (Mark);
T := Entity (Mark);
@@ -4353,6 +4364,8 @@ package body Sem_Ch4 is
Set_Etype (N, T);
+ Analyze_Expression (Expr);
+
if T = Any_Type then
return;
end if;
@@ -4389,8 +4402,6 @@ package body Sem_Ch4 is
end loop;
end if;
end if;
-
- Set_Etype (N, T);
end Analyze_Qualified_Expression;
-----------------------------------
@@ -5423,7 +5434,8 @@ package body Sem_Ch4 is
-- untagged record types.
if Ada_Version >= Ada_2005
- and then (Is_Tagged_Type (Prefix_Type) or else Extensions_Allowed)
+ and then (Is_Tagged_Type (Prefix_Type)
+ or else Core_Extensions_Allowed)
and then not Is_Concurrent_Type (Prefix_Type)
then
if Nkind (Parent (N)) = N_Generic_Association
@@ -5499,7 +5511,7 @@ package body Sem_Ch4 is
-- Extension feature: Also support calls with prefixed views for
-- untagged private types.
- if Extensions_Allowed then
+ if Core_Extensions_Allowed then
if Try_Object_Operation (N) then
return;
end if;
@@ -5760,7 +5772,7 @@ package body Sem_Ch4 is
-- Extension feature: Also support calls with prefixed views for
-- untagged types.
- elsif Extensions_Allowed
+ elsif Core_Extensions_Allowed
and then Try_Object_Operation (N)
then
return;
@@ -5949,9 +5961,9 @@ package body Sem_Ch4 is
It : Interp;
begin
+ Set_Etype (N, Any_Type);
Analyze_Expression (L);
Analyze_Expression (R);
- Set_Etype (N, Any_Type);
if not Is_Overloaded (L) then
if Root_Type (Etype (L)) = Standard_Boolean
@@ -6084,7 +6096,9 @@ package body Sem_Ch4 is
-----------------------------
procedure Analyze_Type_Conversion (N : Node_Id) is
- Expr : constant Node_Id := Expression (N);
+ Expr : constant Node_Id := Expression (N);
+ Mark : constant Entity_Id := Subtype_Mark (N);
+
Typ : Entity_Id;
begin
@@ -6101,11 +6115,13 @@ package body Sem_Ch4 is
-- Otherwise full type analysis is required, as well as some semantic
-- checks to make sure the argument of the conversion is appropriate.
- Find_Type (Subtype_Mark (N));
- Typ := Entity (Subtype_Mark (N));
+ Find_Type (Mark);
+ Typ := Entity (Mark);
Set_Etype (N, Typ);
- Check_Fully_Declared (Typ, N);
+
Analyze_Expression (Expr);
+
+ Check_Fully_Declared (Typ, N);
Validate_Remote_Type_Type_Conversion (N);
-- Only remaining step is validity checks on the argument. These
@@ -6228,10 +6244,12 @@ package body Sem_Ch4 is
----------------------------------
procedure Analyze_Unchecked_Expression (N : Node_Id) is
+ Expr : constant Node_Id := Expression (N);
+
begin
- Analyze (Expression (N), Suppress => All_Checks);
- Set_Etype (N, Etype (Expression (N)));
- Save_Interps (Expression (N), N);
+ Analyze (Expr, Suppress => All_Checks);
+ Set_Etype (N, Etype (Expr));
+ Save_Interps (Expr, N);
end Analyze_Unchecked_Expression;
---------------------------------------
@@ -6239,10 +6257,13 @@ package body Sem_Ch4 is
---------------------------------------
procedure Analyze_Unchecked_Type_Conversion (N : Node_Id) is
+ Expr : constant Node_Id := Expression (N);
+ Mark : constant Entity_Id := Subtype_Mark (N);
+
begin
- Find_Type (Subtype_Mark (N));
- Analyze_Expression (Expression (N));
- Set_Etype (N, Entity (Subtype_Mark (N)));
+ Find_Type (Mark);
+ Set_Etype (N, Entity (Mark));
+ Analyze_Expression (Expr);
end Analyze_Unchecked_Type_Conversion;
------------------------------------
@@ -9862,7 +9883,7 @@ package body Sem_Ch4 is
if (not Is_Tagged_Type (Obj_Type)
and then
- (not (Extensions_Allowed or Allow_Extensions)
+ (not (Core_Extensions_Allowed or Allow_Extensions)
or else not Present (Primitive_Operations (Obj_Type))))
or else Is_Incomplete_Type (Obj_Type)
then
@@ -9891,7 +9912,7 @@ package body Sem_Ch4 is
-- have homographic prefixed-view operations that could result
-- in an ambiguity, but handling properly may be tricky. ???)
- if (Extensions_Allowed or Allow_Extensions)
+ if (Core_Extensions_Allowed or Allow_Extensions)
and then not Prim_Result
and then Is_Named_Access_Type (Prev_Obj_Type)
and then Present (Direct_Primitive_Operations (Prev_Obj_Type))
diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index d0f00b3..344b3eb 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -66,6 +66,7 @@ with Targparm; use Targparm;
with Tbuild; use Tbuild;
with Ttypes; use Ttypes;
with Uintp; use Uintp;
+with Warnsw; use Warnsw;
package body Sem_Ch5 is
@@ -306,7 +307,8 @@ package body Sem_Ch5 is
-- get the actual subtype (needed for the unconstrained case). If the
-- operand is the actual in an entry declaration, then within the
-- accept statement it is replaced with a local renaming, which may
- -- also have an actual subtype.
+ -- also have an actual subtype. Likewise for a return object that
+ -- lives on the secondary stack.
if Is_Entity_Name (Opnd)
and then (Ekind (Entity (Opnd)) in E_Out_Parameter
@@ -317,7 +319,8 @@ package body Sem_Ch5 is
and then Nkind (Parent (Entity (Opnd))) =
N_Object_Renaming_Declaration
and then Nkind (Parent (Parent (Entity (Opnd)))) =
- N_Accept_Statement))
+ N_Accept_Statement)
+ or else Is_Secondary_Stack_Return_Object (Entity (Opnd)))
then
Opnd_Type := Get_Actual_Subtype (Opnd);
@@ -1042,8 +1045,7 @@ package body Sem_Ch5 is
if Ekind (Comp_Id) = E_Component
and then Nkind (Parent (Comp_Id))
= N_Component_Declaration
- and then
- not Present (Expression (Parent (Comp_Id)))
+ and then No (Expression (Parent (Comp_Id)))
then
return True;
end if;
@@ -1614,7 +1616,7 @@ package body Sem_Ch5 is
-- out non-discretes may resolve the ambiguity.
-- But GNAT extensions allow casing on non-discretes.
- elsif Extensions_Allowed and then Is_Overloaded (Exp) then
+ elsif Core_Extensions_Allowed and then Is_Overloaded (Exp) then
-- It would be nice if we could generate all the right error
-- messages by calling "Resolve (Exp, Any_Type);" in the
@@ -1632,7 +1634,7 @@ package body Sem_Ch5 is
-- Check for a GNAT-extension "general" case statement (i.e., one where
-- the type of the selecting expression is not discrete).
- elsif Extensions_Allowed
+ elsif Core_Extensions_Allowed
and then not Is_Discrete_Type (Etype (Exp))
then
Resolve (Exp, Etype (Exp));
@@ -1670,7 +1672,7 @@ package body Sem_Ch5 is
("(Ada 83) case expression cannot be of a generic type", Exp);
return;
- elsif not Extensions_Allowed
+ elsif not Core_Extensions_Allowed
and then not Is_Discrete_Type (Exp_Type)
then
Error_Msg_N
@@ -2192,7 +2194,7 @@ package body Sem_Ch5 is
if Is_Array_Type (Typ)
or else Is_Reversible_Iterator (Typ)
or else
- (Present (Find_Aspect (Typ, Aspect_Iterable))
+ (Has_Aspect (Typ, Aspect_Iterable)
and then
Present
(Get_Iterable_Type_Primitive (Typ, Name_Previous)))
@@ -2523,6 +2525,7 @@ package body Sem_Ch5 is
Subtype_Mark => New_Occurrence_Of (Typ, Loc),
Name =>
New_Copy_Tree (Iter_Name, New_Sloc => Loc));
+ Set_Comes_From_Iterator (Decl);
Insert_Actions (Parent (Parent (N)), New_List (Decl));
Rewrite (Name (N), New_Occurrence_Of (Id, Loc));
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index 7ad6408..f46ca46 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Accessibility; use Accessibility;
with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
@@ -34,6 +35,7 @@ with Einfo.Utils; use Einfo.Utils;
with Elists; use Elists;
with Errout; use Errout;
with Expander; use Expander;
+with Exp_Ch3; use Exp_Ch3;
with Exp_Ch6; use Exp_Ch6;
with Exp_Ch9; use Exp_Ch9;
with Exp_Dbug; use Exp_Dbug;
@@ -200,6 +202,13 @@ package body Sem_Ch6 is
-- This procedure makes S, a new overloaded entity, into the first visible
-- entity with that name.
+ function Has_Reliable_Extra_Formals (E : Entity_Id) return Boolean;
+ -- E is the entity for a subprogram spec. Returns False for abstract
+ -- predefined dispatching primitives of Root_Controlled since they
+ -- cannot have extra formals (this is required to build the runtime);
+ -- it also returns False for predefined stream dispatching operations
+ -- not emitted by the frontend. Otherwise returns True.
+
function Is_Non_Overriding_Operation
(Prev_E : Entity_Id;
New_E : Entity_Id) return Boolean;
@@ -264,7 +273,7 @@ package body Sem_Ch6 is
elsif Warn_On_Redundant_Constructs
and then not Is_Dispatching_Operation (Subp_Id)
- and then not Present (Overridden_Operation (Subp_Id))
+ and then No (Overridden_Operation (Subp_Id))
and then (not Is_Operator_Symbol_Name (Chars (Subp_Id))
or else Scop /= Scope (Etype (First_Formal (Subp_Id))))
then
@@ -737,14 +746,6 @@ package body Sem_Ch6 is
-- Ada 2022: Check that the return expression in a No_Return function
-- meets the conditions specified by RM 6.5.1(5.1/5).
- procedure Check_Return_Construct_Accessibility (Return_Stmt : Node_Id);
- -- Apply legality rule of 6.5 (5.9) to the access discriminants of an
- -- aggregate in a return statement.
-
- procedure Check_Return_Subtype_Indication (Obj_Decl : Node_Id);
- -- Check that the return_subtype_indication properly matches the result
- -- subtype of the function, as required by RM-6.5(5.1/2-5.3/2).
-
--------------------------------
-- Check_No_Return_Expression --
--------------------------------
@@ -773,645 +774,6 @@ package body Sem_Ch6 is
Return_Expr);
end Check_No_Return_Expression;
- ------------------------------------------
- -- Check_Return_Construct_Accessibility --
- ------------------------------------------
-
- procedure Check_Return_Construct_Accessibility (Return_Stmt : Node_Id) is
-
- function First_Selector (Assoc : Node_Id) return Node_Id;
- -- Obtain the first selector or choice from a given association
-
- function Is_Formal_Of_Current_Function
- (Assoc_Expr : Entity_Id) return Boolean;
- -- Predicate to test if a given expression associated with a
- -- discriminant is a formal parameter to the function in which the
- -- return construct we checking applies to.
-
- --------------------
- -- First_Selector --
- --------------------
-
- function First_Selector (Assoc : Node_Id) return Node_Id is
- begin
- if Nkind (Assoc) = N_Component_Association then
- return First (Choices (Assoc));
-
- elsif Nkind (Assoc) = N_Discriminant_Association then
- return (First (Selector_Names (Assoc)));
-
- else
- raise Program_Error;
- end if;
- end First_Selector;
-
- -----------------------------------
- -- Is_Formal_Of_Current_Function --
- -----------------------------------
-
- function Is_Formal_Of_Current_Function
- (Assoc_Expr : Entity_Id) return Boolean is
- begin
- return Is_Entity_Name (Assoc_Expr)
- and then Enclosing_Subprogram
- (Entity (Assoc_Expr)) = Scope_Id
- and then Is_Formal (Entity (Assoc_Expr));
- end Is_Formal_Of_Current_Function;
-
- -- Local declarations
-
- Assoc : Node_Id := Empty;
- -- Assoc should perhaps be renamed and declared as a
- -- Node_Or_Entity_Id since it encompasses not only component and
- -- discriminant associations, but also discriminant components within
- -- a type declaration or subtype indication ???
-
- Assoc_Expr : Node_Id;
- Assoc_Present : Boolean := False;
-
- Check_Cond : Node_Id;
- Unseen_Disc_Count : Nat := 0;
- Seen_Discs : Elist_Id;
- Disc : Entity_Id;
- First_Disc : Entity_Id;
-
- Obj_Decl : Node_Id;
- Return_Con : Node_Id;
- Unqual : Node_Id;
-
- -- Start of processing for Check_Return_Construct_Accessibility
-
- begin
- -- Only perform checks on record types with access discriminants and
- -- non-internally generated functions.
-
- if not Is_Record_Type (R_Type)
- or else not Has_Anonymous_Access_Discriminant (R_Type)
- or else not Comes_From_Source (Return_Stmt)
- then
- return;
- end if;
-
- -- We are only interested in return statements
-
- if Nkind (Return_Stmt) not in
- N_Extended_Return_Statement | N_Simple_Return_Statement
- then
- return;
- end if;
-
- -- Fetch the object from the return statement, in the case of a
- -- simple return statement the expression is part of the node.
-
- if Nkind (Return_Stmt) = N_Extended_Return_Statement then
- -- Obtain the object definition from the expanded extended return
-
- Return_Con := First (Return_Object_Declarations (Return_Stmt));
- while Present (Return_Con) loop
- -- Inspect the original node to avoid object declarations
- -- expanded into renamings.
-
- if Nkind (Original_Node (Return_Con)) = N_Object_Declaration
- and then Comes_From_Source (Original_Node (Return_Con))
- then
- exit;
- end if;
-
- Nlists.Next (Return_Con);
- end loop;
-
- pragma Assert (Present (Return_Con));
-
- -- Could be dealing with a renaming
-
- Return_Con := Original_Node (Return_Con);
- else
- Return_Con := Expression (Return_Stmt);
- end if;
-
- -- Obtain the accessibility levels of the expressions associated
- -- with all anonymous access discriminants, then generate a
- -- dynamic check or static error when relevant.
-
- -- Note the repeated use of Original_Node to avoid checking
- -- expanded code.
-
- Unqual := Original_Node (Unqualify (Original_Node (Return_Con)));
-
- -- Get the corresponding declaration based on the return object's
- -- identifier.
-
- if Nkind (Unqual) = N_Identifier
- and then Nkind (Parent (Entity (Unqual)))
- in N_Object_Declaration
- | N_Object_Renaming_Declaration
- then
- Obj_Decl := Original_Node (Parent (Entity (Unqual)));
-
- -- We were passed the object declaration directly, so use it
-
- elsif Nkind (Unqual) in N_Object_Declaration
- | N_Object_Renaming_Declaration
- then
- Obj_Decl := Unqual;
-
- -- Otherwise, we are looking at something else
-
- else
- Obj_Decl := Empty;
-
- end if;
-
- -- Hop up object renamings when present
-
- if Present (Obj_Decl)
- and then Nkind (Obj_Decl) = N_Object_Renaming_Declaration
- then
- while Nkind (Obj_Decl) = N_Object_Renaming_Declaration loop
-
- if Nkind (Name (Obj_Decl)) not in N_Entity then
- -- We may be looking at the expansion of iterators or
- -- some other internally generated construct, so it is safe
- -- to ignore checks ???
-
- if not Comes_From_Source (Obj_Decl) then
- return;
- end if;
-
- Obj_Decl := Original_Node
- (Declaration_Node
- (Ultimate_Prefix (Name (Obj_Decl))));
-
- -- Move up to the next declaration based on the object's name
-
- else
- Obj_Decl := Original_Node
- (Declaration_Node (Name (Obj_Decl)));
- end if;
- end loop;
- end if;
-
- -- Obtain the discriminant values from the return aggregate
-
- -- Do we cover extension aggregates correctly ???
-
- if Nkind (Unqual) = N_Aggregate then
- if Present (Expressions (Unqual)) then
- Assoc := First (Expressions (Unqual));
- else
- Assoc := First (Component_Associations (Unqual));
- end if;
-
- -- There is an object declaration for the return object
-
- elsif Present (Obj_Decl) then
- -- When a subtype indication is present in an object declaration
- -- it must contain the object's discriminants.
-
- if Nkind (Object_Definition (Obj_Decl)) = N_Subtype_Indication then
- Assoc := First
- (Constraints
- (Constraint
- (Object_Definition (Obj_Decl))));
-
- -- The object declaration contains an aggregate
-
- elsif Present (Expression (Obj_Decl)) then
-
- if Nkind (Unqualify (Expression (Obj_Decl))) = N_Aggregate then
- -- Grab the first associated discriminant expresion
-
- if Present
- (Expressions (Unqualify (Expression (Obj_Decl))))
- then
- Assoc := First
- (Expressions
- (Unqualify (Expression (Obj_Decl))));
- else
- Assoc := First
- (Component_Associations
- (Unqualify (Expression (Obj_Decl))));
- end if;
-
- -- Otherwise, this is something else
-
- else
- return;
- end if;
-
- -- There are no supplied discriminants in the object declaration,
- -- so get them from the type definition since they must be default
- -- initialized.
-
- -- Do we handle constrained subtypes correctly ???
-
- elsif Nkind (Unqual) = N_Object_Declaration then
- Assoc := First_Discriminant
- (Etype (Object_Definition (Obj_Decl)));
-
- else
- Assoc := First_Discriminant (Etype (Unqual));
- end if;
-
- -- When we are not looking at an aggregate or an identifier, return
- -- since any other construct (like a function call) is not
- -- applicable since checks will be performed on the side of the
- -- callee.
-
- else
- return;
- end if;
-
- -- Obtain the discriminants so we know the actual type in case the
- -- value of their associated expression gets implicitly converted.
-
- if No (Obj_Decl) then
- pragma Assert (Nkind (Unqual) = N_Aggregate);
-
- Disc := First_Discriminant (Etype (Unqual));
-
- else
- Disc := First_Discriminant
- (Etype (Defining_Identifier (Obj_Decl)));
- end if;
-
- -- Preserve the first discriminant for checking named associations
-
- First_Disc := Disc;
-
- -- Count the number of discriminants for processing an aggregate
- -- which includes an others.
-
- Disc := First_Disc;
- while Present (Disc) loop
- Unseen_Disc_Count := Unseen_Disc_Count + 1;
-
- Next_Discriminant (Disc);
- end loop;
-
- Seen_Discs := New_Elmt_List;
-
- -- Loop through each of the discriminants and check each expression
- -- associated with an anonymous access discriminant.
-
- -- When named associations occur in the return aggregate then
- -- discriminants can be in any order, so we need to ensure we do
- -- not continue to loop when all discriminants have been seen.
-
- Disc := First_Disc;
- while Present (Assoc)
- and then (Present (Disc) or else Assoc_Present)
- and then Unseen_Disc_Count > 0
- loop
- -- Handle named associations by searching through the names of
- -- the relevant discriminant components.
-
- if Nkind (Assoc)
- in N_Component_Association | N_Discriminant_Association
- then
- Assoc_Expr := Expression (Assoc);
- Assoc_Present := True;
-
- -- We currently don't handle box initialized discriminants,
- -- however, since default initialized anonymous access
- -- discriminants are a corner case, this is ok for now ???
-
- if Nkind (Assoc) = N_Component_Association
- and then Box_Present (Assoc)
- then
- if Nkind (First_Selector (Assoc)) = N_Others_Choice then
- Unseen_Disc_Count := 0;
- end if;
-
- -- When others is present we must identify a discriminant we
- -- haven't already seen so as to get the appropriate type for
- -- the static accessibility check.
-
- -- This works because all components within an others clause
- -- must have the same type.
-
- elsif Nkind (First_Selector (Assoc)) = N_Others_Choice then
-
- Disc := First_Disc;
- Outer : while Present (Disc) loop
- declare
- Current_Seen_Disc : Elmt_Id;
- begin
- -- Move through the list of identified discriminants
-
- Current_Seen_Disc := First_Elmt (Seen_Discs);
- while Present (Current_Seen_Disc) loop
- -- Exit the loop when we found a match
-
- exit when
- Chars (Node (Current_Seen_Disc)) = Chars (Disc);
-
- Next_Elmt (Current_Seen_Disc);
- end loop;
-
- -- When we have exited the above loop without finding
- -- a match then we know that Disc has not been seen.
-
- exit Outer when No (Current_Seen_Disc);
- end;
-
- Next_Discriminant (Disc);
- end loop Outer;
-
- -- If we got to an others clause with a non-zero
- -- discriminant count there must be a discriminant left to
- -- check.
-
- pragma Assert (Present (Disc));
-
- -- Set the unseen discriminant count to zero because we know
- -- an others clause sets all remaining components of an
- -- aggregate.
-
- Unseen_Disc_Count := 0;
-
- -- Move through each of the selectors in the named association
- -- and obtain a discriminant for accessibility checking if one
- -- is referenced in the list. Also track which discriminants
- -- are referenced for the purpose of handling an others clause.
-
- else
- declare
- Assoc_Choice : Node_Id;
- Curr_Disc : Node_Id;
- begin
-
- Disc := Empty;
- Curr_Disc := First_Disc;
- while Present (Curr_Disc) loop
- -- Check each of the choices in the associations for a
- -- match to the name of the current discriminant.
-
- Assoc_Choice := First_Selector (Assoc);
- while Present (Assoc_Choice) loop
- -- When the name matches we track that we have seen
- -- the discriminant, but instead of exiting the
- -- loop we continue iterating to make sure all the
- -- discriminants within the named association get
- -- tracked.
-
- if Chars (Assoc_Choice) = Chars (Curr_Disc) then
- Append_Elmt (Curr_Disc, Seen_Discs);
-
- Disc := Curr_Disc;
- Unseen_Disc_Count := Unseen_Disc_Count - 1;
- end if;
-
- Next (Assoc_Choice);
- end loop;
-
- Next_Discriminant (Curr_Disc);
- end loop;
- end;
- end if;
-
- -- Unwrap the associated expression if we are looking at a default
- -- initialized type declaration. In this case Assoc is not really
- -- an association, but a component declaration. Should Assoc be
- -- renamed in some way to be more clear ???
-
- -- This occurs when the return object does not initialize
- -- discriminant and instead relies on the type declaration for
- -- their supplied values.
-
- elsif Nkind (Assoc) in N_Entity
- and then Ekind (Assoc) = E_Discriminant
- then
- Append_Elmt (Disc, Seen_Discs);
-
- Assoc_Expr := Discriminant_Default_Value (Assoc);
- Unseen_Disc_Count := Unseen_Disc_Count - 1;
-
- -- Otherwise, there is nothing to do because Assoc is an
- -- expression within the return aggregate itself.
-
- else
- Append_Elmt (Disc, Seen_Discs);
-
- Assoc_Expr := Assoc;
- Unseen_Disc_Count := Unseen_Disc_Count - 1;
- end if;
-
- -- Check the accessibility level of the expression when the
- -- discriminant is of an anonymous access type.
-
- if Present (Assoc_Expr)
- and then Present (Disc)
- and then Ekind (Etype (Disc)) = E_Anonymous_Access_Type
-
- -- We disable the check when we have a tagged return type and
- -- the associated expression for the discriminant is a formal
- -- parameter since the check would require us to compare the
- -- accessibility level of Assoc_Expr to the level of the
- -- Extra_Accessibility_Of_Result of the function - which is
- -- currently disabled for functions with tagged return types.
- -- This may change in the future ???
-
- -- See Needs_Result_Accessibility_Level for details.
-
- and then not
- (No (Extra_Accessibility_Of_Result (Scope_Id))
- and then Is_Formal_Of_Current_Function (Assoc_Expr)
- and then Is_Tagged_Type (Etype (Scope_Id)))
- then
- -- Generate a dynamic check based on the extra accessibility of
- -- the result or the scope of the current function.
-
- Check_Cond :=
- Make_Op_Gt (Loc,
- Left_Opnd => Accessibility_Level
- (Expr => Assoc_Expr,
- Level => Dynamic_Level,
- In_Return_Context => True),
- Right_Opnd =>
- (if Present (Extra_Accessibility_Of_Result (Scope_Id))
-
- -- When Assoc_Expr is a formal we have to look at the
- -- extra accessibility-level formal associated with
- -- the result.
-
- and then Is_Formal_Of_Current_Function (Assoc_Expr)
- then
- New_Occurrence_Of
- (Extra_Accessibility_Of_Result (Scope_Id), Loc)
-
- -- Otherwise, we compare the level of Assoc_Expr to the
- -- scope of the current function.
-
- else
- Make_Integer_Literal
- (Loc, Scope_Depth (Scope (Scope_Id)))));
-
- Insert_Before_And_Analyze (Return_Stmt,
- Make_Raise_Program_Error (Loc,
- Condition => Check_Cond,
- Reason => PE_Accessibility_Check_Failed));
-
- -- If constant folding has happened on the condition for the
- -- generated error, then warn about it being unconditional when
- -- we know an error will be raised.
-
- if Nkind (Check_Cond) = N_Identifier
- and then Entity (Check_Cond) = Standard_True
- then
- Error_Msg_N
- ("access discriminant in return object would be a dangling"
- & " reference", Return_Stmt);
- end if;
- end if;
-
- -- Iterate over the discriminants, except when we have encountered
- -- a named association since the discriminant order becomes
- -- irrelevant in that case.
-
- if not Assoc_Present then
- Next_Discriminant (Disc);
- end if;
-
- -- Iterate over associations
-
- if not Is_List_Member (Assoc) then
- exit;
- else
- Nlists.Next (Assoc);
- end if;
- end loop;
- end Check_Return_Construct_Accessibility;
-
- -------------------------------------
- -- Check_Return_Subtype_Indication --
- -------------------------------------
-
- procedure Check_Return_Subtype_Indication (Obj_Decl : Node_Id) is
- Return_Obj : constant Node_Id := Defining_Identifier (Obj_Decl);
-
- R_Stm_Type : constant Entity_Id := Etype (Return_Obj);
- -- Subtype given in the extended return statement (must match R_Type)
-
- Subtype_Ind : constant Node_Id :=
- Object_Definition (Original_Node (Obj_Decl));
-
- procedure Error_No_Match (N : Node_Id);
- -- Output error messages for case where types do not statically
- -- match. N is the location for the messages.
-
- --------------------
- -- Error_No_Match --
- --------------------
-
- procedure Error_No_Match (N : Node_Id) is
- begin
- Error_Msg_N
- ("subtype must statically match function result subtype", N);
-
- if not Predicates_Match (R_Stm_Type, R_Type) then
- Error_Msg_Node_2 := R_Type;
- Error_Msg_NE
- ("\predicate of& does not match predicate of&",
- N, R_Stm_Type);
- end if;
- end Error_No_Match;
-
- -- Start of processing for Check_Return_Subtype_Indication
-
- begin
- -- First, avoid cascaded errors
-
- if Error_Posted (Obj_Decl) or else Error_Posted (Subtype_Ind) then
- return;
- end if;
-
- -- "return access T" case; check that the return statement also has
- -- "access T", and that the subtypes statically match:
- -- if this is an access to subprogram the signatures must match.
-
- if Is_Anonymous_Access_Type (R_Type) then
- if Is_Anonymous_Access_Type (R_Stm_Type) then
- if Ekind (Designated_Type (R_Stm_Type)) /= E_Subprogram_Type
- then
- if Base_Type (Designated_Type (R_Stm_Type)) /=
- Base_Type (Designated_Type (R_Type))
- or else not Subtypes_Statically_Match (R_Stm_Type, R_Type)
- then
- Error_No_Match (Subtype_Mark (Subtype_Ind));
- end if;
-
- else
- -- For two anonymous access to subprogram types, the types
- -- themselves must be type conformant.
-
- if not Conforming_Types
- (R_Stm_Type, R_Type, Fully_Conformant)
- then
- Error_No_Match (Subtype_Ind);
- end if;
- end if;
-
- else
- Error_Msg_N ("must use anonymous access type", Subtype_Ind);
- end if;
-
- -- If the return object is of an anonymous access type, then report
- -- an error if the function's result type is not also anonymous.
-
- elsif Is_Anonymous_Access_Type (R_Stm_Type) then
- pragma Assert (not Is_Anonymous_Access_Type (R_Type));
- Error_Msg_N
- ("anonymous access not allowed for function with named access "
- & "result", Subtype_Ind);
-
- -- Subtype indication case: check that the return object's type is
- -- covered by the result type, and that the subtypes statically match
- -- when the result subtype is constrained. Also handle record types
- -- with unknown discriminants for which we have built the underlying
- -- record view. Coverage is needed to allow specific-type return
- -- objects when the result type is class-wide (see AI05-32).
-
- elsif Covers (Base_Type (R_Type), Base_Type (R_Stm_Type))
- or else (Is_Underlying_Record_View (Base_Type (R_Stm_Type))
- and then
- Covers
- (Base_Type (R_Type),
- Underlying_Record_View (Base_Type (R_Stm_Type))))
- then
- -- A null exclusion may be present on the return type, on the
- -- function specification, on the object declaration or on the
- -- subtype itself.
-
- if Is_Access_Type (R_Type)
- and then
- (Can_Never_Be_Null (R_Type)
- or else Null_Exclusion_Present (Parent (Scope_Id))) /=
- Can_Never_Be_Null (R_Stm_Type)
- then
- Error_No_Match (Subtype_Ind);
- end if;
-
- -- AI05-103: for elementary types, subtypes must statically match
-
- if Is_Constrained (R_Type) or else Is_Access_Type (R_Type) then
- if not Subtypes_Statically_Match (R_Stm_Type, R_Type) then
- Error_No_Match (Subtype_Ind);
- end if;
- end if;
-
- -- All remaining cases are illegal
-
- -- Note: previous versions of this subprogram allowed the return
- -- value to be the ancestor of the return type if the return type
- -- was a null extension. This was plainly incorrect.
-
- else
- Error_Msg_N
- ("wrong type for return_subtype_indication", Subtype_Ind);
- end if;
- end Check_Return_Subtype_Indication;
-
---------------------
-- Local Variables --
---------------------
@@ -1487,7 +849,7 @@ package body Sem_Ch6 is
Resolve (Expr, R_Type);
Check_Limited_Return (N, Expr, R_Type);
- Check_Return_Construct_Accessibility (N);
+ Check_Return_Construct_Accessibility (N, Stm_Entity);
-- Ada 2022 (AI12-0269): Any return statement that applies to a
-- nonreturning function shall be a simple_return_statement with
@@ -1521,8 +883,6 @@ package body Sem_Ch6 is
Set_Is_Return_Object (Defining_Identifier (Obj_Decl));
Analyze (Obj_Decl);
- Check_Return_Subtype_Indication (Obj_Decl);
-
if Present (HSS) then
Analyze (HSS);
@@ -1543,7 +903,7 @@ package body Sem_Ch6 is
Check_References (Stm_Entity);
- Check_Return_Construct_Accessibility (N);
+ Check_Return_Construct_Accessibility (N, Stm_Entity);
-- Check RM 6.5 (5.9/3)
@@ -3352,7 +2712,8 @@ package body Sem_Ch6 is
or else
(Is_Class_Wide_Type (Designated_Type (Etype (Scop)))
and then
- Is_Limited_Record (Designated_Type (Etype (Scop)))))
+ Is_Limited_Record
+ (Etype (Designated_Type (Etype (Scop))))))
and then Expander_Active
then
Decl := Build_Master_Declaration (Loc);
@@ -4070,7 +3431,7 @@ package body Sem_Ch6 is
-- an instance that may have manipulated the flag during
-- expansion. As a result, we add an exception for this case.
- elsif not Present (Overridden_Operation (Spec_Id))
+ elsif No (Overridden_Operation (Spec_Id))
and then not (Chars (Spec_Id) in Name_Adjust
| Name_Finalize
| Name_Initialize
@@ -6795,7 +6156,7 @@ package body Sem_Ch6 is
Error_Msg_Sloc := Sloc (Op);
if Comes_From_Source (Op) or else No (Alias (Op)) then
- if not Present (Overridden_Operation (Op)) then
+ if No (Overridden_Operation (Op)) then
Error_Msg_N ("\\primitive % defined #", Typ);
else
Error_Msg_N
@@ -8366,7 +7727,7 @@ package body Sem_Ch6 is
or else not Is_Overloadable (Subp)
or else not Is_Primitive (Subp)
or else not Is_Dispatching_Operation (Subp)
- or else not Present (Find_Dispatching_Type (Subp))
+ or else No (Find_Dispatching_Type (Subp))
or else not Is_Interface (Find_Dispatching_Type (Subp))
then
null;
@@ -8471,6 +7832,253 @@ package body Sem_Ch6 is
(New_Id, Old_Id, Type_Conformant, True, Result, Err_Loc);
end Check_Type_Conformant;
+ -----------------------------
+ -- Check_Untagged_Equality --
+ -----------------------------
+
+ procedure Check_Untagged_Equality (Eq_Op : Entity_Id) is
+ Eq_Decl : constant Node_Id := Unit_Declaration_Node (Eq_Op);
+ Typ : constant Entity_Id := Etype (First_Formal (Eq_Op));
+
+ procedure Freezing_Point_Warning (N : Node_Id; S : String);
+ -- Output a warning about the freezing point N of Typ
+
+ function Is_Actual_Of_Instantiation
+ (E : Entity_Id;
+ Inst : Node_Id) return Boolean;
+ -- Return True if E is an actual parameter of instantiation Inst
+
+ -----------------------------------
+ -- Output_Freezing_Point_Warning --
+ -----------------------------------
+
+ procedure Freezing_Point_Warning (N : Node_Id; S : String) is
+ begin
+ Error_Msg_String (1 .. S'Length) := S;
+ Error_Msg_Strlen := S'Length;
+
+ if Ada_Version >= Ada_2012 then
+ Error_Msg_NE ("type& is frozen by ~??", N, Typ);
+ Error_Msg_N
+ ("\an equality operator cannot be declared after this point??",
+ N);
+
+ else
+ Error_Msg_NE ("type& is frozen by ~ (Ada 2012)?y?", N, Typ);
+ Error_Msg_N
+ ("\an equality operator cannot be declared after this point"
+ & " (Ada 2012)?y?", N);
+ end if;
+ end Freezing_Point_Warning;
+
+ --------------------------------
+ -- Is_Actual_Of_Instantiation --
+ --------------------------------
+
+ function Is_Actual_Of_Instantiation
+ (E : Entity_Id;
+ Inst : Node_Id) return Boolean
+ is
+ Assoc : Node_Id;
+
+ begin
+ if Present (Generic_Associations (Inst)) then
+ Assoc := First (Generic_Associations (Inst));
+
+ while Present (Assoc) loop
+ if Present (Explicit_Generic_Actual_Parameter (Assoc))
+ and then
+ Is_Entity_Name (Explicit_Generic_Actual_Parameter (Assoc))
+ and then
+ Entity (Explicit_Generic_Actual_Parameter (Assoc)) = E
+ then
+ return True;
+ end if;
+
+ Next (Assoc);
+ end loop;
+ end if;
+
+ return False;
+ end Is_Actual_Of_Instantiation;
+
+ -- Local variable
+
+ Decl : Node_Id;
+
+ -- Start of processing for Check_Untagged_Equality
+
+ begin
+ -- This check applies only if we have a subprogram declaration or a
+ -- subprogram body that is not a completion, for an untagged record
+ -- type, and that is conformant with the predefined operator.
+
+ if (Nkind (Eq_Decl) /= N_Subprogram_Declaration
+ and then not (Nkind (Eq_Decl) = N_Subprogram_Body
+ and then Acts_As_Spec (Eq_Decl)))
+ or else not Is_Record_Type (Typ)
+ or else Is_Tagged_Type (Typ)
+ or else not Is_User_Defined_Equality (Eq_Op)
+ then
+ return;
+ end if;
+
+ -- In Ada 2012 case, we will output errors or warnings depending on
+ -- the setting of debug flag -gnatd.E.
+
+ if Ada_Version >= Ada_2012 then
+ Error_Msg_Warn := Debug_Flag_Dot_EE;
+
+ -- In earlier versions of Ada, nothing to do unless we are warning on
+ -- Ada 2012 incompatibilities (Warn_On_Ada_2012_Incompatibility set).
+
+ else
+ if not Warn_On_Ada_2012_Compatibility then
+ return;
+ end if;
+ end if;
+
+ -- Cases where the type has already been frozen
+
+ if Is_Frozen (Typ) then
+
+ -- The check applies to a primitive operation, so check that type
+ -- and equality operation are in the same scope.
+
+ if Scope (Typ) /= Current_Scope then
+ return;
+
+ -- If the type is a generic actual (sub)type, the operation is not
+ -- primitive either because the base type is declared elsewhere.
+
+ elsif Is_Generic_Actual_Type (Typ) then
+ return;
+
+ -- Here we may have an error of declaration after freezing, but we
+ -- must make sure not to flag the equality operator itself causing
+ -- the freezing when it is a subprogram body.
+
+ else
+ Decl := Next (Declaration_Node (Typ));
+
+ while Present (Decl) and then Decl /= Eq_Decl loop
+
+ -- The declaration of an object of the type
+
+ if Nkind (Decl) = N_Object_Declaration
+ and then Etype (Defining_Identifier (Decl)) = Typ
+ then
+ Freezing_Point_Warning (Decl, "declaration");
+ exit;
+
+ -- The instantiation of a generic on the type
+
+ elsif Nkind (Decl) in N_Generic_Instantiation
+ and then Is_Actual_Of_Instantiation (Typ, Decl)
+ then
+ Freezing_Point_Warning (Decl, "instantiation");
+ exit;
+
+ -- A noninstance proper body, body stub or entry body
+
+ elsif Nkind (Decl) in N_Proper_Body
+ | N_Body_Stub
+ | N_Entry_Body
+ and then not Is_Generic_Instance (Defining_Entity (Decl))
+ then
+ Freezing_Point_Warning (Decl, "body");
+ exit;
+
+ -- If we have reached the freeze node and immediately after we
+ -- have the body or generated code for the body, then it is the
+ -- body that caused the freezing and this is legal.
+
+ elsif Nkind (Decl) = N_Freeze_Entity
+ and then Entity (Decl) = Typ
+ and then (Next (Decl) = Eq_Decl
+ or else
+ Sloc (Next (Decl)) = Sloc (Eq_Decl))
+ then
+ return;
+ end if;
+
+ Next (Decl);
+ end loop;
+
+ -- Here we have a definite error of declaration after freezing
+
+ if Ada_Version >= Ada_2012 then
+ Error_Msg_NE
+ ("equality operator must be declared before type & is "
+ & "frozen (RM 4.5.2 (9.8)) (Ada 2012)<<", Eq_Op, Typ);
+
+ -- In Ada 2012 mode with error turned to warning, output one
+ -- more warning to warn that the equality operation may not
+ -- compose. This is the consequence of ignoring the error.
+
+ if Error_Msg_Warn then
+ Error_Msg_N ("\equality operation may not compose??", Eq_Op);
+ end if;
+
+ else
+ Error_Msg_NE
+ ("equality operator must be declared before type& is "
+ & "frozen (RM 4.5.2 (9.8)) (Ada 2012)?y?", Eq_Op, Typ);
+ end if;
+
+ -- If we have found no freezing point and the declaration of the
+ -- operator could not be reached from that of the type and we are
+ -- in a package body, this must be because the type is declared
+ -- in the spec of the package. Add a message tailored to this.
+
+ if No (Decl) and then In_Package_Body (Scope (Typ)) then
+ if Ada_Version >= Ada_2012 then
+ if Nkind (Eq_Decl) = N_Subprogram_Body then
+ Error_Msg_N
+ ("\put declaration in package spec<<", Eq_Op);
+ else
+ Error_Msg_N
+ ("\move declaration to package spec<<", Eq_Op);
+ end if;
+
+ else
+ if Nkind (Eq_Decl) = N_Subprogram_Body then
+ Error_Msg_N
+ ("\put declaration in package spec (Ada 2012)?y?",
+ Eq_Op);
+ else
+ Error_Msg_N
+ ("\move declaration to package spec (Ada 2012)?y?",
+ Eq_Op);
+ end if;
+ end if;
+ end if;
+ end if;
+
+ -- Now check for AI12-0352: the declaration of a user-defined primitive
+ -- equality operation for a record type T is illegal if it occurs after
+ -- a type has been derived from T.
+
+ else
+ Decl := Next (Declaration_Node (Typ));
+
+ while Present (Decl) and then Decl /= Eq_Decl loop
+ if Nkind (Decl) = N_Full_Type_Declaration
+ and then Etype (Defining_Identifier (Decl)) = Typ
+ then
+ Error_Msg_N
+ ("equality operator cannot appear after derivation", Eq_Op);
+ Error_Msg_NE
+ ("an equality operator for& cannot be declared after "
+ & "this point??",
+ Decl, Typ);
+ end if;
+
+ Next (Decl);
+ end loop;
+ end if;
+ end Check_Untagged_Equality;
+
---------------------------
-- Can_Override_Operator --
---------------------------
@@ -8950,6 +8558,26 @@ package body Sem_Ch6 is
-- BIP_xxx denotes an extra formal for a build-in-place function. See
-- the full list in exp_ch6.BIP_Formal_Kind.
+ function Has_Extra_Formals (E : Entity_Id) return Boolean;
+ -- Determines if E has its extra formals
+
+ function Needs_Accessibility_Check_Extra
+ (E : Entity_Id;
+ Formal : Node_Id) return Boolean;
+ -- Determines whether the given formal of E needs an extra formal for
+ -- supporting accessibility checking. Returns True for both anonymous
+ -- access formals and formals of named access types that are marked as
+ -- controlling formals. The latter case can occur when the subprogram
+ -- Expand_Dispatching_Call creates a subprogram-type and substitutes
+ -- the types of access-to-class-wide actuals for the anonymous access-
+ -- to-specific-type of controlling formals.
+
+ function Parent_Subprogram (Subp_Id : Entity_Id) return Entity_Id;
+ -- Subp_Id is a subprogram of a derived type; return its parent
+ -- subprogram if Subp_Id overrides a parent primitive or derives
+ -- from a parent primitive, and such parent primitive can have extra
+ -- formals. Otherwise return Empty.
+
----------------------
-- Add_Extra_Formal --
----------------------
@@ -8960,10 +8588,7 @@ package body Sem_Ch6 is
Scope : Entity_Id;
Suffix : String) return Entity_Id
is
- EF : constant Entity_Id :=
- Make_Defining_Identifier (Sloc (Assoc_Entity),
- Chars => New_External_Name (Chars (Assoc_Entity),
- Suffix => Suffix));
+ EF : Entity_Id;
begin
-- A little optimization. Never generate an extra formal for the
@@ -8974,6 +8599,10 @@ package body Sem_Ch6 is
return Empty;
end if;
+ EF := Make_Defining_Identifier (Sloc (Assoc_Entity),
+ Chars => New_External_Name (Chars (Assoc_Entity),
+ Suffix => Suffix));
+
Mutate_Ekind (EF, E_In_Parameter);
Set_Actual_Subtype (EF, Typ);
Set_Etype (EF, Typ);
@@ -8995,49 +8624,266 @@ package body Sem_Ch6 is
return EF;
end Add_Extra_Formal;
+ -----------------------
+ -- Has_Extra_Formals --
+ -----------------------
+
+ function Has_Extra_Formals (E : Entity_Id) return Boolean is
+ begin
+ return Present (Extra_Formals (E))
+ or else
+ (Ekind (E) = E_Function
+ and then Present (Extra_Accessibility_Of_Result (E)));
+ end Has_Extra_Formals;
+
+ -------------------------------------
+ -- Needs_Accessibility_Check_Extra --
+ -------------------------------------
+
+ function Needs_Accessibility_Check_Extra
+ (E : Entity_Id;
+ Formal : Node_Id) return Boolean is
+
+ begin
+ -- For dispatching operations this extra formal is not suppressed
+ -- since all the derivations must have matching formals.
+
+ -- For nondispatching operations it is suppressed if we specifically
+ -- suppress accessibility checks at the package level for either the
+ -- subprogram, or the package in which it resides. However, we do
+ -- not suppress it simply if the scope has accessibility checks
+ -- suppressed, since this could cause trouble when clients are
+ -- compiled with a different suppression setting. The explicit checks
+ -- at the package level are safe from this point of view.
+
+ if not Is_Dispatching_Operation (E)
+ and then
+ (Explicit_Suppress (E, Accessibility_Check)
+ or else Explicit_Suppress (Scope (E), Accessibility_Check))
+ then
+ return False;
+ end if;
+
+ -- Base_Type is applied to handle cases where there is a null
+ -- exclusion the formal may have an access subtype.
+
+ return
+ Ekind (Base_Type (Etype (Formal))) = E_Anonymous_Access_Type
+ or else
+ (Is_Controlling_Formal (Formal)
+ and then Is_Access_Type (Base_Type (Etype (Formal))));
+ end Needs_Accessibility_Check_Extra;
+
+ -----------------------
+ -- Parent_Subprogram --
+ -----------------------
+
+ function Parent_Subprogram (Subp_Id : Entity_Id) return Entity_Id is
+ pragma Assert (not Is_Thunk (Subp_Id));
+ Ovr_E : Entity_Id := Overridden_Operation (Subp_Id);
+ Ovr_Alias : Entity_Id;
+
+ begin
+ if Present (Ovr_E) then
+ Ovr_Alias := Ultimate_Alias (Ovr_E);
+
+ -- There is no real overridden subprogram if there is a mutual
+ -- reference between the E and its overridden operation. This
+ -- weird scenery occurs in the following cases:
+
+ -- 1) Controlling function wrappers internally built by
+ -- Make_Controlling_Function_Wrappers.
+
+ -- 2) Hidden overridden primitives of type extensions or private
+ -- extensions (cf. Find_Hidden_Overridden_Primitive). These
+ -- hidden primitives have suffix 'P'.
+
+ -- 3) Overriding primitives of stub types (see the subprogram
+ -- Add_RACW_Primitive_Declarations_And_Bodies).
+
+ if Ovr_Alias = Subp_Id then
+ pragma Assert
+ ((Is_Wrapper (Subp_Id)
+ and then Has_Controlling_Result (Subp_Id))
+ or else Has_Suffix (Ovr_E, 'P')
+ or else Is_RACW_Stub_Type
+ (Find_Dispatching_Type (Subp_Id)));
+
+ if Present (Overridden_Operation (Ovr_E)) then
+ Ovr_E := Overridden_Operation (Ovr_E);
+
+ -- Ovr_E is an internal entity built by Derive_Subprogram and
+ -- we have no direct way to climb to the corresponding parent
+ -- subprogram but this internal entity has the extra formals
+ -- (if any) required for the purpose of checking the extra
+ -- formals of Subp_Id.
+
+ else
+ pragma Assert (not Comes_From_Source (Ovr_E));
+ end if;
+
+ -- Use as our reference entity the ultimate renaming of the
+ -- overridden subprogram.
+
+ elsif Present (Alias (Ovr_E)) then
+ pragma Assert (No (Overridden_Operation (Ovr_Alias))
+ or else Overridden_Operation (Ovr_Alias) /= Ovr_E);
+
+ Ovr_E := Ovr_Alias;
+ end if;
+ end if;
+
+ if Present (Ovr_E) and then Has_Reliable_Extra_Formals (Ovr_E) then
+ return Ovr_E;
+ else
+ return Empty;
+ end if;
+ end Parent_Subprogram;
+
-- Local variables
- Formal_Type : Entity_Id;
- P_Formal : Entity_Id;
+ Formal_Type : Entity_Id;
+ May_Have_Alias : Boolean;
+ Alias_Formal : Entity_Id := Empty;
+ Alias_Subp : Entity_Id := Empty;
+ Parent_Formal : Entity_Id := Empty;
+ Parent_Subp : Entity_Id := Empty;
+ Ref_E : Entity_Id;
-- Start of processing for Create_Extra_Formals
begin
+ pragma Assert (Is_Subprogram_Or_Entry (E)
+ or else Ekind (E) in E_Subprogram_Type);
+
-- We never generate extra formals if expansion is not active because we
-- don't need them unless we are generating code.
if not Expander_Active then
return;
- end if;
+
+ -- Enumeration literals have no extra formal; this case occurs when
+ -- a function renames it.
+
+ elsif Ekind (E) = E_Function
+ and then Ekind (Ultimate_Alias (E)) = E_Enumeration_Literal
+ then
+ return;
+
+ -- Initialization procedures don't have extra formals
+
+ elsif Is_Init_Proc (E) then
+ return;
-- No need to generate extra formals in thunks whose target has no extra
-- formals, but we can have two of them chained (interface and stack).
- if Is_Thunk (E) and then No (Extra_Formals (Thunk_Target (E))) then
+ elsif Is_Thunk (E) and then No (Extra_Formals (Thunk_Target (E))) then
return;
- end if;
- -- If this is a derived subprogram then the subtypes of the parent
- -- subprogram's formal parameters will be used to determine the need
- -- for extra formals.
+ -- If Extra_Formals were already created, don't do it again. This
+ -- situation may arise for subprogram types created as part of
+ -- dispatching calls (see Expand_Dispatching_Call).
- if Is_Overloadable (E) and then Present (Alias (E)) then
- P_Formal := First_Formal (Alias (E));
- else
- P_Formal := Empty;
+ elsif Has_Extra_Formals (E) then
+ return;
+
+ -- Extra formals of renamings of generic actual subprograms and
+ -- renamings of instances of generic subprograms are shared. The
+ -- check performed on the last formal is required to ensure that
+ -- this is the renaming built by Analyze_Instance_And_Renamings
+ -- (which shares all the formals); otherwise this would be wrong.
+
+ elsif Ekind (E) in E_Function | E_Procedure
+ and then Is_Generic_Instance (E)
+ and then Present (Alias (E))
+ and then Last_Formal (Ultimate_Alias (E)) = Last_Formal (E)
+ then
+ pragma Assert (Is_Generic_Instance (E)
+ = Is_Generic_Instance (Ultimate_Alias (E)));
+
+ Create_Extra_Formals (Ultimate_Alias (E));
+
+ -- Share the extra formals
+
+ Set_Extra_Formals (E, Extra_Formals (Ultimate_Alias (E)));
+
+ if Ekind (E) = E_Function then
+ Set_Extra_Accessibility_Of_Result (E,
+ Extra_Accessibility_Of_Result (Ultimate_Alias (E)));
+ end if;
+
+ pragma Assert (Extra_Formals_OK (E));
+ return;
end if;
+ -- Locate the last formal; required by Add_Extra_Formal.
+
Formal := First_Formal (E);
while Present (Formal) loop
Last_Extra := Formal;
Next_Formal (Formal);
end loop;
- -- If Extra_Formals were already created, don't do it again. This
- -- situation may arise for subprogram types created as part of
- -- dispatching calls (see Expand_Dispatching_Call).
+ -- We rely on three entities to ensure consistency of extra formals of
+ -- entity E:
+ --
+ -- 1. A reference entity (Ref_E). For thunks it is their target
+ -- primitive since this ensures that they have exactly the
+ -- same extra formals; otherwise it is the identity.
+ --
+ -- 2. The parent subprogram; only for derived types and references
+ -- either the overridden subprogram or the internal entity built
+ -- by Derive_Subprogram that has the extra formals of the parent
+ -- subprogram; otherwise it is Empty. This entity ensures matching
+ -- extra formals in derived types.
+ --
+ -- 3. For renamings, their ultimate alias; this ensures taking the
+ -- same decision in all the renamings (independently of the Ada
+ -- mode on which they are compiled). For example:
+ --
+ -- pragma Ada_2012;
+ -- function Id_A (I : access Integer) return access Integer;
+ --
+ -- pragma Ada_2005;
+ -- function Id_B (I : access Integer) return access Integer
+ -- renames Id_A;
+
+ if Is_Thunk (E) then
+ Ref_E := Thunk_Target (E);
+ else
+ Ref_E := E;
+ end if;
+
+ if Is_Subprogram (Ref_E) then
+ Parent_Subp := Parent_Subprogram (Ref_E);
+ end if;
+
+ May_Have_Alias :=
+ (Is_Subprogram (Ref_E) or else Ekind (Ref_E) = E_Subprogram_Type);
- if Present (Last_Extra) and then Present (Extra_Formal (Last_Extra)) then
+ -- If the parent subprogram is available then its ultimate alias of
+ -- Ref_E is not needed since it will not be used to check its extra
+ -- formals.
+
+ if No (Parent_Subp)
+ and then May_Have_Alias
+ and then Present (Alias (Ref_E))
+ and then Has_Reliable_Extra_Formals (Ultimate_Alias (Ref_E))
+ then
+ Alias_Subp := Ultimate_Alias (Ref_E);
+ end if;
+
+ -- Cannot add extra formals to subprograms and access types that have
+ -- foreign convention nor to subprograms overriding primitives that
+ -- have foreign convention since the foreign language does not know
+ -- how to handle these extra formals; same for renamings of entities
+ -- with foreign convention.
+
+ if Has_Foreign_Convention (Ref_E)
+ or else (Present (Alias_Subp)
+ and then Has_Foreign_Convention (Alias_Subp))
+ then
return;
end if;
@@ -9052,20 +8898,74 @@ package body Sem_Ch6 is
goto Test_For_Func_Result_Extras;
end if;
+ -- Process the formals relying on the formals of our reference entities:
+ -- Parent_Formal, Alias_Formal and Formal. Notice that we don't use the
+ -- formal of Ref_E; we must use the formal of E which is the entity to
+ -- which we are adding the extra formals.
+
+ -- If this is a derived subprogram then the subtypes of the parent
+ -- subprogram's formal parameters will be used to determine the need
+ -- for extra formals.
+
+ if Present (Parent_Subp) then
+ Parent_Formal := First_Formal (Parent_Subp);
+
+ -- For concurrent types, the controlling argument of a dispatching
+ -- primitive implementing an interface primitive is implicit. For
+ -- example:
+ --
+ -- type Iface is protected interface;
+ -- function Prim
+ -- (Obj : Iface;
+ -- Value : Integer) return Natural is abstract;
+ --
+ -- protected type PO is new Iface with
+ -- function Prim (Value : Integer) return Natural;
+ -- end PO;
+
+ if Convention (Ref_E) = Convention_Protected
+ and then Is_Abstract_Subprogram (Parent_Subp)
+ and then Is_Interface (Find_Dispatching_Type (Parent_Subp))
+ then
+ Parent_Formal := Next_Formal (Parent_Formal);
+
+ -- This is the nondispatching subprogram of a concurrent type
+ -- that overrides the interface primitive; the expander will
+ -- create the dispatching primitive (without Convention_Protected)
+ -- with all the matching formals (see exp_ch9.Build_Wrapper_Specs)
+
+ pragma Assert (not Is_Dispatching_Operation (Ref_E));
+ end if;
+
+ -- Ensure that the ultimate alias has all its extra formals
+
+ elsif Present (Alias_Subp) then
+ Create_Extra_Formals (Alias_Subp);
+ Alias_Formal := First_Formal (Alias_Subp);
+ end if;
+
Formal := First_Formal (E);
while Present (Formal) loop
+ -- Here we establish our priority for deciding on the extra
+ -- formals: 1) Parent primitive 2) Aliased primitive 3) Identity
+
+ if Present (Parent_Formal) then
+ Formal_Type := Etype (Parent_Formal);
+
+ elsif Present (Alias_Formal) then
+ Formal_Type := Etype (Alias_Formal);
+
+ else
+ Formal_Type := Etype (Formal);
+ end if;
+
-- Create extra formal for supporting the attribute 'Constrained.
-- The case of a private type view without discriminants also
-- requires the extra formal if the underlying type has defaulted
-- discriminants.
if Ekind (Formal) /= E_In_Parameter then
- if Present (P_Formal) then
- Formal_Type := Etype (P_Formal);
- else
- Formal_Type := Etype (Formal);
- end if;
-- Do not produce extra formals for Unchecked_Union parameters.
-- Jump directly to the end of the loop.
@@ -9110,36 +9010,22 @@ package body Sem_Ch6 is
end if;
end if;
- -- Create extra formal for supporting accessibility checking. This
- -- is done for both anonymous access formals and formals of named
- -- access types that are marked as controlling formals. The latter
- -- case can occur when Expand_Dispatching_Call creates a subprogram
- -- type and substitutes the types of access-to-class-wide actuals
- -- for the anonymous access-to-specific-type of controlling formals.
- -- Base_Type is applied because in cases where there is a null
- -- exclusion the formal may have an access subtype.
+ -- Extra formal for supporting accessibility checking
+
+ if Needs_Accessibility_Check_Extra (Ref_E, Formal) then
+ pragma Assert (No (Parent_Formal)
+ or else Present (Extra_Accessibility (Parent_Formal)));
+ pragma Assert (No (Alias_Formal)
+ or else Present (Extra_Accessibility (Alias_Formal)));
- -- This is suppressed if we specifically suppress accessibility
- -- checks at the package level for either the subprogram, or the
- -- package in which it resides. However, we do not suppress it
- -- simply if the scope has accessibility checks suppressed, since
- -- this could cause trouble when clients are compiled with a
- -- different suppression setting. The explicit checks at the
- -- package level are safe from this point of view.
-
- if (Ekind (Base_Type (Etype (Formal))) = E_Anonymous_Access_Type
- or else (Is_Controlling_Formal (Formal)
- and then Is_Access_Type (Base_Type (Etype (Formal)))))
- and then not
- (Explicit_Suppress (E, Accessibility_Check)
- or else
- Explicit_Suppress (Scope (E), Accessibility_Check))
- and then
- (No (P_Formal)
- or else Present (Extra_Accessibility (P_Formal)))
- then
Set_Extra_Accessibility
(Formal, Add_Extra_Formal (Formal, Standard_Natural, E, "L"));
+
+ else
+ pragma Assert (No (Parent_Formal)
+ or else No (Extra_Accessibility (Parent_Formal)));
+ pragma Assert (No (Alias_Formal)
+ or else No (Extra_Accessibility (Alias_Formal)));
end if;
-- This label is required when skipping extra formal generation for
@@ -9147,8 +9033,12 @@ package body Sem_Ch6 is
<<Skip_Extra_Formal_Generation>>
- if Present (P_Formal) then
- Next_Formal (P_Formal);
+ if Present (Parent_Formal) then
+ Next_Formal (Parent_Formal);
+ end if;
+
+ if Present (Alias_Formal) then
+ Next_Formal (Alias_Formal);
end if;
Next_Formal (Formal);
@@ -9156,20 +9046,47 @@ package body Sem_Ch6 is
<<Test_For_Func_Result_Extras>>
- -- Ada 2012 (AI05-234): "the accessibility level of the result of a
- -- function call is ... determined by the point of call ...".
+ -- Assume the worst case (Ada 2022) to evaluate this extra formal;
+ -- required to ensure matching of extra formals between subprograms
+ -- and access-to-subprogram types in projects with mixed Ada dialects.
- if Needs_Result_Accessibility_Level (E) then
- Set_Extra_Accessibility_Of_Result
- (E, Add_Extra_Formal (E, Standard_Natural, E, "L"));
- end if;
+ declare
+ Save_Ada_Version : constant Ada_Version_Type := Ada_Version;
+
+ begin
+ Ada_Version := Ada_2022;
+
+ if Needs_Result_Accessibility_Level (Ref_E) then
+ pragma Assert (No (Parent_Subp)
+ or else Needs_Result_Accessibility_Level (Parent_Subp));
+ pragma Assert (No (Alias_Subp)
+ or else Needs_Result_Accessibility_Level (Alias_Subp));
+
+ Set_Extra_Accessibility_Of_Result (E,
+ Add_Extra_Formal (E, Standard_Natural, E, "L"));
+
+ else
+ pragma Assert (No (Parent_Subp)
+ or else not Needs_Result_Accessibility_Level (Parent_Subp));
+ pragma Assert (No (Alias_Subp)
+ or else not Needs_Result_Accessibility_Level (Alias_Subp));
+ end if;
+
+ Ada_Version := Save_Ada_Version;
+ end;
-- Ada 2005 (AI-318-02): In the case of build-in-place functions, add
-- appropriate extra formals. See type Exp_Ch6.BIP_Formal_Kind.
- if Is_Build_In_Place_Function (E) then
+ if (Present (Parent_Subp) and then Has_BIP_Formals (Parent_Subp))
+ or else
+ (Present (Alias_Subp) and then Has_BIP_Formals (Alias_Subp))
+ or else
+ (Is_Build_In_Place_Function (Ref_E)
+ and then Has_Reliable_Extra_Formals (Ref_E))
+ then
declare
- Result_Subt : constant Entity_Id := Etype (E);
+ Result_Subt : constant Entity_Id := Etype (Ref_E);
Formal_Typ : Entity_Id;
Subp_Decl : Node_Id;
Discard : Entity_Id;
@@ -9187,7 +9104,14 @@ package body Sem_Ch6 is
-- dispatching context and such calls must be handled like calls
-- to a class-wide function.
- if Needs_BIP_Alloc_Form (E) then
+ if Needs_BIP_Alloc_Form (Ref_E) then
+ pragma Assert (No (Parent_Subp)
+ or else Has_BIP_Extra_Formal (Parent_Subp, BIP_Alloc_Form,
+ Must_Be_Frozen => False));
+ pragma Assert (No (Alias_Subp)
+ or else Has_BIP_Extra_Formal (Alias_Subp, BIP_Alloc_Form,
+ Must_Be_Frozen => False));
+
Discard :=
Add_Extra_Formal
(E, Standard_Natural,
@@ -9203,23 +9127,66 @@ package body Sem_Ch6 is
(E, RTE (RE_Root_Storage_Pool_Ptr),
E, BIP_Formal_Suffix (BIP_Storage_Pool));
end if;
+
+ else
+ pragma Assert (No (Parent_Subp)
+ or else not
+ Has_BIP_Extra_Formal (Parent_Subp, BIP_Alloc_Form,
+ Must_Be_Frozen => False));
+ pragma Assert (No (Alias_Subp)
+ or else not
+ Has_BIP_Extra_Formal (Alias_Subp, BIP_Alloc_Form,
+ Must_Be_Frozen => False));
end if;
-- In the case of functions whose result type needs finalization,
-- add an extra formal which represents the finalization master.
- if Needs_BIP_Finalization_Master (E) then
+ if Needs_BIP_Finalization_Master (Ref_E) then
+ pragma Assert (No (Parent_Subp)
+ or else Has_BIP_Extra_Formal (Parent_Subp,
+ Kind => BIP_Finalization_Master,
+ Must_Be_Frozen => False));
+ pragma Assert (No (Alias_Subp)
+ or else Has_BIP_Extra_Formal (Alias_Subp,
+ Kind => BIP_Finalization_Master,
+ Must_Be_Frozen => False));
+
Discard :=
Add_Extra_Formal
(E, RTE (RE_Finalization_Master_Ptr),
E, BIP_Formal_Suffix (BIP_Finalization_Master));
+
+ else
+ pragma Assert (No (Parent_Subp)
+ or else not
+ Has_BIP_Extra_Formal (Parent_Subp,
+ Kind => BIP_Finalization_Master,
+ Must_Be_Frozen => False));
+ pragma Assert (No (Alias_Subp)
+ or else not
+ Has_BIP_Extra_Formal (Alias_Subp,
+ Kind => BIP_Finalization_Master,
+ Must_Be_Frozen => False));
end if;
-- When the result type contains tasks, add two extra formals: the
-- master of the tasks to be created, and the caller's activation
-- chain.
- if Needs_BIP_Task_Actuals (E) then
+ if Needs_BIP_Task_Actuals (Ref_E) then
+ pragma Assert (No (Parent_Subp)
+ or else Has_BIP_Extra_Formal (Parent_Subp, BIP_Task_Master,
+ Must_Be_Frozen => False));
+ pragma Assert (No (Alias_Subp)
+ or else Has_BIP_Extra_Formal (Alias_Subp, BIP_Task_Master,
+ Must_Be_Frozen => False)
+ or else
+ (Is_Abstract_Subprogram (Ref_E)
+ and then Is_Predefined_Dispatching_Operation (Ref_E)
+ and then Is_Interface
+ (Find_Dispatching_Type (Alias_Subp))));
+
Discard :=
Add_Extra_Formal
(E, Standard_Integer,
@@ -9231,6 +9198,16 @@ package body Sem_Ch6 is
Add_Extra_Formal
(E, RTE (RE_Activation_Chain_Access),
E, BIP_Formal_Suffix (BIP_Activation_Chain));
+
+ else
+ pragma Assert (No (Parent_Subp)
+ or else not
+ Has_BIP_Extra_Formal (Parent_Subp, BIP_Task_Master,
+ Must_Be_Frozen => False));
+ pragma Assert (No (Alias_Subp)
+ or else not
+ Has_BIP_Extra_Formal (Alias_Subp, BIP_Task_Master,
+ Must_Be_Frozen => False));
end if;
-- All build-in-place functions get an extra formal that will be
@@ -9296,6 +9273,14 @@ package body Sem_Ch6 is
if Is_Generic_Instance (E) and then Present (Alias (E)) then
Set_Extra_Formals (Alias (E), Extra_Formals (E));
end if;
+
+ pragma Assert (No (Alias_Subp)
+ or else Extra_Formals_Match_OK (E, Alias_Subp));
+
+ pragma Assert (No (Parent_Subp)
+ or else Extra_Formals_Match_OK (E, Parent_Subp));
+
+ pragma Assert (Extra_Formals_OK (E));
end Create_Extra_Formals;
-----------------------------
@@ -9526,252 +9511,162 @@ package body Sem_Ch6 is
end if;
end Enter_Overloaded_Entity;
- -----------------------------
- -- Check_Untagged_Equality --
- -----------------------------
-
- procedure Check_Untagged_Equality (Eq_Op : Entity_Id) is
- Eq_Decl : constant Node_Id := Unit_Declaration_Node (Eq_Op);
- Typ : constant Entity_Id := Etype (First_Formal (Eq_Op));
-
- procedure Freezing_Point_Warning (N : Node_Id; S : String);
- -- Output a warning about the freezing point N of Typ
-
- function Is_Actual_Of_Instantiation
- (E : Entity_Id;
- Inst : Node_Id) return Boolean;
- -- Return True if E is an actual parameter of instantiation Inst
-
- -----------------------------------
- -- Output_Freezing_Point_Warning --
- -----------------------------------
-
- procedure Freezing_Point_Warning (N : Node_Id; S : String) is
- begin
- Error_Msg_String (1 .. S'Length) := S;
- Error_Msg_Strlen := S'Length;
-
- if Ada_Version >= Ada_2012 then
- Error_Msg_NE ("type& is frozen by ~??", N, Typ);
- Error_Msg_N
- ("\an equality operator cannot be declared after this point??",
- N);
-
- else
- Error_Msg_NE ("type& is frozen by ~ (Ada 2012)?y?", N, Typ);
- Error_Msg_N
- ("\an equality operator cannot be declared after this point"
- & " (Ada 2012)?y?", N);
- end if;
- end Freezing_Point_Warning;
-
- --------------------------------
- -- Is_Actual_Of_Instantiation --
- --------------------------------
-
- function Is_Actual_Of_Instantiation
- (E : Entity_Id;
- Inst : Node_Id) return Boolean
- is
- Assoc : Node_Id;
-
- begin
- if Present (Generic_Associations (Inst)) then
- Assoc := First (Generic_Associations (Inst));
-
- while Present (Assoc) loop
- if Present (Explicit_Generic_Actual_Parameter (Assoc))
- and then
- Is_Entity_Name (Explicit_Generic_Actual_Parameter (Assoc))
- and then
- Entity (Explicit_Generic_Actual_Parameter (Assoc)) = E
- then
- return True;
- end if;
-
- Next (Assoc);
- end loop;
- end if;
-
- return False;
- end Is_Actual_Of_Instantiation;
-
- -- Local variable
-
- Decl : Node_Id;
-
- -- Start of processing for Check_Untagged_Equality
+ ----------------------------
+ -- Extra_Formals_Match_OK --
+ ----------------------------
+ function Extra_Formals_Match_OK
+ (E : Entity_Id;
+ Ref_E : Entity_Id) return Boolean is
begin
- -- This check applies only if we have a subprogram declaration or a
- -- subprogram body that is not a completion, for an untagged record
- -- type, and that is conformant with the predefined operator.
+ pragma Assert (Is_Subprogram (E));
+
+ -- Cases where no check can be performed:
+ -- 1) When expansion is not active (since we never generate extra
+ -- formals if expansion is not active because we don't need them
+ -- unless we are generating code).
+ -- 2) On abstract predefined dispatching operations of Root_Controlled
+ -- and predefined stream operations not emitted by the frontend.
+ -- 3) On renamings of abstract predefined dispatching operations of
+ -- interface types (since limitedness is not inherited in such
+ -- case (AI-419)).
+ -- 4) The controlling formal of the nondispatching subprogram of
+ -- a concurrent type that overrides an interface primitive is
+ -- implicit and hence we cannot check here if all its extra
+ -- formals match; the expander will create the dispatching
+ -- primitive (without Convention_Protected) with the matching
+ -- formals (see exp_ch9.Build_Wrapper_Specs) which will be
+ -- checked later.
+
+ if Debug_Flag_Underscore_XX
+ or else not Expander_Active
+ or else
+ (Is_Predefined_Dispatching_Operation (E)
+ and then (not Has_Reliable_Extra_Formals (E)
+ or else not Has_Reliable_Extra_Formals (Ref_E)))
+ or else
+ (Is_Predefined_Dispatching_Operation (E)
+ and then Is_Abstract_Subprogram (E)
+ and then Is_Interface (Find_Dispatching_Type (Ref_E)))
+ then
+ return True;
- if (Nkind (Eq_Decl) /= N_Subprogram_Declaration
- and then not (Nkind (Eq_Decl) = N_Subprogram_Body
- and then Acts_As_Spec (Eq_Decl)))
- or else not Is_Record_Type (Typ)
- or else Is_Tagged_Type (Typ)
- or else not Is_User_Defined_Equality (Eq_Op)
+ elsif Convention (E) = Convention_Protected
+ and then not Is_Dispatching_Operation (E)
+ and then Is_Abstract_Subprogram (Ref_E)
+ and then Is_Interface (Find_Dispatching_Type (Ref_E))
then
- return;
+ return True;
end if;
- -- In Ada 2012 case, we will output errors or warnings depending on
- -- the setting of debug flag -gnatd.E.
-
- if Ada_Version >= Ada_2012 then
- Error_Msg_Warn := Debug_Flag_Dot_EE;
+ -- Perform the checks
- -- In earlier versions of Ada, nothing to do unless we are warning on
- -- Ada 2012 incompatibilities (Warn_On_Ada_2012_Incompatibility set).
-
- else
- if not Warn_On_Ada_2012_Compatibility then
- return;
- end if;
+ if No (Extra_Formals (E)) then
+ return No (Extra_Formals (Ref_E));
end if;
- -- Cases where the type has already been frozen
-
- if Is_Frozen (Typ) then
-
- -- The check applies to a primitive operation, so check that type
- -- and equality operation are in the same scope.
-
- if Scope (Typ) /= Current_Scope then
- return;
-
- -- If the type is a generic actual (sub)type, the operation is not
- -- primitive either because the base type is declared elsewhere.
+ if Ekind (E) in E_Function | E_Subprogram_Type
+ and then Present (Extra_Accessibility_Of_Result (E))
+ /= Present (Extra_Accessibility_Of_Result (Ref_E))
+ then
+ return False;
+ end if;
- elsif Is_Generic_Actual_Type (Typ) then
- return;
+ declare
+ Formal_1 : Entity_Id := Extra_Formals (E);
+ Formal_2 : Entity_Id := Extra_Formals (Ref_E);
- -- Here we may have an error of declaration after freezing, but we
- -- must make sure not to flag the equality operator itself causing
- -- the freezing when it is a subprogram body.
+ begin
+ while Present (Formal_1) and then Present (Formal_2) loop
+ if Has_Suffix (Formal_1, 'L') then
+ if not Has_Suffix (Formal_2, 'L') then
+ return False;
+ end if;
- else
- Decl := Next (Declaration_Node (Typ));
+ elsif Has_Suffix (Formal_1, 'O') then
+ if not Has_Suffix (Formal_2, 'O') then
+ return False;
+ end if;
- while Present (Decl) and then Decl /= Eq_Decl loop
+ elsif BIP_Suffix_Kind (Formal_1) /= BIP_Suffix_Kind (Formal_2) then
+ return False;
+ end if;
- -- The declaration of an object of the type
+ Formal_1 := Next_Formal_With_Extras (Formal_1);
+ Formal_2 := Next_Formal_With_Extras (Formal_2);
+ end loop;
- if Nkind (Decl) = N_Object_Declaration
- and then Etype (Defining_Identifier (Decl)) = Typ
- then
- Freezing_Point_Warning (Decl, "declaration");
- exit;
+ return No (Formal_1) and then No (Formal_2);
+ end;
+ end Extra_Formals_Match_OK;
- -- The instantiation of a generic on the type
+ ----------------------
+ -- Extra_Formals_OK --
+ ----------------------
- elsif Nkind (Decl) in N_Generic_Instantiation
- and then Is_Actual_Of_Instantiation (Typ, Decl)
- then
- Freezing_Point_Warning (Decl, "instantiation");
- exit;
+ function Extra_Formals_OK (E : Entity_Id) return Boolean is
+ Last_Formal : Entity_Id := Empty;
+ Formal : Entity_Id;
+ Has_Extra_Formals : Boolean := False;
- -- A noninstance proper body, body stub or entry body
+ begin
+ -- No check required if explicitly disabled
- elsif Nkind (Decl) in N_Proper_Body
- | N_Body_Stub
- | N_Entry_Body
- and then not Is_Generic_Instance (Defining_Entity (Decl))
- then
- Freezing_Point_Warning (Decl, "body");
- exit;
+ if Debug_Flag_Underscore_XX then
+ return True;
- -- If we have reached the freeze node and immediately after we
- -- have the body or generated code for the body, then it is the
- -- body that caused the freezing and this is legal.
+ -- No check required if expansion is disabled because extra
+ -- formals are only generated when we are generating code.
+ -- See Create_Extra_Formals.
- elsif Nkind (Decl) = N_Freeze_Entity
- and then Entity (Decl) = Typ
- and then (Next (Decl) = Eq_Decl
- or else
- Sloc (Next (Decl)) = Sloc (Eq_Decl))
- then
- return;
- end if;
+ elsif not Expander_Active then
+ return True;
+ end if;
- Next (Decl);
- end loop;
+ -- Check attribute Extra_Formal: If available, it must be set only
+ -- on the last formal of E.
- -- Here we have a definite error of declaration after freezing
+ Formal := First_Formal (E);
+ while Present (Formal) loop
+ if Present (Extra_Formal (Formal)) then
+ if Has_Extra_Formals then
+ return False;
+ end if;
- if Ada_Version >= Ada_2012 then
- Error_Msg_NE
- ("equality operator must be declared before type & is "
- & "frozen (RM 4.5.2 (9.8)) (Ada 2012)<<", Eq_Op, Typ);
+ Has_Extra_Formals := True;
+ end if;
- -- In Ada 2012 mode with error turned to warning, output one
- -- more warning to warn that the equality operation may not
- -- compose. This is the consequence of ignoring the error.
+ Last_Formal := Formal;
+ Next_Formal (Formal);
+ end loop;
- if Error_Msg_Warn then
- Error_Msg_N ("\equality operation may not compose??", Eq_Op);
- end if;
+ -- Check attribute Extra_Accessibility_Of_Result
- else
- Error_Msg_NE
- ("equality operator must be declared before type& is "
- & "frozen (RM 4.5.2 (9.8)) (Ada 2012)?y?", Eq_Op, Typ);
- end if;
+ if Ekind (E) in E_Function | E_Subprogram_Type
+ and then Needs_Result_Accessibility_Level (E)
+ and then No (Extra_Accessibility_Of_Result (E))
+ then
+ return False;
+ end if;
- -- If we have found no freezing point and the declaration of the
- -- operator could not be reached from that of the type and we are
- -- in a package body, this must be because the type is declared
- -- in the spec of the package. Add a message tailored to this.
+ -- Check attribute Extra_Formals: If E has extra formals, then this
+ -- attribute must point to the first extra formal of E.
- if No (Decl) and then In_Package_Body (Scope (Typ)) then
- if Ada_Version >= Ada_2012 then
- if Nkind (Eq_Decl) = N_Subprogram_Body then
- Error_Msg_N
- ("\put declaration in package spec<<", Eq_Op);
- else
- Error_Msg_N
- ("\move declaration to package spec<<", Eq_Op);
- end if;
+ if Has_Extra_Formals then
+ return Present (Extra_Formals (E))
+ and then Present (Extra_Formal (Last_Formal))
+ and then Extra_Formal (Last_Formal) = Extra_Formals (E);
- else
- if Nkind (Eq_Decl) = N_Subprogram_Body then
- Error_Msg_N
- ("\put declaration in package spec (Ada 2012)?y?",
- Eq_Op);
- else
- Error_Msg_N
- ("\move declaration to package spec (Ada 2012)?y?",
- Eq_Op);
- end if;
- end if;
- end if;
- end if;
+ -- When E has no formals, the first extra formal is available through
+ -- the Extra_Formals attribute.
- -- Now check for AI12-0352: the declaration of a user-defined primitive
- -- equality operation for a record type T is illegal if it occurs after
- -- a type has been derived from T.
+ elsif Present (Extra_Formals (E)) then
+ return No (First_Formal (E));
else
- Decl := Next (Declaration_Node (Typ));
-
- while Present (Decl) and then Decl /= Eq_Decl loop
- if Nkind (Decl) = N_Full_Type_Declaration
- and then Etype (Defining_Identifier (Decl)) = Typ
- then
- Error_Msg_N
- ("equality operator cannot appear after derivation", Eq_Op);
- Error_Msg_NE
- ("an equality operator for& cannot be declared after "
- & "this point??",
- Decl, Typ);
- end if;
-
- Next (Decl);
- end loop;
+ return True;
end if;
- end Check_Untagged_Equality;
+ end Extra_Formals_OK;
-----------------------------
-- Find_Corresponding_Spec --
@@ -10656,6 +10551,89 @@ package body Sem_Ch6 is
end if;
end Fully_Conformant_Discrete_Subtypes;
+ ---------------------
+ -- Has_BIP_Formals --
+ ---------------------
+
+ function Has_BIP_Formals (E : Entity_Id) return Boolean is
+ Formal : Entity_Id := First_Formal_With_Extras (E);
+
+ begin
+ while Present (Formal) loop
+ if Is_Build_In_Place_Entity (Formal) then
+ return True;
+ end if;
+
+ Next_Formal_With_Extras (Formal);
+ end loop;
+
+ return False;
+ end Has_BIP_Formals;
+
+ --------------------------------
+ -- Has_Reliable_Extra_Formals --
+ --------------------------------
+
+ function Has_Reliable_Extra_Formals (E : Entity_Id) return Boolean is
+ Alias_E : Entity_Id;
+
+ begin
+ -- Extra formals are not added if expansion is not active (and hence if
+ -- available they are not reliable for extra formals check).
+
+ if not Expander_Active then
+ return False;
+
+ -- Currently the unique cases where extra formals are not reliable
+ -- are associated with predefined dispatching operations; otherwise
+ -- they are properly added when required.
+
+ elsif not Is_Predefined_Dispatching_Operation (E) then
+ return True;
+ end if;
+
+ Alias_E := Ultimate_Alias (E);
+
+ -- Abstract predefined primitives of Root_Controlled don't have
+ -- extra formals; this is required to build the runtime.
+
+ if Ekind (Alias_E) = E_Function
+ and then Is_Abstract_Subprogram (Alias_E)
+ and then Is_RTE (Underlying_Type (Etype (Alias_E)),
+ RE_Root_Controlled)
+ then
+ return False;
+
+ -- Predefined stream dispatching operations that are not emitted by
+ -- the frontend; they have a renaming of the corresponding primitive
+ -- of their parent type and hence they don't have extra formals.
+
+ else
+ declare
+ Typ : constant Entity_Id :=
+ Underlying_Type (Find_Dispatching_Type (Alias_E));
+
+ begin
+ if (Get_TSS_Name (E) = TSS_Stream_Input
+ and then not Stream_Operation_OK (Typ, TSS_Stream_Input))
+ or else
+ (Get_TSS_Name (E) = TSS_Stream_Output
+ and then not Stream_Operation_OK (Typ, TSS_Stream_Output))
+ or else
+ (Get_TSS_Name (E) = TSS_Stream_Read
+ and then not Stream_Operation_OK (Typ, TSS_Stream_Read))
+ or else
+ (Get_TSS_Name (E) = TSS_Stream_Write
+ and then not Stream_Operation_OK (Typ, TSS_Stream_Write))
+ then
+ return False;
+ end if;
+ end;
+ end if;
+
+ return True;
+ end Has_Reliable_Extra_Formals;
+
--------------------
-- Install_Entity --
--------------------
@@ -10711,13 +10689,13 @@ package body Sem_Ch6 is
E : Entity_Id;
begin
- E := First_Entity (Prim);
+ E := First_Formal (Prim);
while Present (E) loop
- if Is_Formal (E) and then Is_Controlling_Formal (E) then
+ if Is_Controlling_Formal (E) then
return E;
end if;
- Next_Entity (E);
+ Next_Formal (E);
end loop;
return Empty;
@@ -11043,7 +11021,7 @@ package body Sem_Ch6 is
procedure List_Inherited_Pre_Post_Aspects (E : Entity_Id) is
begin
- if Opt.List_Inherited_Aspects
+ if List_Inherited_Aspects
and then Is_Subprogram_Or_Generic_Subprogram (E)
then
declare
@@ -11389,7 +11367,7 @@ package body Sem_Ch6 is
return False;
end if;
- if not Present (Partial_View) then
+ if No (Partial_View) then
return True;
end if;
@@ -11403,7 +11381,7 @@ package body Sem_Ch6 is
begin
loop
H := Homonym (H);
- exit when not Present (H) or else Scope (H) /= Scope (S);
+ exit when No (H) or else Scope (H) /= Scope (S);
if Nkind (Parent (H)) in
N_Private_Extension_Declaration |
@@ -11451,7 +11429,7 @@ package body Sem_Ch6 is
if ((Present (Partial_View)
and then Is_Tagged_Type (Partial_View))
- or else (not Present (Partial_View)
+ or else (No (Partial_View)
and then Is_Tagged_Type (T)))
and then T = Base_Type (Etype (S))
then
@@ -12527,7 +12505,7 @@ package body Sem_Ch6 is
if Is_Dispatching_Operation (E) then
-- An overriding dispatching subprogram inherits the
- -- convention of the overridden subprogram (AI-117).
+ -- convention of the overridden subprogram (AI95-117).
Set_Convention (S, Convention (E));
Check_Dispatching_Operation (S, E);
@@ -12947,7 +12925,7 @@ package body Sem_Ch6 is
-- No need to continue if we already notified errors
- if not Present (Formal_Type) then
+ if No (Formal_Type) then
return;
end if;
diff --git a/gcc/ada/sem_ch6.ads b/gcc/ada/sem_ch6.ads
index da56ce6..5f0e1ba 100644
--- a/gcc/ada/sem_ch6.ads
+++ b/gcc/ada/sem_ch6.ads
@@ -174,6 +174,22 @@ package Sem_Ch6 is
-- the end of Subp's parameter list (with each subsequent extra formal
-- being attached to the preceding extra formal).
+ function Extra_Formals_Match_OK
+ (E : Entity_Id;
+ Ref_E : Entity_Id) return Boolean;
+ -- Return True if the extra formals of the given entities match. E is a
+ -- subprogram, and Ref_E is the reference entity that will be used to check
+ -- the extra formals of E: a subprogram type or another subprogram. For
+ -- example, if E is a dispatching primitive of a tagged type then Ref_E
+ -- may be the overridden primitive of its parent type or its ultimate
+ -- renamed entity; however, if E is a subprogram to which 'Access is
+ -- applied then Ref_E is its corresponding subprogram type. Used in
+ -- assertions.
+
+ function Extra_Formals_OK (E : Entity_Id) return Boolean;
+ -- Return True if the decoration of the attributes associated with extra
+ -- formals are properly set. Used in assertions.
+
function Find_Corresponding_Spec
(N : Node_Id;
Post_Error : Boolean := True) return Entity_Id;
@@ -197,6 +213,9 @@ package Sem_Ch6 is
-- Determines if two subtype definitions are fully conformant. Used
-- for entry family conformance checks (RM 6.3.1 (24)).
+ function Has_BIP_Formals (E : Entity_Id) return Boolean;
+ -- Determines if a given entity has build-in-place formals
+
procedure Install_Entity (E : Entity_Id);
-- Place a single entity on the visibility chain
diff --git a/gcc/ada/sem_ch7.adb b/gcc/ada/sem_ch7.adb
index 5c347bd..2847069 100644
--- a/gcc/ada/sem_ch7.adb
+++ b/gcc/ada/sem_ch7.adb
@@ -72,6 +72,7 @@ with Sinfo.Utils; use Sinfo.Utils;
with Sinput; use Sinput;
with Style;
with Uintp; use Uintp;
+with Warnsw; use Warnsw;
with GNAT.HTable;
@@ -1242,11 +1243,11 @@ package body Sem_Ch7 is
Check_Completion;
-- If the package spec does not require an explicit body, then all
- -- abstract states declared in nested packages cannot possibly get
- -- a proper refinement (SPARK RM 7.2.2(3)). This check is performed
- -- only when the compilation unit is the main unit to allow for
- -- modular SPARK analysis where packages do not necessarily have
- -- bodies.
+ -- abstract states declared in nested packages cannot possibly get a
+ -- proper refinement (SPARK RM 7.1.4(4) and SPARK RM 7.2.2(3)). This
+ -- check is performed only when the compilation unit is the main
+ -- unit to allow for modular SPARK analysis where packages do not
+ -- necessarily have bodies.
if Is_Comp_Unit then
Check_State_Refinements
@@ -1317,11 +1318,10 @@ package body Sem_Ch7 is
-- private_with_clauses, and remove them at the end of the nested
-- package.
- procedure Clear_Constants (Id : Entity_Id; FE : Entity_Id);
- -- Clears constant indications (Never_Set_In_Source, Constant_Value, and
- -- Is_True_Constant) on all variables that are entities of Id, and on
- -- the chain whose first element is FE. A recursive call is made for all
- -- packages and generic packages.
+ procedure Clear_Constants (Id : Entity_Id);
+ -- Clears constant indications (Never_Set_In_Source, Constant_Value,
+ -- and Is_True_Constant) on all variables that are entities of Id.
+ -- A recursive call is made for all packages and generic packages.
procedure Generate_Parent_References;
-- For a child unit, generate references to parent units, for
@@ -1352,7 +1352,7 @@ package body Sem_Ch7 is
-- Clear_Constants --
---------------------
- procedure Clear_Constants (Id : Entity_Id; FE : Entity_Id) is
+ procedure Clear_Constants (Id : Entity_Id) is
E : Entity_Id;
begin
@@ -1368,9 +1368,9 @@ package body Sem_Ch7 is
-- package can contain a renaming declaration to itself, and such
-- renamings are generated automatically within package instances.
- E := FE;
+ E := First_Entity (Id);
while Present (E) and then E /= Id loop
- if Is_Assignable (E) then
+ if Ekind (E) = E_Variable then
Set_Never_Set_In_Source (E, False);
Set_Is_True_Constant (E, False);
Set_Current_Value (E, Empty);
@@ -1382,8 +1382,7 @@ package body Sem_Ch7 is
end if;
elsif Is_Package_Or_Generic_Package (E) then
- Clear_Constants (E, First_Entity (E));
- Clear_Constants (E, First_Private_Entity (E));
+ Clear_Constants (E);
end if;
Next_Entity (E);
@@ -2009,8 +2008,7 @@ package body Sem_Ch7 is
if Is_Library_Level_Entity (Id)
or else Is_Generic_Instance (Id)
then
- Clear_Constants (Id, First_Entity (Id));
- Clear_Constants (Id, First_Private_Entity (Id));
+ Clear_Constants (Id);
end if;
-- Output relevant information as to why the package requires a body.
diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
index eb9e359..841076b 100644
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -76,6 +76,7 @@ with Style;
with Table;
with Tbuild; use Tbuild;
with Uintp; use Uintp;
+with Warnsw; use Warnsw;
package body Sem_Ch8 is
@@ -960,7 +961,7 @@ package body Sem_Ch8 is
Set_Etype (Nam, T);
end if;
elsif Present (Subtype_Mark (N))
- or else not Present (Access_Definition (N))
+ or else No (Access_Definition (N))
then
if Present (Subtype_Mark (N)) then
Find_Type (Subtype_Mark (N));
@@ -4702,7 +4703,7 @@ package body Sem_Ch8 is
-- want to deal with AST_Handler in ZFP mode.
if not Configurable_Run_Time_Mode
- and then not Present (Corresponding_Formal_Spec (N))
+ and then No (Corresponding_Formal_Spec (N))
and then not Is_RTE (Etype (Nam), RE_AST_Handler)
then
declare
@@ -4890,6 +4891,18 @@ package body Sem_Ch8 is
then
null;
+ -- Don't replace the discriminant in strict preanalysis mode since
+ -- it can lead to errors during full analysis when the discriminant
+ -- gets referenced later.
+
+ -- This can occur in situations where a protected type contains
+ -- an expression function which references a discriminant.
+
+ elsif Preanalysis_Active
+ and then Inside_Preanalysis_Without_Freezing = 0
+ then
+ null;
+
else
Set_Entity (N, Discriminal (E));
end if;
@@ -6047,21 +6060,6 @@ package body Sem_Ch8 is
if Is_Type (Entity (N)) then
Set_Etype (N, Entity (N));
- -- The exception to this general rule are constants associated with
- -- discriminals of protected types because for each protected op
- -- a new set of discriminals is internally created by the frontend
- -- (see Exp_Ch9.Set_Discriminals), and the current decoration of the
- -- entity pointer may have been set as part of a preanalysis, where
- -- discriminals still reference the first subprogram or entry to be
- -- expanded (see Expand_Protected_Body_Declarations).
-
- elsif Full_Analysis
- and then Ekind (Entity (N)) = E_Constant
- and then Present (Discriminal_Link (Entity (N)))
- and then Is_Protected_Type (Scope (Discriminal_Link (Entity (N))))
- then
- goto Find_Name;
-
else
declare
Entyp : constant Entity_Id := Etype (Entity (N));
@@ -6101,8 +6099,6 @@ package body Sem_Ch8 is
return;
end if;
- <<Find_Name>>
-
-- Preserve relevant elaboration-related attributes of the context which
-- are no longer available or very expensive to recompute once analysis,
-- resolution, and expansion are over.
@@ -7918,7 +7914,7 @@ package body Sem_Ch8 is
if Is_Type (P_Type)
and then (Has_Components (P_Type)
- or else (Extensions_Allowed
+ or else (Core_Extensions_Allowed
and then not Is_Concurrent_Type (P_Type)))
and then not Is_Overloadable (P_Name)
and then not Is_Type (P_Name)
@@ -8173,7 +8169,7 @@ package body Sem_Ch8 is
("prefixed call is only allowed for objects of a "
& "tagged type unless -gnatX is used", N);
- if not Extensions_Allowed
+ if not Core_Extensions_Allowed
and then
Try_Object_Operation (N, Allow_Extensions => True)
then
@@ -9272,9 +9268,9 @@ package body Sem_Ch8 is
Scope1 := Scope (Scope1);
Scope2 := Scope (Scope2);
- if not Present (Scope1) then
+ if No (Scope1) then
return Clause1;
- elsif not Present (Scope2) then
+ elsif No (Scope2) then
return Clause2;
end if;
end loop;
@@ -9717,10 +9713,10 @@ package body Sem_Ch8 is
-- we saved (we use Remove, since this list will not be used again).
loop
- Elmt := Last_Elmt (List);
+ Elmt := First_Elmt (List);
exit when Elmt = No_Elmt;
Set_Is_Immediately_Visible (Node (Elmt));
- Remove_Last_Elmt (List);
+ Remove_Elmt (List, Elmt);
end loop;
-- Restore use clauses
diff --git a/gcc/ada/sem_ch9.adb b/gcc/ada/sem_ch9.adb
index f2a5901..aad86fa 100644
--- a/gcc/ada/sem_ch9.adb
+++ b/gcc/ada/sem_ch9.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Accessibility; use Accessibility;
with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
@@ -463,7 +464,7 @@ package body Sem_Ch9 is
-- References
- elsif Kind = N_Identifier
+ elsif Kind in N_Identifier | N_Expanded_Name
and then Present (Entity (N))
then
declare
@@ -474,6 +475,12 @@ package body Sem_Ch9 is
begin
-- Prohibit references to non-constant entities
-- outside the protected subprogram scope.
+ --
+ -- References to variables in System.Scalar_Values
+ -- generated because of pragma Initialize_Scalars are
+ -- allowed, because once those variables are
+ -- initialized by the binder-generated code, they
+ -- behave like constants.
if Is_Assignable (Id)
and then not
@@ -482,6 +489,9 @@ package body Sem_Ch9 is
Scope_Within_Or_Same
(Scope (Id),
Protected_Body_Subprogram (Sub_Id))
+ and then not
+ (Is_RTU (Scope (Id), System_Scalar_Values)
+ and then not Comes_From_Source (N))
then
if Lock_Free_Given then
Error_Msg_NE
@@ -564,7 +574,7 @@ package body Sem_Ch9 is
-- reference only one component of the protected type, plus
-- the type of the component must support atomic operation.
- if Kind = N_Identifier
+ if Kind in N_Identifier | N_Expanded_Name
and then Present (Entity (N))
then
declare
diff --git a/gcc/ada/sem_dim.adb b/gcc/ada/sem_dim.adb
index a24b9d7..801339a 100644
--- a/gcc/ada/sem_dim.adb
+++ b/gcc/ada/sem_dim.adb
@@ -1316,7 +1316,7 @@ package body Sem_Dim is
-- Look at the named components right after the positional components
- if not Present (Next (Comp))
+ if No (Next (Comp))
and then List_Containing (Comp) = Exps
then
Comp := First (Comp_Ass);
diff --git a/gcc/ada/sem_disp.adb b/gcc/ada/sem_disp.adb
index ee1d96e..af26013 100644
--- a/gcc/ada/sem_disp.adb
+++ b/gcc/ada/sem_disp.adb
@@ -3072,18 +3072,27 @@ package body Sem_Disp is
if Tagged_Type_Expansion then
declare
- Call_Typ : constant Entity_Id := Etype (Call_Node);
+ Call_Typ : Entity_Id := Etype (Call_Node);
+ Ctrl_Typ : Entity_Id := Etype (Control);
begin
Expand_Dispatching_Call (Call_Node);
+ if Is_Class_Wide_Type (Call_Typ) then
+ Call_Typ := Root_Type (Call_Typ);
+ end if;
+
+ if Is_Class_Wide_Type (Ctrl_Typ) then
+ Ctrl_Typ := Root_Type (Ctrl_Typ);
+ end if;
+
-- If the controlling argument is an interface type and the type
-- of Call_Node differs then we must add an implicit conversion to
-- force displacement of the pointer to the object to reference
-- the secondary dispatch table of the interface.
- if Is_Interface (Etype (Control))
- and then Etype (Control) /= Call_Typ
+ if Is_Interface (Ctrl_Typ)
+ and then Ctrl_Typ /= Call_Typ
then
-- Cannot use Convert_To because the previous call to
-- Expand_Dispatching_Call leaves decorated the Call_Node
diff --git a/gcc/ada/sem_elab.adb b/gcc/ada/sem_elab.adb
index f912f8b..9bf8614 100644
--- a/gcc/ada/sem_elab.adb
+++ b/gcc/ada/sem_elab.adb
@@ -64,6 +64,7 @@ with Table;
with Tbuild; use Tbuild;
with Uintp; use Uintp;
with Uname; use Uname;
+with Warnsw; use Warnsw;
with GNAT; use GNAT;
with GNAT.Dynamic_HTables; use GNAT.Dynamic_HTables;
@@ -880,6 +881,10 @@ package body Sem_Elab is
-- The subprogram body traversal mode. Once set, this value should not
-- be changed.
+ Within_Freezing_Actions : Boolean := False;
+ -- This flag is set when the Processing phase is currently examining a
+ -- scenario which was reached from the actions of a freeze node.
+
Within_Generic : Boolean := False;
-- This flag is set when the Processing phase is currently within a
-- generic unit.
@@ -5352,6 +5357,7 @@ package body Sem_Elab is
Subp_Id : constant Entity_Id := Target (Call_Rep);
Subp_Rep : constant Target_Rep_Id :=
Target_Representation_Of (Subp_Id, In_State);
+ Body_Decl : constant Node_Id := Body_Declaration (Subp_Rep);
Subp_Decl : constant Node_Id := Spec_Declaration (Subp_Rep);
SPARK_Rules_On : constant Boolean :=
@@ -5451,6 +5457,16 @@ package body Sem_Elab is
or else not Elaboration_Warnings_OK (Call_Rep)
or else not Elaboration_Warnings_OK (Subp_Rep);
+ -- The call occurs in freezing actions context when a prior scenario
+ -- is already in that mode, or when the target is a subprogram whose
+ -- body has been generated as a freezing action. Update the state of
+ -- the Processing phase to reflect this.
+
+ New_In_State.Within_Freezing_Actions :=
+ New_In_State.Within_Freezing_Actions
+ or else (Present (Body_Decl)
+ and then Nkind (Parent (Body_Decl)) = N_Freeze_Entity);
+
-- The call occurs in an initial condition context when a prior
-- scenario is already in that mode, or when the target is an
-- Initial_Condition procedure. Update the state of the Processing
@@ -5501,7 +5517,7 @@ package body Sem_Elab is
In_State => New_In_State);
Traverse_Conditional_ABE_Body
- (N => Body_Declaration (Subp_Rep),
+ (N => Body_Decl,
In_State => New_In_State);
end Process_Conditional_ABE_Call;
@@ -5720,6 +5736,13 @@ package body Sem_Elab is
if In_State.Suppress_Warnings then
null;
+ -- Do not emit any ABE diagnostics when the call occurs in a
+ -- freezing actions context because this leads to incorrect
+ -- diagnostics.
+
+ elsif In_State.Within_Freezing_Actions then
+ null;
+
-- Do not emit any ABE diagnostics when the call occurs in an
-- initial condition context because this leads to incorrect
-- diagnostics.
diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb
index 2ba4608..bec91ad 100644
--- a/gcc/ada/sem_eval.adb
+++ b/gcc/ada/sem_eval.adb
@@ -61,6 +61,7 @@ with Snames; use Snames;
with Stand; use Stand;
with Stringt; use Stringt;
with Tbuild; use Tbuild;
+with Warnsw; use Warnsw;
package body Sem_Eval is
@@ -1823,6 +1824,7 @@ package body Sem_Eval is
return False;
elsif Op = Error
+ or else Nkind (Op) not in N_Has_Etype
or else Etype (Op) = Any_Type
or else Raises_Constraint_Error (Op)
then
@@ -2856,10 +2858,11 @@ package body Sem_Eval is
return;
end if;
- -- Intrinsic calls as part of a static function is a language extension.
+ -- Intrinsic calls as part of a static function is a (core)
+ -- language extension.
if Checking_Potentially_Static_Expression
- and then not Extensions_Allowed
+ and then not Core_Extensions_Allowed
then
return;
end if;
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index f85d091..f3c23ca 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -63,6 +63,7 @@ with Sem; use Sem;
with Sem_Aux; use Sem_Aux;
with Sem_Ch3; use Sem_Ch3;
with Sem_Ch6; use Sem_Ch6;
+with Sem_Ch7; use Sem_Ch7;
with Sem_Ch8; use Sem_Ch8;
with Sem_Ch12; use Sem_Ch12;
with Sem_Ch13; use Sem_Ch13;
@@ -2115,9 +2116,16 @@ package body Sem_Prag is
First (Pragma_Argument_Associations (N));
Obj_Decl : constant Node_Id := Find_Related_Context (N);
Obj_Id : constant Entity_Id := Defining_Entity (Obj_Decl);
+ Obj_Typ : Entity_Id;
Expr : Node_Id;
begin
+ if Is_Type (Obj_Id) then
+ Obj_Typ := Obj_Id;
+ else
+ Obj_Typ := Etype (Obj_Id);
+ end if;
+
-- Ensure that the Boolean expression (if present) is static. A missing
-- argument defaults the value to True (SPARK RM 7.1.2(5)).
@@ -2152,9 +2160,7 @@ package body Sem_Prag is
if Prag_Id /= Pragma_No_Caching
and then not Is_Effectively_Volatile (Obj_Id)
then
- if Ekind (Obj_Id) = E_Variable
- and then No_Caching_Enabled (Obj_Id)
- then
+ if No_Caching_Enabled (Obj_Id) then
if Expr_Val then -- Confirming value of False is allowed
SPARK_Msg_N
("illegal combination of external property % and property "
@@ -2166,15 +2172,16 @@ package body Sem_Prag is
N);
end if;
- -- Pragma No_Caching should only apply to volatile variables of
+ -- Pragma No_Caching should only apply to volatile types or variables of
-- a non-effectively volatile type (SPARK RM 7.1.2).
elsif Prag_Id = Pragma_No_Caching then
- if Is_Effectively_Volatile (Etype (Obj_Id)) then
- SPARK_Msg_N ("property % must not apply to an object of "
+ if Is_Effectively_Volatile (Obj_Typ) then
+ SPARK_Msg_N ("property % must not apply to a type or object of "
& "an effectively volatile type", N);
elsif not Is_Volatile (Obj_Id) then
- SPARK_Msg_N ("property % must apply to a volatile object", N);
+ SPARK_Msg_N
+ ("property % must apply to a volatile type or object", N);
end if;
end if;
@@ -3567,6 +3574,21 @@ package body Sem_Prag is
return;
end if;
+ -- In the case of state in a (descendant of a private) child which
+ -- is Part_Of the state of another package, the package defining the
+ -- encapsulating abstract state should have a body, to ensure that it
+ -- has a state refinement (SPARK RM 7.1.4(4)).
+
+ if Enclosing_Comp_Unit_Node (Encap_Id) /=
+ Enclosing_Comp_Unit_Node (Item_Id)
+ and then not Unit_Requires_Body (Scope (Encap_Id))
+ then
+ SPARK_Msg_N
+ ("indicator Part_Of must denote abstract state of package "
+ & "with a body (SPARK RM 7.1.4(4))", Indic);
+ return;
+ end if;
+
-- At this point it is known that the Part_Of indicator is legal
Legal := True;
@@ -4549,6 +4571,11 @@ package body Sem_Prag is
elsif Nkind (Subp_Decl) = N_Single_Task_Declaration then
null;
+ -- Abstract subprogram declaration
+
+ elsif Nkind (Subp_Decl) = N_Abstract_Subprogram_Declaration then
+ null;
+
-- Subprogram body acts as spec
elsif Nkind (Subp_Decl) = N_Subprogram_Body
@@ -7315,22 +7342,16 @@ package body Sem_Prag is
Parent_Node : Node_Id;
begin
- if not Is_List_Member (N) then
- return False;
-
- else
+ if Is_List_Member (N) then
Plist := List_Containing (N);
Parent_Node := Parent (Plist);
- if Parent_Node = Empty
- or else Nkind (Parent_Node) /= N_Compilation_Unit
- or else Context_Items (Parent_Node) /= Plist
- then
- return False;
- end if;
+ return Present (Parent_Node)
+ and then Nkind (Parent_Node) = N_Compilation_Unit
+ and then Context_Items (Parent_Node) = Plist;
end if;
- return True;
+ return False;
end Is_In_Context_Clause;
---------------------------------
@@ -13469,22 +13490,19 @@ package body Sem_Prag is
Obj_Or_Type_Decl := Find_Related_Context (N, Do_Checks => True);
-- Pragma must apply to a object declaration or to a type
- -- declaration (only the former in the No_Caching case).
- -- Original_Node is necessary to account for untagged derived
- -- types that are rewritten as subtypes of their
- -- respective root types.
-
- if Nkind (Obj_Or_Type_Decl) /= N_Object_Declaration then
- if Prag_Id = Pragma_No_Caching
- or else Nkind (Original_Node (Obj_Or_Type_Decl)) not in
- N_Full_Type_Declaration |
- N_Private_Type_Declaration |
- N_Formal_Type_Declaration |
- N_Task_Type_Declaration |
- N_Protected_Type_Declaration
- then
- Pragma_Misplaced;
- end if;
+ -- declaration. Original_Node is necessary to account for
+ -- untagged derived types that are rewritten as subtypes of
+ -- their respective root types.
+
+ if Nkind (Obj_Or_Type_Decl) /= N_Object_Declaration
+ and then Nkind (Original_Node (Obj_Or_Type_Decl)) not in
+ N_Full_Type_Declaration |
+ N_Private_Type_Declaration |
+ N_Formal_Type_Declaration |
+ N_Task_Type_Declaration |
+ N_Protected_Type_Declaration
+ then
+ Pragma_Misplaced;
end if;
Obj_Or_Type_Id := Defining_Entity (Obj_Or_Type_Decl);
@@ -15408,12 +15426,12 @@ package body Sem_Prag is
-- aspect/pragma from parent types (see Build_DIC_Procedure_Body),
-- though that extra argument isn't documented for the pragma.
- if not Present (Arg2) then
+ if No (Arg2) then
-- When the pragma has no arguments, create an argument with
-- the value Empty, so the type name argument can be appended
-- following it (since it's expected as the second argument).
- if not Present (Arg1) then
+ if No (Arg1) then
Set_Pragma_Argument_Associations (N, New_List (
Make_Pragma_Argument_Association (Sloc (Typ),
Expression => Empty)));
@@ -16595,16 +16613,18 @@ package body Sem_Prag is
-- Extensions_Allowed --
------------------------
- -- pragma Extensions_Allowed (ON | OFF);
+ -- pragma Extensions_Allowed (ON | OFF | ALL);
when Pragma_Extensions_Allowed =>
GNAT_Pragma;
Check_Arg_Count (1);
Check_No_Identifiers;
- Check_Arg_Is_One_Of (Arg1, Name_On, Name_Off);
+ Check_Arg_Is_One_Of (Arg1, Name_On, Name_Off, Name_All);
if Chars (Get_Pragma_Arg (Arg1)) = Name_On then
- Ada_Version := Ada_With_Extensions;
+ Ada_Version := Ada_With_Core_Extensions;
+ elsif Chars (Get_Pragma_Arg (Arg1)) = Name_All then
+ Ada_Version := Ada_With_All_Extensions;
else
Ada_Version := Ada_Version_Explicit;
Ada_Version_Pragma := Empty;
@@ -20500,10 +20520,16 @@ package body Sem_Prag is
if No (Decl) then
- -- First case: library level compilation unit declaration with
+ -- Case 0: library level compilation unit declaration with
+ -- the pragma preceding the declaration.
+
+ if Nkind (Parent (N)) = N_Compilation_Unit then
+ Pragma_Misplaced;
+
+ -- Case 1: library level compilation unit declaration with
-- the pragma immediately following the declaration.
- if Nkind (Parent (N)) = N_Compilation_Unit_Aux then
+ elsif Nkind (Parent (N)) = N_Compilation_Unit_Aux then
Set_Obsolescent
(Defining_Entity (Unit (Parent (Parent (N)))));
return;
@@ -21095,6 +21121,25 @@ package body Sem_Prag is
if Partition_Elaboration_Policy_Sloc /= System_Location then
Partition_Elaboration_Policy_Sloc := Loc;
end if;
+
+ if PEP_Val = Name_Sequential
+ and then not Restriction_Active (No_Task_Hierarchy)
+ then
+ -- RM H.6(6) guarantees that No_Task_Hierarchy will be
+ -- set eventually, so take advantage of that knowledge now.
+ -- But we have to do this in a tricky way. If we simply
+ -- set the No_Task_Hierarchy restriction here, then the
+ -- assumption that the restriction will be set eventually
+ -- becomes a self-fulfilling prophecy; the binder can
+ -- then mistakenly conclude that the H.6(6) rule is
+ -- satisified in cases where the post-compilation check
+ -- should fail. So we invent a new restriction,
+ -- No_Task_Hierarchy_Implicit, which is treated specially
+ -- in the function Restriction_Active.
+
+ Set_Restriction (No_Task_Hierarchy_Implicit, N);
+ pragma Assert (Restriction_Active (No_Task_Hierarchy));
+ end if;
end if;
end PEP;
@@ -23422,10 +23467,14 @@ package body Sem_Prag is
Spec_Id : constant Entity_Id := Unique_Defining_Entity (Decl);
begin
- -- Ignore pragma when applied to the special body created for
- -- inlining, recognized by its internal name _Parent.
+ -- Ignore pragma when applied to the special body created
+ -- for inlining, recognized by its internal name _Parent; or
+ -- when applied to the special body created for contracts,
+ -- recognized by its internal name _Wrapped_Statements.
- if Chars (Body_Id) = Name_uParent then
+ if Chars (Body_Id) in Name_uParent
+ | Name_uWrapped_Statements
+ then
return;
end if;
@@ -25778,7 +25827,7 @@ package body Sem_Prag is
C := Get_String_Char (Str, J);
Chr := Get_Character (C);
- if not Set_Dot_Warning_Switch (Chr) then
+ if not Set_Warning_Switch ('.', Chr) then
Error_Pragma_Arg
("invalid warning switch character "
& '.' & Chr, Arg1);
@@ -25787,7 +25836,7 @@ package body Sem_Prag is
-- Non-Dot case
else
- OK := Set_Warning_Switch (Chr);
+ OK := Set_Warning_Switch (Plain, Chr);
end if;
if not OK then
@@ -26199,6 +26248,20 @@ package body Sem_Prag is
Check_Postcondition_Use_In_Inlined_Subprogram (N, Spec_Id);
Set_Is_Analyzed_Pragma (N);
+ -- If the subprogram is frozen then its class-wide pre- and post-
+ -- conditions have been preanalyzed (see Merge_Class_Conditions);
+ -- otherwise they must be preanalyzed now to ensure the correct
+ -- visibility of their referenced entities. This scenario occurs
+ -- when the subprogram is defined in a nested package (since the
+ -- end of the package does not cause freezing).
+
+ if Class_Present (N)
+ and then Is_Dispatching_Operation (Spec_Id)
+ and then not Is_Frozen (Spec_Id)
+ then
+ Preanalyze_Class_Conditions (Spec_Id);
+ end if;
+
Restore_Ghost_Region (Saved_GM, Saved_IGR);
end Analyze_Pre_Post_Condition_In_Decl_Part;
@@ -31717,43 +31780,45 @@ package body Sem_Prag is
-- Start of processing for Non_Significant_Pragma_Reference
begin
- P := Parent (N);
+ -- Reference might appear either directly as expression of a pragma
+ -- argument association, e.g. pragma Export (...), or within an
+ -- aggregate with component associations, e.g. pragma Refined_State
+ -- ((... => ...)).
- if Nkind (P) /= N_Pragma_Argument_Association then
-
- -- References within pragma Refined_State are not significant. They
- -- can't be recognized using pragma argument number, because they
- -- appear inside refinement clauses that rely on aggregate syntax.
+ P := Parent (N);
+ loop
+ case Nkind (P) is
+ when N_Pragma_Argument_Association =>
+ exit;
+ when N_Aggregate | N_Component_Association =>
+ P := Parent (P);
+ when others =>
+ return False;
+ end case;
+ end loop;
- if In_Pragma_Expression (N, Name_Refined_State) then
- return True;
- end if;
+ AN := Arg_No;
+ if AN = 0 then
return False;
+ end if;
- else
- Id := Get_Pragma_Id (Parent (P));
- C := Sig_Flags (Id);
- AN := Arg_No;
+ Id := Get_Pragma_Id (Parent (P));
+ C := Sig_Flags (Id);
- if AN = 0 then
+ case C is
+ when -1 =>
return False;
- end if;
-
- case C is
- when -1 =>
- return False;
- when 0 =>
- return True;
+ when 0 =>
+ return True;
- when 92 .. 99 =>
- return AN < (C - 90);
+ when 92 .. 99 =>
+ return AN < (C - 90);
- when others =>
- return AN /= C;
- end case;
- end if;
+ when others =>
+ return AN /= C;
+ end case;
end Is_Non_Significant_Pragma_Reference;
------------------------------
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index 7675070..b54ed93 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Accessibility; use Accessibility;
with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
@@ -90,6 +91,7 @@ with Targparm; use Targparm;
with Tbuild; use Tbuild;
with Uintp; use Uintp;
with Urealp; use Urealp;
+with Warnsw; use Warnsw;
package body Sem_Res is
@@ -171,6 +173,13 @@ package body Sem_Res is
-- of the task, it must be replaced with a reference to the discriminant
-- of the task being called.
+ procedure Resolve_Dependent_Expression
+ (N : Node_Id;
+ Expr : Node_Id;
+ Typ : Entity_Id);
+ -- Internal procedure to resolve the dependent expression Expr of the
+ -- conditional expression N with type Typ.
+
procedure Resolve_Op_Concat_Arg
(N : Node_Id;
Arg : Node_Id;
@@ -291,12 +300,6 @@ package body Sem_Res is
-- Called after N has been resolved and evaluated, but before range checks
-- have been applied. This rewrites the conversion into a simpler form.
- function Unique_Fixed_Point_Type (N : Node_Id) return Entity_Id;
- -- A universal_fixed expression in an universal context is unambiguous if
- -- there is only one applicable fixed point type. Determining whether there
- -- is only one requires a search over all visible entities, and happens
- -- only in very pathological cases (see 6115-006).
-
function Try_User_Defined_Literal
(N : Node_Id;
Typ : Entity_Id) return Boolean;
@@ -306,6 +309,12 @@ package body Sem_Res is
-- If such aspect exists, replace literal with a call to the
-- corresponding function and return True, return false otherwise.
+ function Unique_Fixed_Point_Type (N : Node_Id) return Entity_Id;
+ -- A universal_fixed expression in an universal context is unambiguous if
+ -- there is only one applicable fixed point type. Determining whether there
+ -- is only one requires a search over all visible entities, and happens
+ -- only in very pathological cases (see 6115-006).
+
-------------------------
-- Ambiguous_Character --
-------------------------
@@ -895,10 +904,6 @@ package body Sem_Res is
------------------------------
function Check_Infinite_Recursion (Call : Node_Id) return Boolean is
- function Enclosing_Declaration_Or_Statement (N : Node_Id) return Node_Id;
- -- Return the nearest enclosing declaration or statement that houses
- -- arbitrary node N.
-
function Invoked_With_Different_Arguments (N : Node_Id) return Boolean;
-- Determine whether call N invokes the related enclosing subprogram
-- with actuals that differ from the subprogram's formals.
@@ -934,33 +939,6 @@ package body Sem_Res is
-- Determine whether arbitrary node N appears within a conditional
-- construct.
- ----------------------------------------
- -- Enclosing_Declaration_Or_Statement --
- ----------------------------------------
-
- function Enclosing_Declaration_Or_Statement
- (N : Node_Id) return Node_Id
- is
- Par : Node_Id;
-
- begin
- Par := N;
- while Present (Par) loop
- if Is_Declaration (Par) or else Is_Statement (Par) then
- return Par;
-
- -- Prevent the search from going too far
-
- elsif Is_Body_Or_Package_Declaration (Par) then
- exit;
- end if;
-
- Par := Parent (Par);
- end loop;
-
- return N;
- end Enclosing_Declaration_Or_Statement;
-
--------------------------------------
-- Invoked_With_Different_Arguments --
--------------------------------------
@@ -2370,8 +2348,6 @@ package body Sem_Res is
("prefix must statically denote a non-remote subprogram", N);
end if;
- From_Lib := Comes_From_Predefined_Lib_Unit (N);
-
-- If the context is a Remote_Access_To_Subprogram, access attributes
-- must be resolved with the corresponding fat pointer. There is no need
-- to check for the attribute name since the return type of an
@@ -2494,6 +2470,15 @@ package body Sem_Res is
Found := True;
Expr_Type := Etype (Expression (N));
+ -- The resolution of a conditional expression that is the operand of a
+ -- type conversion is determined by the conversion (RM 4.5.7(10/3)).
+
+ elsif Nkind (N) in N_Case_Expression | N_If_Expression
+ and then Nkind (Parent (N)) = N_Type_Conversion
+ then
+ Found := True;
+ Expr_Type := Etype (Parent (N));
+
-- If not overloaded, then we know the type, and all that needs doing
-- is to check that this type is compatible with the context.
@@ -2505,6 +2490,8 @@ package body Sem_Res is
-- is compatible with the context (i.e. the type passed to Resolve)
else
+ From_Lib := Comes_From_Predefined_Lib_Unit (N);
+
-- Loop through possible interpretations
Get_First_Interp (N, I, It);
@@ -5635,7 +5622,7 @@ package body Sem_Res is
-- caller does use an allocator, it will be caught at the call site.
if No_Pool_Assigned (Typ)
- and then not Alloc_For_BIP_Return (N)
+ and then not For_Special_Return_Object (N)
then
Error_Msg_N ("allocation from empty storage pool!", N);
@@ -7421,7 +7408,8 @@ package body Sem_Res is
return;
end if;
- Resolve (Alt_Expr, Typ);
+ Resolve_Dependent_Expression (N, Alt_Expr, Typ);
+
Check_Unset_Reference (Alt_Expr);
Alt_Typ := Etype (Alt_Expr);
@@ -7702,6 +7690,34 @@ package body Sem_Res is
Check_Unset_Reference (Expr);
end Resolve_Declare_Expression;
+ -----------------------------------
+ -- Resolve_Dependent_Expression --
+ -----------------------------------
+
+ procedure Resolve_Dependent_Expression
+ (N : Node_Id;
+ Expr : Node_Id;
+ Typ : Entity_Id)
+ is
+ begin
+ -- RM 4.5.7(8/3) says that the expected type of dependent expressions is
+ -- that of the conditional expression but RM 4.5.7(10/3) forces the type
+ -- of the conditional expression without changing the expected type (the
+ -- expected type of the operand of a type conversion is any type), so we
+ -- may have a gap between these two types that is bridged by the dynamic
+ -- semantics specified by RM 4.5.7(20/3) with the associated legality
+ -- rule RM 4.5.7(16/3) that will be automatically enforced.
+
+ if Nkind (Parent (N)) = N_Type_Conversion
+ and then Nkind (Expr) /= N_Raise_Expression
+ then
+ Convert_To_And_Rewrite (Typ, Expr);
+ Analyze_And_Resolve (Expr);
+ else
+ Resolve (Expr, Typ);
+ end if;
+ end Resolve_Dependent_Expression;
+
-----------------------------------------
-- Resolve_Discrete_Subtype_Indication --
-----------------------------------------
@@ -9338,7 +9354,9 @@ package body Sem_Res is
---------------------------
procedure Resolve_If_Expression (N : Node_Id; Typ : Entity_Id) is
- procedure Apply_Check (Expr : Node_Id);
+ Condition : constant Node_Id := First (Expressions (N));
+
+ procedure Apply_Check (Expr : Node_Id; Result_Type : Entity_Id);
-- When a dependent expression is of a subtype different from
-- the context subtype, then insert a qualification to ensure
-- the generation of a constraint check. This was previously
@@ -9346,21 +9364,11 @@ package body Sem_Res is
-- that the context in general allows sliding, while a qualified
-- expression forces equality of bounds.
- Result_Type : Entity_Id := Typ;
- -- So in most cases the type of the If_Expression and of its
- -- dependent expressions is that of the context. However, if
- -- the expression is the index of an Indexed_Component, we must
- -- ensure that a proper index check is applied, rather than a
- -- range check on the index type (which might be discriminant
- -- dependent). In this case we resolve with the base type of the
- -- index type, and the index check is generated in the resolution
- -- of the indexed_component above.
-
-----------------
-- Apply_Check --
-----------------
- procedure Apply_Check (Expr : Node_Id) is
+ procedure Apply_Check (Expr : Node_Id; Result_Type : Entity_Id) is
Expr_Typ : constant Entity_Id := Etype (Expr);
Loc : constant Source_Ptr := Sloc (Expr);
@@ -9388,10 +9396,19 @@ package body Sem_Res is
-- Local variables
- Condition : constant Node_Id := First (Expressions (N));
Else_Expr : Node_Id;
Then_Expr : Node_Id;
+ Result_Type : Entity_Id;
+ -- So in most cases the type of the if_expression and of its
+ -- dependent expressions is that of the context. However, if
+ -- the expression is the index of an Indexed_Component, we must
+ -- ensure that a proper index check is applied, rather than a
+ -- range check on the index type (which might be discriminant
+ -- dependent). In this case we resolve with the base type of the
+ -- index type, and the index check is generated in the resolution
+ -- of the indexed_component above.
+
-- Start of processing for Resolve_If_Expression
begin
@@ -9406,6 +9423,9 @@ package body Sem_Res is
or else Nkind (Parent (Parent (N))) = N_Indexed_Component)
then
Result_Type := Base_Type (Typ);
+
+ else
+ Result_Type := Typ;
end if;
Then_Expr := Next (Condition);
@@ -9414,32 +9434,23 @@ package body Sem_Res is
return;
end if;
- Else_Expr := Next (Then_Expr);
-
Resolve (Condition, Any_Boolean);
- Resolve (Then_Expr, Result_Type);
Check_Unset_Reference (Condition);
+
+ Resolve_Dependent_Expression (N, Then_Expr, Result_Type);
+
Check_Unset_Reference (Then_Expr);
+ Apply_Check (Then_Expr, Result_Type);
- Apply_Check (Then_Expr);
+ Else_Expr := Next (Then_Expr);
-- If ELSE expression present, just resolve using the determined type
- -- If type is universal, resolve to any member of the class.
if Present (Else_Expr) then
- if Typ = Universal_Integer then
- Resolve (Else_Expr, Any_Integer);
-
- elsif Typ = Universal_Real then
- Resolve (Else_Expr, Any_Real);
-
- else
- Resolve (Else_Expr, Result_Type);
- end if;
+ Resolve_Dependent_Expression (N, Else_Expr, Result_Type);
Check_Unset_Reference (Else_Expr);
-
- Apply_Check (Else_Expr);
+ Apply_Check (Else_Expr, Result_Type);
-- Apply RM 4.5.7 (17/3): whether the expression is statically or
-- dynamically tagged must be known statically.
@@ -10094,6 +10105,55 @@ package body Sem_Res is
then
T := Etype (R);
+ -- If the type of the left operand is universal_integer and that of the
+ -- right operand is smaller, then we do not resolve the operands to the
+ -- tested type but to universal_integer instead. If not conforming to
+ -- the letter, it's conforming to the spirit of the specification of
+ -- membership tests, which are typically used to guard an operation and
+ -- ought not to fail a check in doing so. Without this, in the case of
+
+ -- type Small_Length is range 1 .. 16;
+
+ -- function Is_Small_String (S : String) return Boolean is
+ -- begin
+ -- return S'Length in Small_Length;
+ -- end;
+
+ -- the function Is_Small_String would fail a range check for strings
+ -- larger than 127 characters.
+
+ -- The test on the size is required in GNAT because universal_integer
+ -- does not cover all the values of all the supported integer types,
+ -- for example the large values of Long_Long_Long_Unsigned.
+
+ elsif not Is_Overloaded (L)
+ and then Etype (L) = Universal_Integer
+ and then (Is_Overloaded (R)
+ or else RM_Size (Etype (R)) < RM_Size (Universal_Integer))
+ then
+ T := Etype (L);
+
+ -- If the right operand is 'Range, we first need to resolve it (to
+ -- the tested type) so that it is rewritten as an N_Range, before
+ -- converting its bounds and resolving it again below.
+
+ if Nkind (R) = N_Attribute_Reference
+ and then Attribute_Name (R) = Name_Range
+ then
+ Resolve (R);
+ end if;
+
+ -- If the right operand is an N_Range, we convert its bounds to the
+ -- universal type before resolving it.
+
+ if Nkind (R) = N_Range then
+ Rewrite (R,
+ Make_Range (Sloc (R),
+ Low_Bound => Convert_To (T, Low_Bound (R)),
+ High_Bound => Convert_To (T, High_Bound (R))));
+ Analyze (R);
+ end if;
+
-- Ada 2005 (AI-251): Support the following case:
-- type I is interface;
@@ -10113,6 +10173,7 @@ package body Sem_Res is
and then not Is_Interface (Etype (R))
then
return;
+
else
T := Intersect_Types (L, R);
end if;
@@ -12200,6 +12261,12 @@ package body Sem_Res is
then
null;
+ -- Never give a warning if the operand is a conditional expression
+ -- because RM 4.5.7(10/3) forces its type to be the target type.
+
+ elsif Nkind (Orig_N) in N_Case_Expression | N_If_Expression then
+ null;
+
-- Finally, if this type conversion occurs in a context requiring
-- a prefix, and the expression is a qualified expression then the
-- type conversion is not redundant, since a qualified expression
diff --git a/gcc/ada/sem_type.adb b/gcc/ada/sem_type.adb
index 2fc82d1..718c297 100644
--- a/gcc/ada/sem_type.adb
+++ b/gcc/ada/sem_type.adb
@@ -1007,7 +1007,7 @@ package body Sem_Type is
elsif Ada_Version >= Ada_2022
and then T2 = Any_Composite
- and then Present (Find_Aspect (T1, Aspect_Aggregate))
+ and then Has_Aspect (T1, Aspect_Aggregate)
then
return True;
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index 25e886e..a1cebb0 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Accessibility; use Accessibility;
with Casing; use Casing;
with Checks; use Checks;
with Debug; use Debug;
@@ -30,7 +31,6 @@ with Einfo.Utils; use Einfo.Utils;
with Elists; use Elists;
with Errout; use Errout;
with Erroutc; use Erroutc;
-with Exp_Ch3; use Exp_Ch3;
with Exp_Ch6; use Exp_Ch6;
with Exp_Ch11; use Exp_Ch11;
with Exp_Util; use Exp_Util;
@@ -71,6 +71,7 @@ with Targparm; use Targparm;
with Tbuild; use Tbuild;
with Ttypes; use Ttypes;
with Uname; use Uname;
+with Warnsw; use Warnsw;
with GNAT.Heap_Sort_G;
with GNAT.HTable; use GNAT.HTable;
@@ -254,740 +255,6 @@ package body Sem_Util is
return Interface_List (Nod);
end Abstract_Interface_List;
- -------------------------
- -- Accessibility_Level --
- -------------------------
-
- function Accessibility_Level
- (Expr : Node_Id;
- Level : Accessibility_Level_Kind;
- In_Return_Context : Boolean := False;
- Allow_Alt_Model : Boolean := True) return Node_Id
- is
- Loc : constant Source_Ptr := Sloc (Expr);
-
- function Accessibility_Level (Expr : Node_Id) return Node_Id
- is (Accessibility_Level (Expr, Level, In_Return_Context));
- -- Renaming of the enclosing function to facilitate recursive calls
-
- function Make_Level_Literal (Level : Uint) return Node_Id;
- -- Construct an integer literal representing an accessibility level
- -- with its type set to Natural.
-
- function Innermost_Master_Scope_Depth (N : Node_Id) return Uint;
- -- Returns the scope depth of the given node's innermost enclosing
- -- scope (effectively the accessibility level of the innermost
- -- enclosing master).
-
- function Function_Call_Or_Allocator_Level (N : Node_Id) return Node_Id;
- -- 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 --
- ----------------------------------
-
- function Innermost_Master_Scope_Depth (N : Node_Id) return Uint is
- Encl_Scop : Entity_Id;
- Ent : Entity_Id;
- Node_Par : Node_Id := Parent (N);
- Master_Lvl_Modifier : Int := 0;
-
- begin
- -- Locate the nearest enclosing node (by traversing Parents)
- -- that Defining_Entity can be applied to, and return the
- -- depth of that entity's nearest enclosing scope.
-
- -- The rules that define what a master are defined in
- -- RM 7.6.1 (3), and include statements and conditions for loops
- -- among other things. These cases are detected properly ???
-
- while Present (Node_Par) loop
- Ent := Defining_Entity_Or_Empty (Node_Par);
-
- if Present (Ent) then
- Encl_Scop := Find_Enclosing_Scope (Ent);
-
- -- Ignore transient scopes made during expansion
-
- if Comes_From_Source (Node_Par) then
- -- Note that in some rare cases the scope depth may not be
- -- set, for example, when we are in the middle of analyzing
- -- a type and the enclosing scope is said type. So, instead,
- -- continue to move up the parent chain since the scope
- -- depth of the type's parent is the same as that of the
- -- type.
-
- if not Scope_Depth_Set (Encl_Scop) then
- pragma Assert (Nkind (Parent (Encl_Scop))
- = N_Full_Type_Declaration);
- else
- return
- Scope_Depth (Encl_Scop) + Master_Lvl_Modifier;
- end if;
- end if;
-
- -- For a return statement within a function, return
- -- the depth of the function itself. This is not just
- -- a small optimization, but matters when analyzing
- -- the expression in an expression function before
- -- the body is created.
-
- elsif Nkind (Node_Par) in N_Extended_Return_Statement
- | N_Simple_Return_Statement
- then
- return Scope_Depth (Enclosing_Subprogram (Node_Par));
-
- -- Statements are counted as masters
-
- elsif Is_Master (Node_Par) then
- Master_Lvl_Modifier := Master_Lvl_Modifier + 1;
-
- end if;
-
- Node_Par := Parent (Node_Par);
- end loop;
-
- -- Should never reach the following return
-
- pragma Assert (False);
-
- return Scope_Depth (Current_Scope) + 1;
- end Innermost_Master_Scope_Depth;
-
- ------------------------
- -- Make_Level_Literal --
- ------------------------
-
- function Make_Level_Literal (Level : Uint) return Node_Id is
- Result : constant Node_Id := Make_Integer_Literal (Loc, Level);
-
- begin
- Set_Etype (Result, Standard_Natural);
- return Result;
- end Make_Level_Literal;
-
- --------------------------------------
- -- Function_Call_Or_Allocator_Level --
- --------------------------------------
-
- function Function_Call_Or_Allocator_Level (N : Node_Id) return Node_Id is
- Par : Node_Id;
- Prev_Par : Node_Id;
- begin
- -- Results of functions are objects, so we either get the
- -- accessibility of the function or, in case of a call which is
- -- indirect, the level of the access-to-subprogram type.
-
- -- This code looks wrong ???
-
- if Nkind (N) = N_Function_Call
- and then Ada_Version < Ada_2005
- then
- if Is_Entity_Name (Name (N)) then
- return Make_Level_Literal
- (Subprogram_Access_Level (Entity (Name (N))));
- else
- return Make_Level_Literal
- (Typ_Access_Level (Etype (Prefix (Name (N)))));
- end if;
-
- -- We ignore coextensions as they cannot be implemented under the
- -- "small-integer" model.
-
- elsif Nkind (N) = N_Allocator
- and then (Is_Static_Coextension (N)
- or else Is_Dynamic_Coextension (N))
- then
- return Make_Level_Literal (Scope_Depth (Standard_Standard));
- end if;
-
- -- Named access types have a designated level
-
- if Is_Named_Access_Type (Etype (N)) then
- 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)));
-
- -- For function calls the level is that of the innermost
- -- master, otherwise (for allocators etc.) we get the level
- -- of the corresponding anonymous access type, which is
- -- calculated through the normal path of execution.
-
- elsif Nkind (N) = N_Function_Call then
- return Make_Level_Literal
- (Innermost_Master_Scope_Depth (Expr));
- 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 accessibility level of the
- -- enclosing subprogram.
-
- if In_Return_Value (N)
- or else In_Return_Context
- then
- return Make_Level_Literal
- (Subprogram_Access_Level (Current_Subprogram));
- 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.
-
- -- Note: The above is only relevant if the result is used "in its
- -- entirety" as RM 3.10.2 (10.2/3) states. However, this is
- -- accounted for in the case statement in the main body of
- -- Accessibility_Level for N_Selected_Component.
-
- Par := Parent (Expr);
- Prev_Par := Empty;
- while Present (Par) loop
- -- Detect an expanded implicit conversion, typically this
- -- occurs on implicitly converted actuals in calls.
-
- -- Does this catch all implicit conversions ???
-
- if Nkind (Par) = N_Type_Conversion
- and then Is_Named_Access_Type (Etype (Par))
- then
- return Make_Level_Literal
- (Typ_Access_Level (Etype (Par)));
- end if;
-
- -- Jump out when we hit an object declaration or the right-hand
- -- side of an assignment, or a construct such as an aggregate
- -- subtype indication which would be the result is not used
- -- "in its entirety."
-
- exit when Nkind (Par) in N_Object_Declaration
- or else (Nkind (Par) = N_Assignment_Statement
- and then Name (Par) /= Prev_Par);
-
- Prev_Par := Par;
- Par := Parent (Par);
- end loop;
-
- -- Assignment statements are handled in a similar way in
- -- accordance to the left-hand part. However, strictly speaking,
- -- this is illegal according to the RM, but this change is needed
- -- to pass an ACATS C-test and is useful in general ???
-
- case Nkind (Par) is
- when N_Object_Declaration =>
- return Make_Level_Literal
- (Scope_Depth
- (Scope (Defining_Identifier (Par))));
-
- when N_Assignment_Statement =>
- -- Return the accessibility level of the left-hand part
-
- return Accessibility_Level
- (Expr => Name (Par),
- Level => Object_Decl_Level,
- In_Return_Context => In_Return_Context);
-
- when others =>
- return Make_Level_Literal
- (Innermost_Master_Scope_Depth (Expr));
- end case;
- end if;
- end Function_Call_Or_Allocator_Level;
-
- -- Local variables
-
- E : Node_Id := Original_Node (Expr);
- Pre : Node_Id;
-
- -- Start of processing for Accessibility_Level
-
- begin
- -- We could be looking at a reference to a formal due to the expansion
- -- of entries and other cases, so obtain the renaming if necessary.
-
- if Present (Param_Entity (Expr)) then
- E := Param_Entity (Expr);
- end if;
-
- -- Extract the entity
-
- if Nkind (E) in N_Has_Entity and then Present (Entity (E)) then
- E := Entity (E);
-
- -- Deal with a possible renaming of a private protected component
-
- if Ekind (E) in E_Constant | E_Variable and then Is_Prival (E) then
- E := Prival_Link (E);
- end if;
- end if;
-
- -- Perform the processing on the expression
-
- case Nkind (E) is
- -- The level of an aggregate is that of the innermost master that
- -- evaluates it as defined in RM 3.10.2 (10/4).
-
- when N_Aggregate =>
- return Make_Level_Literal (Innermost_Master_Scope_Depth (Expr));
-
- -- The accessibility level is that of the access type, except for an
- -- anonymous allocators which have special rules defined in RM 3.10.2
- -- (14/3).
-
- when N_Allocator =>
- return Function_Call_Or_Allocator_Level (E);
-
- -- We could reach this point for two reasons. Either the expression
- -- applies to a special attribute ('Loop_Entry, 'Result, or 'Old), or
- -- we are looking at the access attributes directly ('Access,
- -- 'Address, or 'Unchecked_Access).
-
- when N_Attribute_Reference =>
- Pre := Original_Node (Prefix (E));
-
- -- Regular 'Access attribute presence means we have to look at the
- -- prefix.
-
- if Attribute_Name (E) = Name_Access then
- return Accessibility_Level (Prefix (E));
-
- -- Unchecked or unrestricted attributes have unlimited depth
-
- elsif Attribute_Name (E) in Name_Address
- | Name_Unchecked_Access
- | Name_Unrestricted_Access
- then
- return Make_Level_Literal (Scope_Depth (Standard_Standard));
-
- -- 'Access can be taken further against other special attributes,
- -- so handle these cases explicitly.
-
- elsif Attribute_Name (E)
- in Name_Old | Name_Loop_Entry | Name_Result
- then
- -- Named access types
-
- if Is_Named_Access_Type (Etype (Pre)) then
- return Make_Level_Literal
- (Typ_Access_Level (Etype (Pre)));
-
- -- Anonymous access types
-
- elsif Nkind (Pre) in N_Has_Entity
- and then Ekind (Entity (Pre)) not in Subprogram_Kind
- and then Present (Get_Dynamic_Accessibility (Entity (Pre)))
- and then Level = Dynamic_Level
- then
- return New_Occurrence_Of
- (Get_Dynamic_Accessibility (Entity (Pre)), Loc);
-
- -- Otherwise the level is treated in a similar way as
- -- aggregates according to RM 6.1.1 (35.1/4) which concerns
- -- an implicit constant declaration - in turn defining the
- -- accessibility level to be that of the implicit constant
- -- declaration.
-
- else
- return Make_Level_Literal
- (Innermost_Master_Scope_Depth (Expr));
- end if;
-
- else
- raise Program_Error;
- end if;
-
- -- This is the "base case" for accessibility level calculations which
- -- means we are near the end of our recursive traversal.
-
- when N_Defining_Identifier =>
- -- A dynamic check is performed on the side of the callee when we
- -- are within a return statement, so return a library-level
- -- accessibility level to null out checks on the side of the
- -- caller.
-
- if Is_Explicitly_Aliased (E)
- and then (In_Return_Context
- or else (Level /= Dynamic_Level
- and then In_Return_Value (Expr)))
- then
- return Make_Level_Literal (Scope_Depth (Standard_Standard));
-
- -- Something went wrong and an extra accessibility formal has not
- -- been generated when one should have ???
-
- elsif Is_Formal (E)
- and then not Present (Get_Dynamic_Accessibility (E))
- and then Ekind (Etype (E)) = E_Anonymous_Access_Type
- then
- return Make_Level_Literal (Scope_Depth (Standard_Standard));
-
- -- Stand-alone object of an anonymous access type "SAOAAT"
-
- elsif (Is_Formal (E)
- or else Ekind (E) in E_Variable
- | E_Constant)
- and then Present (Get_Dynamic_Accessibility (E))
- and then (Level = Dynamic_Level
- or else Level = Zero_On_Dynamic_Level)
- then
- if Level = Zero_On_Dynamic_Level then
- return Make_Level_Literal
- (Scope_Depth (Standard_Standard));
- end if;
-
- -- 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 accessibility
- -- parameter associated with the level at which the object
- -- being initialized exists
-
- elsif Ekind (E) = E_Record_Type
- and then Is_Limited_Record (E)
- and then Current_Scope = Init_Proc (E)
- and then Present (Init_Proc_Level_Formal (Current_Scope))
- then
- return New_Occurrence_Of
- (Init_Proc_Level_Formal (Current_Scope), Loc);
-
- -- Current instance of the type is deeper than that of the type
- -- according to RM 3.10.2 (21).
-
- elsif Is_Type (E) then
- -- 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 or object if it came from source
- -- since expansion may have created a dummy renaming under
- -- certain circumstances.
-
- -- Note: We check if the original node of the renaming comes
- -- from source because the node may have been rewritten.
-
- elsif Present (Renamed_Entity_Or_Object (E))
- and then Comes_From_Source
- (Original_Node (Renamed_Entity_Or_Object (E)))
- then
- return Accessibility_Level (Renamed_Entity_Or_Object (E));
-
- -- Named access types get their level from their associated type
-
- elsif Is_Named_Access_Type (Etype (E)) then
- return Make_Level_Literal
- (Typ_Access_Level (Etype (E)));
-
- -- Check if E is an expansion-generated renaming of an iterator
- -- by examining Related_Expression. If so, determine the
- -- accessibility level based on the original expression.
-
- elsif Ekind (E) in E_Constant | E_Variable
- and then Present (Related_Expression (E))
- then
- return Accessibility_Level (Related_Expression (E));
-
- elsif Level = Dynamic_Level
- and then Ekind (E) in E_In_Parameter | E_In_Out_Parameter
- and then Present (Init_Proc_Level_Formal (Scope (E)))
- then
- return New_Occurrence_Of
- (Init_Proc_Level_Formal (Scope (E)), Loc);
-
- -- Normal object - get the level of the enclosing scope
-
- else
- return Make_Level_Literal
- (Scope_Depth (Enclosing_Dynamic_Scope (E)));
- end if;
-
- -- Handle indexed and selected components including the special cases
- -- whereby there is an implicit dereference, a component of a
- -- composite type, or a function call in prefix notation.
-
- -- We don't handle function calls in prefix notation correctly ???
-
- when N_Indexed_Component | N_Selected_Component | N_Slice =>
- Pre := Prefix (E);
-
- -- Fetch the original node when the prefix comes from the result
- -- of expanding a function call since we want to find the level
- -- of the original source call.
-
- if not Comes_From_Source (Pre)
- and then Nkind (Original_Node (Pre)) = N_Function_Call
- then
- Pre := Original_Node (Pre);
- end if;
-
- -- When E is an indexed component or selected component and
- -- the current Expr is a function call, we know that we are
- -- looking at an expanded call in prefix notation.
-
- if Nkind (Expr) = N_Function_Call then
- return Function_Call_Or_Allocator_Level (Expr);
-
- -- If the prefix is a named access type, then we are dealing
- -- with an implicit deferences. In that case the level is that
- -- of the named access type in the prefix.
-
- elsif Is_Named_Access_Type (Etype (Pre)) then
- return Make_Level_Literal
- (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
- -- named access type.
-
- elsif Is_Named_Access_Type (Etype (E)) then
- return Make_Level_Literal
- (Typ_Access_Level (Etype (E)));
-
- -- 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)
-
- -- The alternative accessibility models both treat
- -- discriminants as regular components.
-
- or else (No_Dynamic_Accessibility_Checks_Enabled (E)
- and then Allow_Alt_Model)))
-
- -- Arrays featuring components of anonymous access components
- -- get their corresponding level from their containing type's
- -- declaration.
-
- or else
- (Nkind (E) = N_Indexed_Component
- and then Ekind (Etype (E)) = E_Anonymous_Access_Type
- and then Ekind (Etype (Pre)) in Array_Kind
- 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
- (Typ_Access_Level (Etype (Prefix (E))));
-
- -- The accessibility calculation routine that handles function
- -- calls (Function_Call_Level) assumes, in the case the
- -- result is of an anonymous access type, that the result will be
- -- used "in its entirety" when the call is present within an
- -- assignment or object declaration.
-
- -- To properly handle cases where the result is not used in its
- -- entirety, we test if the prefix of the component in question is
- -- a function call, which tells us that one of its components has
- -- been identified and is being accessed. Therefore we can
- -- conclude that the result is not used "in its entirety"
- -- according to RM 3.10.2 (10.2/3).
-
- elsif Nkind (Pre) = N_Function_Call
- and then not Is_Named_Access_Type (Etype (Pre))
- 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 a library accessibility level to
- -- null out the check on the side of the caller.
-
- if (In_Return_Value (E)
- or else In_Return_Context)
- and then Level /= Dynamic_Level
- then
- return Make_Level_Literal
- (Scope_Depth (Standard_Standard));
- end if;
-
- return Make_Level_Literal
- (Innermost_Master_Scope_Depth (Expr));
-
- -- Otherwise, continue recursing over the expression prefixes
-
- else
- return Accessibility_Level (Prefix (E));
- end if;
-
- -- Qualified expressions
-
- when N_Qualified_Expression =>
- if Is_Named_Access_Type (Etype (E)) then
- return Make_Level_Literal
- (Typ_Access_Level (Etype (E)));
- else
- return Accessibility_Level (Expression (E));
- end if;
-
- -- Handle function calls
-
- when N_Function_Call =>
- return Function_Call_Or_Allocator_Level (E);
-
- -- Explicit dereference accessibility level calculation
-
- when N_Explicit_Dereference =>
- Pre := Original_Node (Prefix (E));
-
- -- The prefix is a named access type so the level is taken from
- -- its type.
-
- if Is_Named_Access_Type (Etype (Pre)) then
- return Make_Level_Literal (Typ_Access_Level (Etype (Pre)));
-
- -- Otherwise, recurse deeper
-
- else
- return Accessibility_Level (Prefix (E));
- end if;
-
- -- Type conversions
-
- when N_Type_Conversion | N_Unchecked_Type_Conversion =>
- -- View conversions are special in that they require use to
- -- inspect the expression of the type conversion.
-
- -- Allocators of anonymous access types are internally generated,
- -- so recurse deeper in that case as well.
-
- if Is_View_Conversion (E)
- or else Ekind (Etype (E)) = E_Anonymous_Access_Type
- then
- return Accessibility_Level (Expression (E));
-
- -- We don't care about the master if we are looking at a named
- -- access type.
-
- elsif Is_Named_Access_Type (Etype (E)) then
- return Make_Level_Literal
- (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
- -- followed in the case of initialization of an object ???
-
- -- Should use Innermost_Master_Scope_Depth ???
-
- else
- return Accessibility_Level (Current_Scope);
- end if;
-
- -- Default to the type accessibility level for the type of the
- -- expression's entity.
-
- when others =>
- return Make_Level_Literal (Typ_Access_Level (Etype (E)));
- end case;
- end Accessibility_Level;
-
- --------------------------------
- -- Static_Accessibility_Level --
- --------------------------------
-
- function Static_Accessibility_Level
- (Expr : Node_Id;
- Level : Static_Accessibility_Level_Kind;
- In_Return_Context : Boolean := False) return Uint
- is
- begin
- return Intval
- (Accessibility_Level (Expr, Level, In_Return_Context));
- end Static_Accessibility_Level;
-
----------------------------------
-- Acquire_Warning_Match_String --
----------------------------------
@@ -1044,7 +311,11 @@ package body Sem_Util is
-- Add_Block_Identifier --
--------------------------
- procedure Add_Block_Identifier (N : Node_Id; Id : out Entity_Id) is
+ procedure Add_Block_Identifier
+ (N : Node_Id;
+ Id : out Entity_Id;
+ Scope : Entity_Id := Current_Scope)
+ is
Loc : constant Source_Ptr := Sloc (N);
begin
pragma Assert (Nkind (N) = N_Block_Statement);
@@ -1057,7 +328,7 @@ package body Sem_Util is
-- Create a new block label and set its attributes
else
- Id := New_Internal_Entity (E_Block, Current_Scope, Loc, 'B');
+ Id := New_Internal_Entity (E_Block, Scope, Loc, 'B');
Set_Etype (Id, Standard_Void_Type);
Set_Parent (Id, N);
@@ -1335,7 +606,7 @@ package body Sem_Util is
end if;
return
- not Present (Etype (Constr)) -- previous error
+ No (Etype (Constr)) -- previous error
or else not Is_Discrete_Type (Etype (Constr))
or else Is_OK_Static_Expression (Constr);
@@ -3195,7 +2466,7 @@ package body Sem_Util is
Actual : Node_Id;
begin
- if Extensions_Allowed then
+ if All_Extensions_Allowed then
Actual := First_Actual (Call);
while Present (Actual) loop
if Nkind (Actual) = N_Aggregate then
@@ -4449,7 +3720,7 @@ package body Sem_Util is
pragma Assert (Present (Ifc_Ancestors (Idx)));
Ifc := Next (Ifc);
end loop;
- pragma Assert (not Present (Ifc));
+ pragma Assert (No (Ifc));
if Present (Parent_Type) then
return Parent_Type & Ifc_Ancestors;
else
@@ -5445,12 +4716,18 @@ package body Sem_Util is
while Present (State_Elmt) loop
State_Id := Node (State_Elmt);
- -- Emit an error when a non-null state lacks any form of
- -- refinement.
+ -- Emit an error when a non-null state lacks refinement,
+ -- but has Part_Of constituents or there is a package
+ -- body (SPARK RM 7.1.4(4)). Constituents in private
+ -- child packages, which are not known at this stage,
+ -- independently require the existence of a package body.
if not Is_Null_State (State_Id)
- and then not Has_Null_Refinement (State_Id)
- and then not Has_Non_Null_Refinement (State_Id)
+ and then No (Refinement_Constituents (State_Id))
+ and then
+ (Present (Part_Of_Constituents (State_Id))
+ or else
+ Present (Body_Id))
then
Error_Msg_N ("state & requires refinement", State_Id);
Error_Msg_N ("\package body should have Refined_State "
@@ -7045,7 +6322,6 @@ package body Sem_Util is
if Present (Asp) then
Set_Aspect_Specifications (To, New_List (New_Copy_Tree (Asp)));
- Set_Has_Aspects (To, True);
end if;
end if;
end Copy_Ghost_Aspect;
@@ -7097,7 +6373,6 @@ package body Sem_Util is
if Present (Asp) then
Set_Aspect_Specifications (To, New_List (New_Copy_Tree (Asp)));
- Set_Has_Aspects (To, True);
end if;
end if;
end Copy_SPARK_Mode_Aspect;
@@ -7422,47 +6697,6 @@ package body Sem_Util is
return Is_Class_Wide_Type (Typ) or else Needs_Finalization (Typ);
end CW_Or_Needs_Finalization;
- -------------------------------
- -- Deepest_Type_Access_Level --
- -------------------------------
-
- 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.
-
- return
- Scope_Depth (Enclosing_Dynamic_Scope
- (Defining_Identifier
- (Associated_Node_For_Itype (Typ))));
-
- -- For generic formal type, return Int'Last (infinite).
- -- See comment preceding Is_Generic_Type call in Type_Access_Level.
-
- elsif Is_Generic_Type (Root_Type (Typ)) then
- return UI_From_Int (Int'Last);
-
- else
- return Type_Access_Level (Typ, Allow_Alt_Model);
- end if;
- end Deepest_Type_Access_Level;
-
---------------------
-- Defining_Entity --
---------------------
@@ -8173,21 +7407,6 @@ package body Sem_Util is
return False;
end Discriminated_Size;
- -----------------------------------
- -- Effective_Extra_Accessibility --
- -----------------------------------
-
- function Effective_Extra_Accessibility (Id : Entity_Id) return Entity_Id is
- begin
- if Present (Renamed_Object (Id))
- and then Is_Entity_Name (Renamed_Object (Id))
- then
- return Effective_Extra_Accessibility (Entity (Renamed_Object (Id)));
- else
- return Extra_Accessibility (Id);
- end if;
- end Effective_Extra_Accessibility;
-
-----------------------------
-- Effective_Reads_Enabled --
-----------------------------
@@ -8269,6 +7488,33 @@ package body Sem_Util is
return Decl;
end Enclosing_Declaration;
+ ----------------------------------------
+ -- Enclosing_Declaration_Or_Statement --
+ ----------------------------------------
+
+ function Enclosing_Declaration_Or_Statement
+ (N : Node_Id) return Node_Id
+ is
+ Par : Node_Id;
+
+ begin
+ Par := N;
+ while Present (Par) loop
+ if Is_Declaration (Par) or else Is_Statement (Par) then
+ return Par;
+
+ -- Prevent the search from going too far
+
+ elsif Is_Body_Or_Package_Declaration (Par) then
+ exit;
+ end if;
+
+ Par := Parent (Par);
+ end loop;
+
+ return N;
+ end Enclosing_Declaration_Or_Statement;
+
----------------------------
-- Enclosing_Generic_Body --
----------------------------
@@ -10740,30 +9986,6 @@ package body Sem_Util is
end if;
end Gather_Components;
- -------------------------------
- -- Get_Dynamic_Accessibility --
- -------------------------------
-
- function Get_Dynamic_Accessibility (E : Entity_Id) return Entity_Id is
- begin
- -- When minimum accessibility is set for E then we utilize it - except
- -- in a few edge cases like the expansion of select statements where
- -- generated subprogram may attempt to unnecessarily use a minimum
- -- accessibility object declared outside of scope.
-
- -- To avoid these situations where expansion may get complex we verify
- -- that the minimum accessibility object is within scope.
-
- if Is_Formal (E)
- and then Present (Minimum_Accessibility (E))
- and then In_Open_Scopes (Scope (Minimum_Accessibility (E)))
- then
- return Minimum_Accessibility (E);
- end if;
-
- return Extra_Accessibility (E);
- end Get_Dynamic_Accessibility;
-
------------------------
-- Get_Actual_Subtype --
------------------------
@@ -11573,7 +10795,7 @@ package body Sem_Util is
-- entry families with no Max_Queue_Length aspect or pragma default to
-- it.
- if not Present (Prag) then
+ if No (Prag) then
return Uint_0;
end if;
@@ -11970,85 +11192,6 @@ package body Sem_Util is
end if;
end Get_Views;
- -----------------------
- -- Has_Access_Values --
- -----------------------
-
- function Has_Access_Values (T : Entity_Id) return Boolean
- is
- Typ : constant Entity_Id := Underlying_Type (T);
-
- begin
- -- Case of a private type which is not completed yet. This can only
- -- happen in the case of a generic formal type appearing directly, or
- -- as a component of the type to which this function is being applied
- -- at the top level. Return False in this case, since we certainly do
- -- not know that the type contains access types.
-
- if No (Typ) then
- return False;
-
- elsif Is_Access_Type (Typ) then
- return True;
-
- elsif Is_Array_Type (Typ) then
- return Has_Access_Values (Component_Type (Typ));
-
- elsif Is_Record_Type (Typ) then
- declare
- Comp : Entity_Id;
-
- begin
- -- Loop to check components
-
- Comp := First_Component_Or_Discriminant (Typ);
- while Present (Comp) loop
-
- -- Check for access component, tag field does not count, even
- -- though it is implemented internally using an access type.
-
- if Has_Access_Values (Etype (Comp))
- and then Chars (Comp) /= Name_uTag
- then
- return True;
- end if;
-
- Next_Component_Or_Discriminant (Comp);
- end loop;
- end;
-
- return False;
-
- else
- return False;
- end if;
- end Has_Access_Values;
-
- ---------------------------------------
- -- Has_Anonymous_Access_Discriminant --
- ---------------------------------------
-
- function Has_Anonymous_Access_Discriminant (Typ : Entity_Id) return Boolean
- is
- Disc : Node_Id;
-
- begin
- if not Has_Discriminants (Typ) then
- return False;
- end if;
-
- Disc := First_Discriminant (Typ);
- while Present (Disc) loop
- if Ekind (Etype (Disc)) = E_Anonymous_Access_Type then
- return True;
- end if;
-
- Next_Discriminant (Disc);
- end loop;
-
- return False;
- end Has_Anonymous_Access_Discriminant;
-
------------------------------
-- Has_Compatible_Alignment --
------------------------------
@@ -13092,7 +12235,7 @@ package body Sem_Util is
Typ := Corresponding_Record_Type (Typ);
end if;
- if not Present (Typ)
+ if No (Typ)
or else not Is_Record_Type (Typ)
or else not Is_Tagged_Type (Typ)
then
@@ -13280,7 +12423,7 @@ package body Sem_Util is
begin
return Nkind (Exp) = N_Aggregate
- and then Present (Find_Aspect (Etype (Exp), Aspect_Aggregate))
+ and then Has_Aspect (Etype (Exp), Aspect_Aggregate)
and then not Is_Record_Aggregate;
end Is_Container_Aggregate;
@@ -13675,15 +12818,12 @@ package body Sem_Util is
Exp : Node_Id;
begin
- -- Loop through entities of record or protected type
+ -- Loop through components and discriminants of record or protected
+ -- type.
- Ent := E;
+ Ent := First_Component_Or_Discriminant (E);
while Present (Ent) loop
- -- We are interested only in components and discriminants
-
- Exp := Empty;
-
case Ekind (Ent) is
when E_Component =>
@@ -13694,6 +12834,8 @@ package body Sem_Util is
if Present (Declaration_Node (Ent)) then
Exp := Expression (Declaration_Node (Ent));
+ else
+ Exp := Empty;
end if;
when E_Discriminant =>
@@ -13706,7 +12848,7 @@ package body Sem_Util is
Exp := Discriminant_Default_Value (Ent);
when others =>
- goto Check_Next_Entity;
+ raise Program_Error;
end case;
-- A component has PI if it has no default expression and the
@@ -13727,8 +12869,7 @@ package body Sem_Util is
exit;
end if;
- <<Check_Next_Entity>>
- Next_Entity (Ent);
+ Next_Component_Or_Discriminant (Ent);
end loop;
end Check_Components;
@@ -13838,7 +12979,7 @@ package body Sem_Util is
-- If OK, check extension components (if any)
if Has_PE and then Is_Record_Type (E) then
- Check_Components (First_Entity (E));
+ Check_Components (E);
end if;
-- Check specifically for 10.2.1(11.4/2) exception: a controlled type
@@ -13878,7 +13019,7 @@ package body Sem_Util is
elsif Is_Record_Type (E) then
Has_PE := True;
- Check_Components (First_Entity (E));
+ Check_Components (E);
-- Protected types must not have entries, and components must meet
-- same set of rules as for record components.
@@ -13888,8 +13029,7 @@ package body Sem_Util is
Has_PE := False;
else
Has_PE := True;
- Check_Components (First_Entity (E));
- Check_Components (First_Private_Entity (E));
+ Check_Components (E);
end if;
-- Type System.Address always has preelaborable initialization
@@ -14349,32 +13489,6 @@ package body Sem_Util is
end if;
end Has_Tagged_Component;
- --------------------------------------------
- -- Has_Unconstrained_Access_Discriminants --
- --------------------------------------------
-
- function Has_Unconstrained_Access_Discriminants
- (Subtyp : Entity_Id) return Boolean
- is
- Discr : Entity_Id;
-
- begin
- if Has_Discriminants (Subtyp)
- and then not Is_Constrained (Subtyp)
- then
- Discr := First_Discriminant (Subtyp);
- while Present (Discr) loop
- if Ekind (Etype (Discr)) = E_Anonymous_Access_Type then
- return True;
- end if;
-
- Next_Discriminant (Discr);
- end loop;
- end if;
-
- return False;
- end Has_Unconstrained_Access_Discriminants;
-
-----------------------------
-- Has_Undefined_Reference --
-----------------------------
@@ -14416,6 +13530,36 @@ package body Sem_Util is
return Has_Undef_Ref;
end Has_Undefined_Reference;
+ ----------------------------------------
+ -- Has_Effectively_Volatile_Component --
+ ----------------------------------------
+
+ function Has_Effectively_Volatile_Component
+ (Typ : Entity_Id) return Boolean
+ is
+ Comp : Entity_Id;
+
+ begin
+ if Has_Volatile_Components (Typ) then
+ return True;
+
+ elsif Is_Array_Type (Typ) then
+ return Is_Effectively_Volatile (Component_Type (Typ));
+
+ elsif Is_Record_Type (Typ) then
+ Comp := First_Component (Typ);
+ while Present (Comp) loop
+ if Is_Effectively_Volatile (Etype (Comp)) then
+ return True;
+ end if;
+
+ Next_Component (Comp);
+ end loop;
+ end if;
+
+ return False;
+ end Has_Effectively_Volatile_Component;
+
----------------------------
-- Has_Volatile_Component --
----------------------------
@@ -14795,8 +13939,15 @@ package body Sem_Util is
loop
if No (P) then
return False;
+
+ -- Prevent the search from going too far
+
+ elsif Is_Body_Or_Package_Declaration (P) then
+ return False;
+
elsif Nkind (P) = N_Pragma and then Pragma_Name (P) = Nam then
return True;
+
else
P := Parent (P);
end if;
@@ -14872,6 +14023,12 @@ package body Sem_Util is
loop
if No (P) then
return False;
+
+ -- Prevent the search from going too far
+
+ elsif Is_Body_Or_Package_Declaration (P) then
+ return False;
+
elsif Nkind (P) = N_Quantified_Expression then
return True;
else
@@ -15943,28 +15100,6 @@ package body Sem_Util is
end if;
end Invalid_Scalar_Value;
- --------------------------------
- -- Is_Anonymous_Access_Actual --
- --------------------------------
-
- function Is_Anonymous_Access_Actual (N : Node_Id) return Boolean is
- Par : Node_Id;
- begin
- if Ekind (Etype (N)) /= E_Anonymous_Access_Type then
- return False;
- end if;
-
- Par := Parent (N);
- while Present (Par)
- and then Nkind (Par) in N_Case_Expression
- | N_If_Expression
- | N_Parameter_Association
- loop
- Par := Parent (Par);
- end loop;
- return Nkind (Par) in N_Subprogram_Call;
- end Is_Anonymous_Access_Actual;
-
------------------------
-- Is_Access_Variable --
------------------------
@@ -17558,9 +16693,11 @@ package body Sem_Util is
if Is_Type (Id) then
-- An arbitrary type is effectively volatile when it is subject to
- -- pragma Atomic or Volatile.
+ -- pragma Atomic or Volatile, unless No_Caching is enabled.
- if Is_Volatile (Id) then
+ if Is_Volatile (Id)
+ and then not No_Caching_Enabled (Id)
+ then
return True;
-- An array type is effectively volatile when it is subject to pragma
@@ -18301,7 +17438,7 @@ package body Sem_Util is
Is_Object (Id)
and then (Is_Independent (Id)
or else
- Is_Independent (Etype (Id)));
+ Is_Independent (Etype (Id)));
end Is_Independent_Object_Entity;
-------------------------------------
@@ -19458,7 +18595,7 @@ package body Sem_Util is
return True;
elsif Present (Variant_Part (Component_List (Record_Def))) then
return False;
- elsif not Present (Component_List (Record_Def)) then
+ elsif No (Component_List (Record_Def)) then
return True;
end if;
@@ -21178,38 +20315,6 @@ package body Sem_Util is
and then Is_Single_Concurrent_Type (Etype (Id));
end Is_Single_Task_Object;
- --------------------------------------
- -- Is_Special_Aliased_Formal_Access --
- --------------------------------------
-
- function Is_Special_Aliased_Formal_Access
- (Exp : Node_Id;
- In_Return_Context : Boolean := False) return Boolean
- is
- Scop : constant Entity_Id := Current_Subprogram;
- begin
- -- Verify the expression is an access reference to 'Access within a
- -- return statement as this is the only time an explicitly aliased
- -- formal has different semantics.
-
- if Nkind (Exp) /= N_Attribute_Reference
- or else Get_Attribute_Id (Attribute_Name (Exp)) /= Attribute_Access
- or else not (In_Return_Value (Exp)
- or else In_Return_Context)
- or else not Needs_Result_Accessibility_Level (Scop)
- then
- return False;
- end if;
-
- -- Check if the prefix of the reference is indeed an explicitly aliased
- -- formal parameter for the function Scop. Additionally, we must check
- -- that Scop returns an anonymous access type, otherwise the special
- -- rules dictating a need for a dynamic check are not in effect.
-
- return Is_Entity_Name (Prefix (Exp))
- and then Is_Explicitly_Aliased (Entity (Prefix (Exp)));
- end Is_Special_Aliased_Formal_Access;
-
-----------------------------
-- Is_Specific_Tagged_Type --
-----------------------------
@@ -21679,18 +20784,16 @@ package body Sem_Util is
-- type has the appropriate user-defined literal aspect.
return (Nkind (N) in N_Numeric_Or_String_Literal
- and then Present (Find_Aspect (Typ, Literal_Aspect_Map (Nkind (N)))))
+ and then Has_Aspect (Typ, Literal_Aspect_Map (Nkind (N))))
or else
(Is_Entity_Name (N)
and then Present (Entity (N))
and then
((Ekind (Entity (N)) = E_Named_Integer
- and then
- Present (Find_Aspect (Typ, Aspect_Integer_Literal)))
+ and then Has_Aspect (Typ, Aspect_Integer_Literal))
or else
(Ekind (Entity (N)) = E_Named_Real
- and then
- Present (Find_Aspect (Typ, Aspect_Real_Literal)))));
+ and then Has_Aspect (Typ, Aspect_Real_Literal))));
end Is_User_Defined_Literal;
--------------------------------------
@@ -22287,25 +21390,6 @@ package body Sem_Util is
procedure Kill_Current_Values (Last_Assignment_Only : Boolean := False) is
S : Entity_Id;
- procedure Kill_Current_Values_For_Entity_Chain (E : Entity_Id);
- -- Clear current value for entity E and all entities chained to E
-
- ------------------------------------------
- -- Kill_Current_Values_For_Entity_Chain --
- ------------------------------------------
-
- procedure Kill_Current_Values_For_Entity_Chain (E : Entity_Id) is
- Ent : Entity_Id;
- begin
- Ent := E;
- while Present (Ent) loop
- Kill_Current_Values (Ent, Last_Assignment_Only);
- Next_Entity (Ent);
- end loop;
- end Kill_Current_Values_For_Entity_Chain;
-
- -- Start of processing for Kill_Current_Values
-
begin
-- Kill all saved checks, a special case of killing saved values
@@ -22321,16 +21405,15 @@ package body Sem_Util is
-- Clear current values of all entities in current scope
- Kill_Current_Values_For_Entity_Chain (First_Entity (S));
-
- -- If scope is a package, also clear current values of all private
- -- entities in the scope.
-
- if Is_Package_Or_Generic_Package (S)
- or else Is_Concurrent_Type (S)
- then
- Kill_Current_Values_For_Entity_Chain (First_Private_Entity (S));
- end if;
+ declare
+ Ent : Entity_Id;
+ begin
+ Ent := First_Entity (S);
+ while Present (Ent) loop
+ Kill_Current_Values (Ent, Last_Assignment_Only);
+ Next_Entity (Ent);
+ end loop;
+ end;
-- If this is a not a subprogram, deal with parents
@@ -23204,141 +22287,6 @@ package body Sem_Util is
end if;
end Needs_One_Actual;
- --------------------------------------
- -- Needs_Result_Accessibility_Level --
- --------------------------------------
-
- function Needs_Result_Accessibility_Level
- (Func_Id : Entity_Id) return Boolean
- is
- Func_Typ : constant Entity_Id := Underlying_Type (Etype (Func_Id));
-
- function Has_Unconstrained_Access_Discriminant_Component
- (Comp_Typ : Entity_Id) return Boolean;
- -- Returns True if any component of the type has an unconstrained access
- -- discriminant.
-
- -----------------------------------------------------
- -- Has_Unconstrained_Access_Discriminant_Component --
- -----------------------------------------------------
-
- function Has_Unconstrained_Access_Discriminant_Component
- (Comp_Typ : Entity_Id) return Boolean
- is
- begin
- if not Is_Limited_Type (Comp_Typ) then
- return False;
-
- -- Only limited types can have access discriminants with
- -- defaults.
-
- elsif Has_Unconstrained_Access_Discriminants (Comp_Typ) then
- return True;
-
- elsif Is_Array_Type (Comp_Typ) then
- return Has_Unconstrained_Access_Discriminant_Component
- (Underlying_Type (Component_Type (Comp_Typ)));
-
- elsif Is_Record_Type (Comp_Typ) then
- declare
- Comp : Entity_Id;
-
- begin
- Comp := First_Component (Comp_Typ);
- while Present (Comp) loop
- if Has_Unconstrained_Access_Discriminant_Component
- (Underlying_Type (Etype (Comp)))
- then
- return True;
- end if;
-
- Next_Component (Comp);
- end loop;
- end;
- end if;
-
- return False;
- end Has_Unconstrained_Access_Discriminant_Component;
-
- Disable_Tagged_Cases : constant Boolean := True;
- -- Flag used to temporarily disable a "True" result for tagged types.
- -- See comments further below for details.
-
- -- Start of processing for Needs_Result_Accessibility_Level
-
- begin
- -- False if completion unavailable, which can happen when we are
- -- analyzing an abstract subprogram or if the subprogram has
- -- delayed freezing.
-
- if No (Func_Typ) then
- return False;
-
- -- False if not a function, also handle enum-lit renames case
-
- elsif Func_Typ = Standard_Void_Type
- or else Is_Scalar_Type (Func_Typ)
- then
- return False;
-
- -- Handle a corner case, a cross-dialect subp renaming. For example,
- -- an Ada 2012 renaming of an Ada 2005 subprogram. This can occur when
- -- an Ada 2005 (or earlier) unit references predefined run-time units.
-
- elsif Present (Alias (Func_Id)) then
-
- -- Unimplemented: a cross-dialect subp renaming which does not set
- -- the Alias attribute (e.g., a rename of a dereference of an access
- -- to subprogram value). ???
-
- return Present (Extra_Accessibility_Of_Result (Alias (Func_Id)));
-
- -- Remaining cases require Ada 2012 mode
-
- elsif Ada_Version < Ada_2012 then
- return False;
-
- -- Handle the situation where a result is an anonymous access type
- -- RM 3.10.2 (10.3/3).
-
- elsif Ekind (Func_Typ) = E_Anonymous_Access_Type then
- return True;
-
- -- In the case of, say, a null tagged record result type, the need for
- -- this extra parameter might not be obvious so this function returns
- -- True for all tagged types for compatibility reasons.
-
- -- A function with, say, a tagged null controlling result type might
- -- be overridden by a primitive of an extension having an access
- -- discriminant and the overrider and overridden must have compatible
- -- calling conventions (including implicitly declared parameters).
-
- -- Similarly, values of one access-to-subprogram type might designate
- -- both a primitive subprogram of a given type and a function which is,
- -- for example, not a primitive subprogram of any type. Again, this
- -- requires calling convention compatibility. It might be possible to
- -- solve these issues by introducing wrappers, but that is not the
- -- approach that was chosen.
-
- -- Note: Despite the reasoning noted above, the extra accessibility
- -- parameter for tagged types is disabled for performance reasons.
-
- elsif Is_Tagged_Type (Func_Typ) then
- return not Disable_Tagged_Cases;
-
- elsif Has_Unconstrained_Access_Discriminants (Func_Typ) then
- return True;
-
- elsif Has_Unconstrained_Access_Discriminant_Component (Func_Typ) then
- return True;
-
- -- False for all other cases
-
- else
- return False;
- end if;
- end Needs_Result_Accessibility_Level;
-
----------------------------
-- Needs_Secondary_Stack --
----------------------------
@@ -23613,7 +22561,7 @@ package body Sem_Util is
-- Unconstrained array type
else
- pragma Assert (Is_Array_Type (Typ) and not Is_Definite_Subtype (Typ));
+ pragma Assert (Is_Array_Type (Typ) and then not Is_Constrained (Typ));
return True;
end if;
end Needs_Secondary_Stack;
@@ -25663,7 +24611,6 @@ package body Sem_Util is
------------------------
function No_Caching_Enabled (Id : Entity_Id) return Boolean is
- pragma Assert (Ekind (Id) = E_Variable);
Prag : constant Node_Id := Get_Pragma (Id, Pragma_No_Caching);
Arg1 : Node_Id;
@@ -27893,7 +26840,10 @@ package body Sem_Util is
P := Parent (N);
while Present (P) loop
- if Nkind (P) = N_If_Statement
+ if Is_Body (P) then
+ return True;
+
+ elsif Nkind (P) = N_If_Statement
or else Nkind (P) = N_Case_Statement
or else (Nkind (P) in N_Short_Circuit
and then Desc = Right_Opnd (P))
@@ -29149,19 +28099,6 @@ package body Sem_Util is
and then Has_Loop_Entry_Attributes (Entity (Identifier (Stmt)));
end Subject_To_Loop_Entry_Attributes;
- -----------------------------
- -- Subprogram_Access_Level --
- -----------------------------
-
- function Subprogram_Access_Level (Subp : Entity_Id) return Uint is
- begin
- if Present (Alias (Subp)) then
- return Subprogram_Access_Level (Alias (Subp));
- else
- return Scope_Depth (Enclosing_Dynamic_Scope (Subp));
- end if;
- end Subprogram_Access_Level;
-
---------------------
-- Subprogram_Name --
---------------------
@@ -29621,179 +28558,6 @@ package body Sem_Util is
Discard := Traverse (Node);
end Traverse_More_Proc;
- -----------------------
- -- Type_Access_Level --
- -----------------------
-
- 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
- -- 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
- -- associated with components the level is the same as that of the
- -- enclosing composite type. However, special treatment is needed for
- -- the cases of access parameters, return objects of an anonymous access
- -- type, and, in Ada 95, access discriminants of limited types.
-
- 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 specified,
- -- 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 defining entity is a subprogram then we know the
- -- anonymous access type Typ has been generated to either
- -- describe an anonymous access type formal or an anonymous
- -- access result type.
-
- -- Since we are only interested in the formal case, avoid
- -- the anonymous access result type.
-
- if Is_Subprogram (Def_Ent)
- and then not (Ekind (Def_Ent) = E_Function
- and then Etype (Def_Ent) = Typ)
- then
- -- When the type comes from an anonymous access
- -- parameter, the level is that of the subprogram
- -- declaration.
-
- 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.
-
- 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
- -- the result subtype of the enclosing function. The test here is
- -- little complicated, because we have to account for extended
- -- return statements that have been rewritten as blocks, in which
- -- case we have to find and the Is_Return_Object attribute of the
- -- itype's associated object. It would be nice to find a way to
- -- simplify this test, but it doesn't seem worthwhile to add a new
- -- flag just for purposes of this test. ???
-
- elsif Ekind (Scope (Btyp)) = E_Return_Statement
- or else
- (Is_Itype (Btyp)
- and then Nkind (Associated_Node_For_Itype (Btyp)) =
- N_Object_Declaration
- and then Is_Return_Object
- (Defining_Identifier
- (Associated_Node_For_Itype (Btyp))))
- then
- declare
- Scop : Entity_Id;
-
- begin
- Scop := Scope (Scope (Btyp));
- while Present (Scop) loop
- exit when Ekind (Scop) = E_Function;
- Scop := Scope (Scop);
- end loop;
-
- -- 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), Allow_Alt_Model);
- end;
- end if;
- end if;
-
- Btyp := Root_Type (Btyp);
-
- -- The accessibility level of anonymous access types associated with
- -- discriminants is that of the current instance of the type, and
- -- that's deeper than the type itself (AARM 3.10.2 (12.3.21)).
-
- -- AI-402: access discriminants have accessibility based on the
- -- object rather than the type in Ada 2005, so the above paragraph
- -- doesn't apply.
-
- -- ??? Needs completion with rules from AI-416
-
- if Ada_Version <= Ada_95
- and then Ekind (Typ) = E_Anonymous_Access_Type
- and then Present (Associated_Node_For_Itype (Typ))
- and then Nkind (Associated_Node_For_Itype (Typ)) =
- N_Discriminant_Specification
- then
- return Scope_Depth (Enclosing_Dynamic_Scope (Btyp)) + 1;
- end if;
- end if;
-
- -- Return library level for a generic formal type. This is done because
- -- RM(10.3.2) says that "The statically deeper relationship does not
- -- apply to ... a descendant of a generic formal type". Rather than
- -- checking at each point where a static accessibility check is
- -- performed to see if we are dealing with a formal type, this rule is
- -- implemented by having Type_Access_Level and Deepest_Type_Access_Level
- -- return extreme values for a formal type; Deepest_Type_Access_Level
- -- returns Int'Last. By calling the appropriate function from among the
- -- two, we ensure that the static accessibility check will pass if we
- -- happen to run into a formal type. More specifically, we should call
- -- Deepest_Type_Access_Level instead of Type_Access_Level whenever the
- -- call occurs as part of a static accessibility check and the error
- -- case is the case where the type's level is too shallow (as opposed
- -- to too deep).
-
- if Is_Generic_Type (Root_Type (Btyp)) then
- return Scope_Depth (Standard_Standard);
- end if;
-
- return Scope_Depth (Enclosing_Dynamic_Scope (Btyp));
- end Type_Access_Level;
-
------------------------------------
-- Type_Without_Stream_Operation --
------------------------------------
@@ -31575,7 +30339,7 @@ package body Sem_Util is
Next (Range_Or_Expr);
end loop;
- pragma Assert (not Present (Range_Or_Expr));
+ pragma Assert (No (Range_Or_Expr));
Check_Consistency (Result);
return Result;
end;
@@ -31825,7 +30589,7 @@ package body Sem_Util is
and then Is_Non_Empty_List (Alternatives (Par))
and then Trailer /= First (Alternatives (Par))
then
- pragma Assert (not Present (Right_Opnd (Par)));
+ pragma Assert (No (Right_Opnd (Par)));
pragma Assert
(Is_List_Member (Trailer)
and then List_Containing (Trailer)
@@ -32538,7 +31302,7 @@ package body Sem_Util is
(Typ : Entity_Id) return Boolean
is
begin
- return Present (Find_Aspect (Typ, Aspect_Designated_Storage_Model));
+ return Has_Aspect (Typ, Aspect_Designated_Storage_Model);
end Has_Designated_Storage_Model_Aspect;
-----------------------------------
@@ -32548,7 +31312,7 @@ package body Sem_Util is
function Has_Storage_Model_Type_Aspect (Typ : Entity_Id) return Boolean
is
begin
- return Present (Find_Aspect (Typ, Aspect_Storage_Model_Type));
+ return Has_Aspect (Typ, Aspect_Storage_Model_Type);
end Has_Storage_Model_Type_Aspect;
--------------------------
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index c23d358..b647e68 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -44,40 +44,6 @@ package Sem_Util is
-- including the cases where there can't be any because e.g. the type is
-- not tagged.
- type Accessibility_Level_Kind is
- (Dynamic_Level,
- Object_Decl_Level,
- Zero_On_Dynamic_Level);
- -- Accessibility_Level_Kind is an enumerated type which captures the
- -- different modes in which an accessibility level could be obtained for
- -- a given expression.
-
- -- When in the context of the function Accessibility_Level,
- -- Accessibility_Level_Kind signals what type of accessibility level to
- -- obtain. For example, when Level is Dynamic_Level, a defining identifier
- -- associated with a SAOOAAT may be returned or an N_Integer_Literal node.
- -- When the level is Object_Decl_Level, an N_Integer_Literal node is
- -- returned containing the level of the declaration of the object if
- -- relevant (be it a SAOOAAT or otherwise). Finally, Zero_On_Dynamic_Level
- -- returns library level for all cases where the accessibility level is
- -- dynamic (used to bypass static accessibility checks in dynamic cases).
-
- function Accessibility_Level
- (Expr : Node_Id;
- Level : Accessibility_Level_Kind;
- 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 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
@@ -88,11 +54,6 @@ package Sem_Util is
-- Add A to the list of access types to process when expanding the
-- freeze node of E.
- procedure Add_Block_Identifier (N : Node_Id; Id : out Entity_Id);
- -- Given a block statement N, generate an internal E_Block label and make
- -- it the identifier of the block. Id denotes the generated entity. If the
- -- block already has an identifier, Id returns the entity of its label.
-
procedure Add_Global_Declaration (N : Node_Id);
-- These procedures adds a declaration N at the library level, to be
-- elaborated before any other code in the unit. It is used for example
@@ -678,6 +639,15 @@ package Sem_Util is
function Current_Scope return Entity_Id;
-- Get entity representing current scope
+ procedure Add_Block_Identifier
+ (N : Node_Id;
+ Id : out Entity_Id;
+ Scope : Entity_Id := Current_Scope);
+ -- Given a block statement N, generate an internal E_Block label and make
+ -- it the identifier of the block. Scope denotes the scope in which the
+ -- generated entity Id is created and defaults to the current scope. If the
+ -- block already has an identifier, Id returns the entity of its label.
+
function Current_Scope_No_Loops return Entity_Id;
-- Return the current scope ignoring internally generated loops
@@ -692,22 +662,6 @@ package Sem_Util is
-- as Needs_Finalization except with pragma Restrictions (No_Finalization),
-- in which case we know that class-wide objects do not need finalization.
- 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
- -- accessibility level of the object may take on values in a range. The low
- -- bound of that range is returned by Type_Access_Level; this function
- -- yields the high bound of that range. Also differs from Type_Access_Level
- -- 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
@@ -782,10 +736,6 @@ package Sem_Util is
-- private components of protected objects, but is generally useful when
-- restriction No_Implicit_Heap_Allocation is active.
- function Effective_Extra_Accessibility (Id : Entity_Id) return Entity_Id;
- -- Same as Einfo.Extra_Accessibility except thtat object renames
- -- are looked through.
-
function Effective_Reads_Enabled (Id : Entity_Id) return Boolean;
-- Id should be the entity of a state abstraction, an object, or a type.
-- Returns True iff Id is subject to external property Effective_Reads.
@@ -805,6 +755,10 @@ package Sem_Util is
-- Returns the declaration node enclosing N (including possibly N itself),
-- if any, or Empty otherwise.
+ function Enclosing_Declaration_Or_Statement (N : Node_Id) return Node_Id;
+ -- Return the nearest enclosing declaration or statement that houses
+ -- arbitrary node N.
+
function Enclosing_Generic_Body (N : Node_Id) return Node_Id;
-- Returns the Node_Id associated with the innermost enclosing generic
-- body, if any. If none, then returns Empty.
@@ -1138,10 +1092,6 @@ package Sem_Util is
-- discriminants. Otherwise all components of the parent must be included
-- in the subtype for semantic analysis.
- function Get_Dynamic_Accessibility (E : Entity_Id) return Entity_Id;
- -- Obtain the accessibility level for a given entity formal taking into
- -- account both extra and minimum accessibility.
-
function Get_Actual_Subtype (N : Node_Id) return Entity_Id;
-- Given a node for an expression, obtain the actual subtype of the
-- expression. In the case of a parameter where the formal is an
@@ -1385,18 +1335,6 @@ package Sem_Util is
-- don't look inside packed array types. If Recurse is False, just
-- go down one level (so it's no longer the "fullest" view).
- function Has_Access_Values (T : Entity_Id) return Boolean;
- -- Returns true if the underlying type of T is an access type, or has a
- -- component (at any recursive level) that is an access type. This is a
- -- conservative predicate, if it is not known whether or not T contains
- -- access values (happens for generic formals in some cases), then False is
- -- returned. Note that tagged types return False. Even though the tag is
- -- implemented as an access type internally, this function tests only for
- -- access types known to the programmer. See also Has_Tagged_Component.
-
- function Has_Anonymous_Access_Discriminant (Typ : Entity_Id) return Boolean;
- -- Returns True if Typ has one or more anonymous access discriminants
-
type Alignment_Result is (Known_Compatible, Unknown, Known_Incompatible);
-- Result of Has_Compatible_Alignment test, description found below. Note
-- that the values are arranged in increasing order of problematicness.
@@ -1536,20 +1474,6 @@ package Sem_Util is
-- Return True if the loop has no side effect and can therefore be
-- marked for removal. Return False if N is not a N_Loop_Statement.
- subtype Static_Accessibility_Level_Kind
- is Accessibility_Level_Kind range Object_Decl_Level
- .. Zero_On_Dynamic_Level;
- -- Restrict the reange of Accessibility_Level_Kind to be non-dynamic for
- -- use in the static version of Accessibility_Level below.
-
- function Static_Accessibility_Level
- (Expr : Node_Id;
- Level : Static_Accessibility_Level_Kind;
- In_Return_Context : Boolean := False) return Uint;
- -- Overloaded version of Accessibility_Level which returns a universal
- -- integer for use in compile-time checking. Note: Level is restricted to
- -- be non-dynamic.
-
function Is_Newly_Constructed
(Exp : Node_Id; Context_Requires_NC : Boolean) return Boolean;
-- Indicates whether a given expression is "newly constructed" (RM 4.4).
@@ -1636,15 +1560,15 @@ package Sem_Util is
-- a tagged type or has a subcomponent that is tagged. Returns False for a
-- noncomposite type, or if no tagged subcomponents are present.
- function Has_Unconstrained_Access_Discriminants
- (Subtyp : Entity_Id) return Boolean;
- -- Returns True if the given subtype is unconstrained and has one or more
- -- access discriminants.
-
function Has_Undefined_Reference (Expr : Node_Id) return Boolean;
-- Given arbitrary expression Expr, determine whether it contains at
-- least one name whose entity is Any_Id.
+ function Has_Effectively_Volatile_Component
+ (Typ : Entity_Id) return Boolean;
+ -- Given arbitrary type Typ, determine whether it contains at least one
+ -- effectively volatile component.
+
function Has_Volatile_Component (Typ : Entity_Id) return Boolean;
-- Given arbitrary type Typ, determine whether it contains at least one
-- volatile component.
@@ -1814,10 +1738,6 @@ package Sem_Util is
-- pragma Initialize_Scalars or by the binder. Return an expression created
-- at source location Loc, which denotes the invalid value.
- function Is_Anonymous_Access_Actual (N : Node_Id) return Boolean;
- -- Determine if N is used as an actual for a call whose corresponding
- -- formal is of an anonymous access type.
-
function Is_Access_Subprogram_Wrapper (E : Entity_Id) return Boolean;
-- True if E is the constructed wrapper for an access_to_subprogram
-- type with Pre/Postconditions.
@@ -1873,12 +1793,13 @@ package Sem_Util is
function Is_Attribute_Update (N : Node_Id) return Boolean;
-- Determine whether node N denotes attribute 'Update
- function Is_Body_Or_Package_Declaration (N : Node_Id) return Boolean;
+ function Is_Body_Or_Package_Declaration (N : Node_Id) return Boolean
+ with Inline;
-- Determine whether node N denotes a body or a package declaration
function Is_Bounded_String (T : Entity_Id) return Boolean;
-- True if T is a bounded string type. Used to make sure "=" composes
- -- properly for bounded string types.
+ -- properly for bounded string types (see 4.5.2(32.1/1)).
function Is_By_Protected_Procedure (Id : Entity_Id) return Boolean;
-- Determine whether entity Id denotes a procedure with synchronization
@@ -2391,21 +2312,6 @@ package Sem_Util is
-- Determine whether arbitrary entity Id denotes the anonymous object
-- created for a single task type.
- function Is_Special_Aliased_Formal_Access
- (Exp : Node_Id;
- In_Return_Context : Boolean := False) return Boolean;
- -- Determines whether a dynamic check must be generated for explicitly
- -- aliased formals within a function Scop for the expression Exp.
-
- -- In_Return_Context forces Is_Special_Aliased_Formal_Access to assume
- -- that Exp is within a return value which is useful for checking
- -- expressions within discriminant associations of return objects.
-
- -- More specially, Is_Special_Aliased_Formal_Access checks that Exp is a
- -- 'Access attribute reference within a return statement where the ultimate
- -- prefix is an aliased formal of Scop and that Scop returns an anonymous
- -- access type. See RM 3.10.2 for more details.
-
function Is_Specific_Tagged_Type (Typ : Entity_Id) return Boolean;
-- Determine whether an arbitrary [private] type is specifically tagged
@@ -2683,12 +2589,6 @@ package Sem_Util is
-- syntactic ambiguity that results from an indexing of a function call
-- that returns an array, so that Obj.F (X, Y) may mean F (Ob) (X, Y).
- function Needs_Result_Accessibility_Level
- (Func_Id : Entity_Id) return Boolean;
- -- Ada 2012 (AI05-0234): Return True if the function needs an implicit
- -- parameter to identify the accessibility level of the function result
- -- "determined by the point of call".
-
function Needs_Secondary_Stack (Id : Entity_Id) return Boolean;
-- Return true if functions whose result type is Id must return on the
-- secondary stack, i.e. allocate the return object on this stack.
@@ -2863,9 +2763,9 @@ package Sem_Util is
-- inline this procedural form, but not the functional form above.
function No_Caching_Enabled (Id : Entity_Id) return Boolean;
- -- Given the entity of a variable, determine whether Id is subject to
- -- volatility property No_Caching and if it is, the related expression
- -- evaluates to True.
+ -- Given any entity Id, determine whether Id is subject to volatility
+ -- property No_Caching and if it is, the related expression evaluates
+ -- to True.
function No_Heap_Finalization (Typ : Entity_Id) return Boolean;
-- Determine whether type Typ is subject to pragma No_Heap_Finalization
@@ -3331,9 +3231,6 @@ package Sem_Util is
-- Determine whether node N is a loop statement subject to at least one
-- 'Loop_Entry attribute.
- function Subprogram_Access_Level (Subp : Entity_Id) return Uint;
- -- Return the accessibility level of the view denoted by Subp
-
function Support_Atomic_Primitives (Typ : Entity_Id) return Boolean;
-- Return True if Typ supports the GCC built-in atomic operations (i.e. if
-- Typ is properly sized and aligned).
@@ -3364,19 +3261,6 @@ 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;
- 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;
diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb
index 1d73f21..cb2a381 100644
--- a/gcc/ada/sem_warn.adb
+++ b/gcc/ada/sem_warn.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Accessibility; use Accessibility;
with Atree; use Atree;
with Debug; use Debug;
with Einfo; use Einfo;
@@ -51,6 +52,7 @@ with Stand; use Stand;
with Stringt; use Stringt;
with Tbuild; use Tbuild;
with Uintp; use Uintp;
+with Warnsw; use Warnsw;
package body Sem_Warn is
@@ -928,7 +930,7 @@ package body Sem_Warn is
if not Is_Generic_Type (T) then
null;
- elsif (Nkind (Par)) = N_Private_Extension_Declaration then
+ elsif Nkind (Par) = N_Private_Extension_Declaration then
-- We only indicate the first such variable in the generic.
@@ -936,7 +938,7 @@ package body Sem_Warn is
Set_Uninitialized_Variable (Par, Ent);
end if;
- elsif (Nkind (Par)) = N_Formal_Type_Declaration
+ elsif Nkind (Par) = N_Formal_Type_Declaration
and then Nkind (Formal_Type_Definition (Par)) =
N_Formal_Private_Type_Definition
then
@@ -1151,8 +1153,6 @@ package body Sem_Warn is
E1 := First_Entity (E);
while Present (E1) loop
- E1T := Etype (E1);
-
-- We are only interested in source entities. We also don't issue
-- warnings within instances, since the proper place for such
-- warnings is on the template when it is compiled, and we don't
@@ -1161,6 +1161,8 @@ package body Sem_Warn is
if Comes_From_Source (E1)
and then Instantiation_Location (Sloc (E1)) = No_Location
then
+ E1T := Etype (E1);
+
-- We are interested in variables and out/in-out parameters, but
-- we exclude protected types, too complicated to worry about.
@@ -1221,7 +1223,7 @@ package body Sem_Warn is
elsif Warn_On_Constant
and then Ekind (E1) = E_Variable
and then Has_Initial_Value (E1)
- and then Never_Set_In_Source_Check_Spec (E1)
+ and then Never_Set_In_Source (E1)
and then not Generic_Package_Spec_Entity (E1)
then
-- A special case, if this variable is volatile and not
@@ -1248,24 +1250,15 @@ package body Sem_Warn is
-- Here we give the warning if referenced and no pragma
-- Unreferenced or Unmodified is present.
- else
- -- Variable case
-
- if Ekind (E1) = E_Variable then
- if Referenced_Check_Spec (E1)
- and then not Has_Pragma_Unreferenced_Check_Spec (E1)
- and then not Has_Pragma_Unmodified_Check_Spec (E1)
- then
- if not Warnings_Off_E1
- and then not Has_Junk_Name (E1)
- then
- Error_Msg_N -- CODEFIX
- ("?k?& is not modified, "
- & "could be declared constant!",
- E1);
- end if;
- end if;
- end if;
+ elsif Referenced (E1)
+ and then not Has_Unreferenced (E1)
+ and then not Has_Unmodified (E1)
+ and then not Warnings_Off_E1
+ and then not Has_Junk_Name (E1)
+ then
+ Error_Msg_N -- CODEFIX
+ ("?k?& is not modified, could be declared constant!",
+ E1);
end if;
-- Other cases of a variable or parameter never set in source
@@ -1469,31 +1462,6 @@ package body Sem_Warn is
and then not Known_To_Have_Preelab_Init (Etype (E1))
then
- -- For other than access type, go back to original node to
- -- deal with case where original unset reference has been
- -- rewritten during expansion.
-
- -- In some cases, the original node may be a type
- -- conversion, a qualification or an attribute reference and
- -- in this case we want the object entity inside. Same for
- -- an expression with actions.
-
- UR := Original_Node (UR);
- loop
- if Nkind (UR) in N_Expression_With_Actions
- | N_Qualified_Expression
- | N_Type_Conversion
- then
- UR := Expression (UR);
-
- elsif Nkind (UR) = N_Attribute_Reference then
- UR := Prefix (UR);
-
- else
- exit;
- end if;
- end loop;
-
-- Don't issue warning if appearing inside Initial_Condition
-- pragma or aspect, since that expression is not evaluated
-- at the point where it occurs in the source.
@@ -1648,20 +1616,6 @@ package body Sem_Warn is
not Is_Package_Or_Generic_Package
(Cunit_Entity (Current_Sem_Unit))))
- -- Exclude instantiations, since there is no reason why every
- -- entity in an instantiation should be referenced.
-
- and then Instantiation_Location (Sloc (E1)) = No_Location
-
- -- Exclude formal parameters from bodies if the corresponding
- -- spec entity has been referenced in the case where there is
- -- a separate spec.
-
- and then not (Is_Formal (E1)
- and then Ekind (Scope (E1)) = E_Subprogram_Body
- and then Present (Spec_Entity (E1))
- and then Referenced (Spec_Entity (E1)))
-
-- Consider private type referenced if full view is referenced.
-- If there is not full view, this is a generic type on which
-- warnings are also useful.
@@ -1768,7 +1722,6 @@ package body Sem_Warn is
elsif Is_Generic_Subprogram (E1)
and then not Is_Instantiated (E1)
and then not Publicly_Referenceable (E1)
- and then Instantiation_Depth (Sloc (E1)) = 0
and then Warn_On_Redundant_Constructs
then
if not Warnings_Off_E1 and then not Has_Junk_Name (E1) then
@@ -2001,8 +1954,7 @@ package body Sem_Warn is
P := Parent (Nod);
if Nkind (P) = N_Pragma
- and then Pragma_Name (P) =
- Name_Test_Case
+ and then Pragma_Name (P) = Name_Test_Case
and then Nod = Test_Case_Arg (P, Name_Ensures)
then
return True;
@@ -2756,7 +2708,7 @@ package body Sem_Warn is
begin
-- Immediate return if no semantics or warning flag not set
- if not Opt.Check_Withs or else Operating_Mode = Check_Syntax then
+ if not Check_Withs or else Operating_Mode = Check_Syntax then
return;
end if;
@@ -2998,21 +2950,6 @@ package body Sem_Warn is
begin
return Traverse (N) = Abandon;
-
- -- If any exception occurs, then something has gone wrong, and this is
- -- only a minor aesthetic issue anyway, so just say we did not find what
- -- we are looking for, rather than blow up.
-
- exception
- when others =>
- -- With debug flag K we will get an exception unless an error has
- -- already occurred (useful for debugging).
-
- if Debug_Flag_K then
- Check_Error_Detected;
- end if;
-
- return False;
end Operand_Has_Warnings_Suppressed;
-----------------------------------------
@@ -3021,20 +2958,20 @@ package body Sem_Warn is
procedure Output_Non_Modified_In_Out_Warnings is
- function No_Warn_On_In_Out (E : Entity_Id) return Boolean;
+ function Warn_On_In_Out (E : Entity_Id) return Boolean;
-- Given a formal parameter entity E, determines if there is a reason to
-- suppress IN OUT warnings (not modified, could be IN) for formals of
-- the subprogram. We suppress these warnings if Warnings Off is set, or
-- if we have seen the address of the subprogram being taken, or if the
-- subprogram is used as a generic actual (in the latter cases the
-- context may force use of IN OUT, even if the parameter is not
- -- modified for this particular case.
+ -- modified for this particular case).
- -----------------------
- -- No_Warn_On_In_Out --
- -----------------------
+ --------------------
+ -- Warn_On_In_Out --
+ --------------------
- function No_Warn_On_In_Out (E : Entity_Id) return Boolean is
+ function Warn_On_In_Out (E : Entity_Id) return Boolean is
S : constant Entity_Id := Scope (E);
SE : constant Entity_Id := Spec_Entity (E);
@@ -3045,7 +2982,7 @@ package body Sem_Warn is
if Address_Taken (S)
or else (Present (SE) and then Address_Taken (Scope (SE)))
then
- return True;
+ return False;
-- Do not warn if used as a generic actual, since the generic may be
-- what is forcing the use of an "unnecessary" IN OUT.
@@ -3053,19 +2990,19 @@ package body Sem_Warn is
elsif Used_As_Generic_Actual (S)
or else (Present (SE) and then Used_As_Generic_Actual (Scope (SE)))
then
- return True;
+ return False;
- -- Else test warnings off
+ -- Else test warnings off on the subprogram
- elsif Warnings_Off_Check_Spec (S) then
- return True;
+ elsif Warnings_Off (S) then
+ return False;
-- All tests for suppressing warning failed
else
- return False;
+ return True;
end if;
- end No_Warn_On_In_Out;
+ end Warn_On_In_Out;
-- Start of processing for Output_Non_Modified_In_Out_Warnings
@@ -3078,16 +3015,9 @@ package body Sem_Warn is
begin
-- Suppress warning in specific cases (see details in comments for
- -- No_Warn_On_In_Out), or if there is a pragma Unmodified.
-
- if Has_Pragma_Unmodified_Check_Spec (E1)
- or else No_Warn_On_In_Out (E1)
- then
- null;
-
- -- Here we generate the warning
+ -- No_Warn_On_In_Out).
- else
+ if Warn_On_In_Out (E1) then
-- If -gnatwk is set then output message that it could be IN
if not Is_Trivial_Subprogram (Scope (E1)) then
@@ -3170,7 +3100,7 @@ package body Sem_Warn is
("?j?with of obsolescent procedure& declared#", N, E);
else
Error_Msg_NE
- ("??with of obsolescent function& declared#", N, E);
+ ("?j?with of obsolescent function& declared#", N, E);
end if;
-- If we do not have a with clause, then ignore any reference to an
@@ -3360,6 +3290,44 @@ package body Sem_Warn is
Left : constant Node_Id := Left_Opnd (Op);
Right : constant Node_Id := Right_Opnd (Op);
+ function Comes_From_Simple_Condition_In_Source
+ (Op : Node_Id) return Boolean;
+ -- Return True if Op comes from a simple condition present in the source
+
+ -------------------------------------------
+ -- Comes_From_Simple_Condition_In_Source --
+ -------------------------------------------
+
+ function Comes_From_Simple_Condition_In_Source
+ (Op : Node_Id) return Boolean
+ is
+ Orig_Op : constant Node_Id := Original_Node (Op);
+
+ begin
+ if not Comes_From_Source (Orig_Op) then
+ return False;
+ end if;
+
+ -- We do not want to give warnings on a membership test with a mark
+ -- for a subtype that is predicated, see also Exp_Ch4.Expand_N_In.
+
+ if Nkind (Orig_Op) = N_In then
+ declare
+ Orig_Rop : constant Node_Id :=
+ Original_Node (Right_Opnd (Orig_Op));
+ begin
+ if Is_Entity_Name (Orig_Rop)
+ and then Is_Type (Entity (Orig_Rop))
+ and then Present (Predicate_Function (Entity (Orig_Rop)))
+ then
+ return False;
+ end if;
+ end;
+ end if;
+
+ return True;
+ end Comes_From_Simple_Condition_In_Source;
+
True_Result : Boolean;
False_Result : Boolean;
@@ -3368,7 +3336,7 @@ package body Sem_Warn is
-- scalar operands are valid.
if Constant_Condition_Warnings
- and then Comes_From_Source (Original_Node (Op))
+ and then Comes_From_Simple_Condition_In_Source (Op)
and then Is_Scalar_Type (Etype (Left))
and then Is_Scalar_Type (Etype (Right))
@@ -3436,11 +3404,10 @@ package body Sem_Warn is
-- determined, and Test_Result is set True/False accordingly. Otherwise
-- False is returned, and Test_Result is unchanged.
- procedure Track (N : Node_Id; Loc : Node_Id);
+ procedure Track (N : Node_Id);
-- Adds continuation warning(s) pointing to reason (assignment or test)
-- for the operand of the conditional having a known value (or at least
- -- enough is known about the value to issue the warning). N is the node
- -- which is judged to have a known value. Loc is the warning location.
+ -- enough is known about the value to issue the warning).
---------------------
-- Is_Known_Branch --
@@ -3474,36 +3441,45 @@ package body Sem_Warn is
-- Track --
-----------
- procedure Track (N : Node_Id; Loc : Node_Id) is
- Nod : constant Node_Id := Original_Node (N);
+ procedure Track (N : Node_Id) is
- begin
- if Nkind (Nod) in N_Op_Compare then
- Track (Left_Opnd (Nod), Loc);
- Track (Right_Opnd (Nod), Loc);
+ procedure Rec (Sub_N : Node_Id);
+ -- Recursive helper to do the work of Track, so we can refer to N's
+ -- Sloc in error messages. Sub_N is initially N, and a proper subnode
+ -- when recursively walking comparison operations.
- elsif Is_Entity_Name (Nod) and then Is_Object (Entity (Nod)) then
- declare
- CV : constant Node_Id := Current_Value (Entity (Nod));
+ procedure Rec (Sub_N : Node_Id) is
+ Orig : constant Node_Id := Original_Node (Sub_N);
+ begin
+ if Nkind (Orig) in N_Op_Compare then
+ Rec (Left_Opnd (Orig));
+ Rec (Right_Opnd (Orig));
- begin
- if Present (CV) then
- Error_Msg_Sloc := Sloc (CV);
+ elsif Is_Entity_Name (Orig) and then Is_Object (Entity (Orig)) then
+ declare
+ CV : constant Node_Id := Current_Value (Entity (Orig));
+ begin
+ if Present (CV) then
+ Error_Msg_Sloc := Sloc (CV);
- if Nkind (CV) not in N_Subexpr then
- Error_Msg_N ("\\??(see test #)", Loc);
+ if Nkind (CV) not in N_Subexpr then
+ Error_Msg_N ("\\??(see test #)", N);
- elsif Nkind (Parent (CV)) =
- N_Case_Statement_Alternative
- then
- Error_Msg_N ("\\??(see case alternative #)", Loc);
+ elsif Nkind (Parent (CV)) =
+ N_Case_Statement_Alternative
+ then
+ Error_Msg_N ("\\??(see case alternative #)", N);
- else
- Error_Msg_N ("\\??(see assignment #)", Loc);
+ else
+ Error_Msg_N ("\\??(see assignment #)", N);
+ end if;
end if;
- end if;
- end;
- end if;
+ end;
+ end if;
+ end Rec;
+
+ begin
+ Rec (N);
end Track;
-- Local variables
@@ -3521,11 +3497,8 @@ package body Sem_Warn is
and then Is_Known_Branch
then
declare
- Atrue : Boolean;
-
+ Atrue : Boolean := Test_Result;
begin
- Atrue := Test_Result;
-
if Present (Parent (C)) and then Nkind (Parent (C)) = N_Op_Not then
Atrue := not Atrue;
end if;
@@ -3607,7 +3580,6 @@ package body Sem_Warn is
declare
True_Branch : Boolean := Test_Result;
Cond : Node_Id := C;
-
begin
if Present (Parent (C))
and then Nkind (Parent (C)) = N_Op_Not
@@ -3616,37 +3588,27 @@ package body Sem_Warn is
Cond := Parent (C);
end if;
- -- Condition always True
-
- if True_Branch then
- if Is_Entity_Name (Original_Node (C))
- and then Nkind (Cond) /= N_Op_Not
- then
- Error_Msg_NE
- ("object & is always True at this point?c?",
- Cond, Original_Node (C));
- Track (Original_Node (C), Cond);
+ -- Suppress warning if this is True/False of a derived boolean
+ -- type with Nonzero_Is_True, which gets rewritten as Boolean
+ -- True/False.
- else
- Error_Msg_N ("condition is always True?c?", Cond);
- Track (Cond, Cond);
- end if;
+ if Is_Entity_Name (Original_Node (C))
+ and then Ekind (Entity (Original_Node (C)))
+ = E_Enumeration_Literal
+ and then Nonzero_Is_True (Etype (Original_Node (C)))
+ then
+ null;
- -- Condition always False
+ -- Give warning for nontrivial always True/False case
else
- if Is_Entity_Name (Original_Node (C))
- and then Nkind (Cond) /= N_Op_Not
- then
- Error_Msg_NE
- ("object & is always False at this point?c?",
- Cond, Original_Node (C));
- Track (Original_Node (C), Cond);
-
+ if True_Branch then
+ Error_Msg_N ("condition is always True?c?", Cond);
else
Error_Msg_N ("condition is always False?c?", Cond);
- Track (Cond, Cond);
end if;
+
+ Track (Cond);
end if;
end;
end if;
@@ -4282,7 +4244,7 @@ package body Sem_Warn is
if Ekind (Form) = E_Out_Parameter
and then Never_Set_In_Source_Check_Spec (Form)
and then Is_Scalar_Type (Etype (Form))
- and then not Present (Unset_Reference (Form))
+ and then No (Unset_Reference (Form))
then
-- Here all conditions are met, record possible unset reference
diff --git a/gcc/ada/sfn_scan.adb b/gcc/ada/sfn_scan.adb
index b428ed7..8ee9a09 100644
--- a/gcc/ada/sfn_scan.adb
+++ b/gcc/ada/sfn_scan.adb
@@ -583,6 +583,7 @@ package body SFN_Scan is
else
Skip_Loop : loop
+ Skip_WS;
exit Main_Scan_Loop when At_EOF;
exit Skip_Loop when S (P) = ';';
diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads
index 53880c5..104ee66 100644
--- a/gcc/ada/sinfo.ads
+++ b/gcc/ada/sinfo.ads
@@ -440,7 +440,7 @@ package Sinfo is
-- documents the restriction.
-- Note that most of these restrictions apply only to trees generated when
- -- code is being generated, since they involved expander actions that
+ -- code is being generated, since they involve expander actions that
-- destroy the tree.
----------------
@@ -528,7 +528,7 @@ package Sinfo is
-- function.
--
-- If the mode of a Ghost region is Ignore, any newly created nodes as well
- -- as source entities are marked as ignored Ghost. In additon, the marking
+ -- as source entities are marked as ignored Ghost. In addition, the marking
-- process signals all enclosing scopes that an ignored Ghost node resides
-- within. The compilation unit where the node resides is also added to an
-- auxiliary table for post processing.
@@ -629,7 +629,7 @@ package Sinfo is
-- specified by means of an aspect or a pragma.
-- The following entities may be subject to a SPARK mode. Entities marked
- -- with * may possess two differente SPARK modes.
+ -- with * may possess two different SPARK modes.
-- E_Entry
-- E_Entry_Family
@@ -715,9 +715,9 @@ package Sinfo is
-- This flag is set if the node comes directly from an explicit construct
-- in the source. It is normally on for any nodes built by the scanner or
-- parser from the source program, with the exception that in a few cases
- -- the parser adds nodes to normalize the representation (in particular
+ -- the parser adds nodes to normalize the representation (in particular,
-- a null statement is added to a package body if there is no begin/end
- -- initialization section.
+ -- initialization section).
--
-- Most nodes inserted by the analyzer or expander are not considered
-- as coming from source, so the flag is off for such nodes. In a few
@@ -842,10 +842,6 @@ package Sinfo is
-- known at compile time, this field points to an N_Range node with those
-- bounds. Otherwise Empty.
- -- Alloc_For_BIP_Return
- -- Present in N_Allocator nodes. True if the allocator is one of those
- -- generated for a build-in-place return statement.
-
-- All_Others
-- Present in an N_Others_Choice node. This flag is set for an others
-- exception where all exceptions are to be caught, even those that are
@@ -953,6 +949,11 @@ package Sinfo is
-- Present in N_Simple_Return_Statement nodes. True if this node was
-- constructed as part of the N_Extended_Return_Statement expansion.
+ -- Comes_From_Iterator
+ -- Present in N_Object_Renaming_Declaration nodes. True if this node was
+ -- was constructed as part of the expansion of an iterator
+ -- specification.
+
-- Compile_Time_Known_Aggregate
-- Present in N_Aggregate nodes. Set for aggregates which can be fully
-- evaluated at compile time without raising constraint error. Such
@@ -1339,6 +1340,10 @@ package Sinfo is
-- cannot figure it out. If both flags Forwards_OK and Backwards_OK are
-- set, it means that the front end can assure no overlap of operands.
+ -- For_Special_Return_Object
+ -- Present in N_Allocator nodes. True if the allocator is generated for
+ -- the initialization of a special return object.
+
-- From_Aspect_Specification
-- Processing of aspect specifications typically results in insertion in
-- the tree of corresponding pragma or attribute definition clause nodes.
@@ -1549,7 +1554,7 @@ package Sinfo is
-- Is_Analyzed_Pragma
-- Present in N_Pragma nodes. Set for delayed pragmas that require a two
- -- step analysis. The initial step is peformed by routine Analyze_Pragma
+ -- step analysis. The initial step is performed by routine Analyze_Pragma
-- and verifies the overall legality of the pragma. The second step takes
-- place in the various Analyze_xxx_In_Decl_Part routines which perform
-- full analysis. The flag prevents the reanalysis of a delayed pragma.
@@ -1641,8 +1646,9 @@ package Sinfo is
-- variable reference marker
--
-- Set when the node appears within a context which allows the generation
- -- of run-time ABE checks. This flag detemines whether the ABE Processing
- -- phase generates conditional ABE checks and guaranteed ABE failures.
+ -- of run-time ABE checks. This flag determines whether the ABE
+ -- Processing phase generates conditional ABE checks and guaranteed ABE
+ -- failures.
-- Is_Elaboration_Code
-- Present in assignment statements. Set for an assignment which updates
@@ -4771,7 +4777,7 @@ package Sinfo is
-- Subpool_Handle_Name (set to Empty if not present)
-- Storage_Pool
-- Procedure_To_Call
- -- Alloc_For_BIP_Return
+ -- For_Special_Return_Object
-- Null_Exclusion_Present
-- No_Initialization
-- Is_Static_Coextension
@@ -5570,7 +5576,7 @@ package Sinfo is
-- The term "return statement" is defined in 6.5 to mean either a
-- SIMPLE_RETURN_STATEMENT or an EXTENDED_RETURN_STATEMENT. We avoid
- -- the use of this term, since it used to mean someting else in earlier
+ -- the use of this term, since it used to mean something else in earlier
-- versions of Ada.
-- N_Simple_Return_Statement
@@ -7815,7 +7821,7 @@ package Sinfo is
-- ABE mechanism, regardless of whether expansion took place.
-- * The call marker captures the target of the related call along
- -- with other attributes which are either unavailabe or expensive
+ -- with other attributes which are either unavailable or expensive
-- to recompute once analysis, resolution, and expansion are over.
-- * The call marker aids the ABE Processing phase by signaling the
diff --git a/gcc/ada/sinput.adb b/gcc/ada/sinput.adb
index 8e80213..c96049b 100644
--- a/gcc/ada/sinput.adb
+++ b/gcc/ada/sinput.adb
@@ -620,7 +620,6 @@ package body Sinput is
-------------------------
function Instantiation_Depth (S : Source_Ptr) return Nat is
- Sind : Source_File_Index;
Sval : Source_Ptr;
Depth : Nat;
@@ -629,8 +628,7 @@ package body Sinput is
Depth := 0;
loop
- Sind := Get_Source_File_Index (Sval);
- Sval := Instantiation (Sind);
+ Sval := Instantiation_Location (Sval);
exit when Sval = No_Location;
Depth := Depth + 1;
end loop;
diff --git a/gcc/ada/sinput.ads b/gcc/ada/sinput.ads
index af2fec7..febb2ef 100644
--- a/gcc/ada/sinput.ads
+++ b/gcc/ada/sinput.ads
@@ -409,8 +409,6 @@ package Sinput is
Current_Source_File : Source_File_Index := No_Source_File;
-- Source_File table index of source file currently being scanned.
- -- Initialized so that some tools (such as gprbuild) can be built with
- -- -gnatVa and pragma Initialize_Scalars without problems.
Current_Source_Unit : Unit_Number_Type := No_Unit;
-- Unit number of source file currently being scanned. Initialized to
diff --git a/gcc/ada/switch-b.adb b/gcc/ada/switch-b.adb
index c40cb97..7a732ae 100644
--- a/gcc/ada/switch-b.adb
+++ b/gcc/ada/switch-b.adb
@@ -168,6 +168,15 @@ package body Switch.B is
if Enable_CUDA_Expansion and Enable_CUDA_Device_Expansion
then
Bad_Switch (Switch_Chars);
+ elsif C = 'c' then
+ -- specify device library name
+ if Ptr >= Max or else Switch_Chars (Ptr + 1) /= '=' then
+ Bad_Switch (Switch_Chars);
+ else
+ CUDA_Device_Library_Name :=
+ new String'(Switch_Chars (Ptr + 2 .. Max));
+ Ptr := Max;
+ end if;
end if;
Underscore := False;
diff --git a/gcc/ada/switch-c.adb b/gcc/ada/switch-c.adb
index feac8bd..db01d53 100644
--- a/gcc/ada/switch-c.adb
+++ b/gcc/ada/switch-c.adb
@@ -28,7 +28,6 @@
-- circularities, especially for back ends using Adabkend.
with Debug; use Debug;
-with Errout; use Errout;
with Lib; use Lib;
with Osint; use Osint;
with Opt; use Opt;
@@ -1327,7 +1326,7 @@ package body Switch.C is
Ptr := Ptr + 1;
C := Switch_Chars (Ptr);
- if Set_Dot_Warning_Switch (C) then
+ if Set_Warning_Switch ('.', C) then
Store_Compilation_Switch ("-gnatw." & C);
else
Bad_Switch ("-gnatw." & Switch_Chars (Ptr .. Max));
@@ -1339,7 +1338,7 @@ package body Switch.C is
Ptr := Ptr + 1;
C := Switch_Chars (Ptr);
- if Set_Underscore_Warning_Switch (C) then
+ if Set_Warning_Switch ('_', C) then
Store_Compilation_Switch ("-gnatw_" & C);
else
Bad_Switch ("-gnatw_" & Switch_Chars (Ptr .. Max));
@@ -1348,7 +1347,7 @@ package body Switch.C is
-- Normal case
else
- if Set_Warning_Switch (C) then
+ if Set_Warning_Switch (Plain, C) then
Store_Compilation_Switch ("-gnatw" & C);
else
Bad_Switch ("-gnatw" & Switch_Chars (Ptr .. Max));
@@ -1391,12 +1390,21 @@ package body Switch.C is
Ptr := Ptr + 1;
Xref_Active := False;
- -- -gnatX (language extensions)
+ -- -gnatX (core language extensions)
when 'X' =>
Ptr := Ptr + 1;
- Ada_Version := Ada_With_Extensions;
- Ada_Version_Explicit := Ada_With_Extensions;
+
+ if Ptr <= Max and then Switch_Chars (Ptr) = '0' then
+ -- -gnatX0 (all language extensions)
+
+ Ptr := Ptr + 1;
+ Ada_Version := Ada_With_All_Extensions;
+ else
+ Ada_Version := Ada_With_Core_Extensions;
+ end if;
+
+ Ada_Version_Explicit := Ada_Version;
Ada_Version_Pragma := Empty;
-- -gnaty (style checks)
diff --git a/gcc/ada/treepr.adb b/gcc/ada/treepr.adb
index a9f4088..a0f45c4 100644
--- a/gcc/ada/treepr.adb
+++ b/gcc/ada/treepr.adb
@@ -269,8 +269,9 @@ package body Treepr is
function Image (F : Node_Or_Entity_Field) return String is
begin
case F is
- when F_Alloc_For_BIP_Return =>
- return "Alloc_For_BIP_Return";
+ -- We special case the following; otherwise the compiler will use
+ -- the usual Mixed_Case convention.
+
when F_Assignment_OK =>
return "Assignment_OK";
when F_Backwards_OK =>
diff --git a/gcc/ada/usage.adb b/gcc/ada/usage.adb
index 7d11ae5..642cfda 100644
--- a/gcc/ada/usage.adb
+++ b/gcc/ada/usage.adb
@@ -567,6 +567,10 @@ begin
"record types");
Write_Line (" .Q* turn off warnings for questionable layout of " &
"record types");
+ Write_Line (" _q turn on warnings for ignored " &
+ "equality operators");
+ Write_Line (" _Q* turn off warnings for ignored " &
+ "equality operators");
Write_Line (" r+ turn on warnings for redundant construct");
Write_Line (" R* turn off warnings for redundant construct");
Write_Line (" .r+ turn on warnings for object renaming function");
diff --git a/gcc/ada/warnsw.adb b/gcc/ada/warnsw.adb
index 4a7dcc3..6fabafb 100644
--- a/gcc/ada/warnsw.adb
+++ b/gcc/ada/warnsw.adb
@@ -23,517 +23,153 @@
-- --
------------------------------------------------------------------------------
-with Err_Vars; use Err_Vars;
with Opt; use Opt;
with Output; use Output;
-package body Warnsw is
-
- -- Local Subprograms
-
- procedure All_Warnings (Setting : Boolean);
- -- Sets all warnings off if Setting = False, and on if Setting = True
+with System.Case_Util; use System.Case_Util;
- procedure WA_Warnings;
- -- Turn on all warnings set by -gnatwa (also used by -gnatw.g)
+package body Warnsw is
- ------------------
- -- All_Warnings --
- ------------------
-
- procedure All_Warnings (Setting : Boolean) is
- begin
- Address_Clause_Overlay_Warnings := Setting;
- Check_Unreferenced := Setting;
- Check_Unreferenced_Formals := Setting;
- Check_Withs := Setting;
- Constant_Condition_Warnings := Setting;
- Elab_Warnings := Setting;
- Implementation_Unit_Warnings := Setting;
- Ineffective_Inline_Warnings := Setting;
- List_Body_Required_Info := Setting;
- List_Inherited_Aspects := Setting;
- Warn_On_Ada_2005_Compatibility := Setting;
- Warn_On_Ada_2012_Compatibility := Setting;
- Warn_On_All_Unread_Out_Parameters := Setting;
- Warn_On_Anonymous_Allocators := Setting;
- Warn_On_Assertion_Failure := Setting;
- Warn_On_Assumed_Low_Bound := Setting;
- Warn_On_Atomic_Synchronization := Setting;
- Warn_On_Bad_Fixed_Value := Setting;
- Warn_On_Biased_Representation := Setting;
- Warn_On_Constant := Setting;
- Warn_On_Deleted_Code := Setting;
- Warn_On_Dereference := Setting;
- Warn_On_Export_Import := Setting;
- Warn_On_Hiding := Setting;
- Warn_On_Late_Primitives := Setting;
- Warn_On_Modified_Unread := Setting;
- Warn_On_No_Value_Assigned := Setting;
- Warn_On_Non_Local_Exception := Setting;
- Warn_On_Object_Renames_Function := Setting;
- Warn_On_Obsolescent_Feature := Setting;
- Warn_On_Overlap := Setting;
- Warn_On_Overridden_Size := Setting;
- Warn_On_Parameter_Order := Setting;
- Warn_On_Pedantic_Checks := Setting;
- Warn_On_Questionable_Layout := Setting;
- Warn_On_Questionable_Missing_Parens := Setting;
- Warn_On_Record_Holes := Setting;
- Warn_On_Component_Order := Setting;
- Warn_On_Redundant_Constructs := Setting;
- Warn_On_Reverse_Bit_Order := Setting;
- Warn_On_Size_Alignment := Setting;
- Warn_On_Standard_Redefinition := Setting;
- Warn_On_Suspicious_Contract := Setting;
- Warn_On_Suspicious_Modulus_Value := Setting;
- Warn_On_Unchecked_Conversion := Setting;
- Warn_On_Unknown_Compile_Time_Warning := Setting;
- Warn_On_Unordered_Enumeration_Type := Setting;
- Warn_On_Unrecognized_Pragma := Setting;
- Warn_On_Unrepped_Components := Setting;
- Warn_On_Warnings_Off := Setting;
- end All_Warnings;
+ subtype Lowercase is Character range 'a' .. 'z';
+ -- Warning-enable switches are lowercase letters
+
+ Switch_To_Flag_Mapping : constant array (Warning_Family, Lowercase) of
+ -- Mapping from the letter after "-gnatw", "-gnatw." or "-gnatw_" to
+ -- the corresponding flag for the warning it enables. Special_Case means
+ -- Set_Warning_Switch must do something special, as opposed to simply
+ -- setting the corresponding flag. No_Such_Warning means the letter
+ -- is not a defined warning switch, which is an error.
+ X.Opt_Warnings_Enum :=
+ (Plain =>
+ ('a' | 'e' | 'n' | 's' | 'u' | 'y' => Special_Case,
+
+ 'b' => X.Warn_On_Bad_Fixed_Value,
+ 'c' => X.Constant_Condition_Warnings,
+ 'd' => X.Warn_On_Dereference,
+ 'f' => X.Check_Unreferenced_Formals,
+ 'g' => X.Warn_On_Unrecognized_Pragma,
+ 'h' => X.Warn_On_Hiding,
+ 'i' => X.Implementation_Unit_Warnings,
+ 'j' => X.Warn_On_Obsolescent_Feature,
+ 'k' => X.Warn_On_Constant,
+ 'l' => X.Elab_Warnings,
+ 'm' => X.Warn_On_Modified_Unread,
+ 'o' => X.Address_Clause_Overlay_Warnings,
+ 'p' => X.Ineffective_Inline_Warnings,
+ 'q' => X.Warn_On_Questionable_Missing_Parens,
+ 'r' => X.Warn_On_Redundant_Constructs,
+ 't' => X.Warn_On_Deleted_Code,
+ 'v' => X.Warn_On_No_Value_Assigned,
+ 'w' => X.Warn_On_Assumed_Low_Bound,
+ 'x' => X.Warn_On_Export_Import,
+ 'z' => X.Warn_On_Unchecked_Conversion),
+
+ '.' =>
+ ('e' | 'g' | 'x' => Special_Case,
+
+ 'a' => X.Warn_On_Assertion_Failure,
+ 'b' => X.Warn_On_Biased_Representation,
+ 'c' => X.Warn_On_Unrepped_Components,
+ 'd' => X.Warning_Doc_Switch,
+ 'f' => X.Warn_On_Elab_Access,
+ 'h' => X.Warn_On_Record_Holes,
+ 'i' => X.Warn_On_Overlap,
+ 'j' => X.Warn_On_Late_Primitives,
+ 'k' => X.Warn_On_Standard_Redefinition,
+ 'l' => X.List_Inherited_Aspects,
+ 'm' => X.Warn_On_Suspicious_Modulus_Value,
+ 'n' => X.Warn_On_Atomic_Synchronization,
+ 'o' => X.Warn_On_All_Unread_Out_Parameters,
+ 'p' => X.Warn_On_Parameter_Order,
+ 'q' => X.Warn_On_Questionable_Layout,
+ 'r' => X.Warn_On_Object_Renames_Function,
+ 's' => X.Warn_On_Overridden_Size,
+ 't' => X.Warn_On_Suspicious_Contract,
+ 'u' => X.Warn_On_Unordered_Enumeration_Type,
+ 'v' => X.Warn_On_Reverse_Bit_Order,
+ 'w' => X.Warn_On_Warnings_Off,
+ 'y' => X.List_Body_Required_Info,
+ 'z' => X.Warn_On_Size_Alignment),
+
+ '_' =>
+ ('b' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' |
+ 'n' | 'o' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' =>
+ No_Such_Warning,
+
+ 'a' => X.Warn_On_Anonymous_Allocators,
+ 'c' => X.Warn_On_Unknown_Compile_Time_Warning,
+ 'p' => X.Warn_On_Pedantic_Checks,
+ 'q' => X.Warn_On_Ignored_Equality,
+ 'r' => X.Warn_On_Component_Order));
+
+ All_Warnings : constant Warnings_State := -- Warnings set by -gnatw.e
+ (X.Elab_Info_Messages |
+ X.Warning_Doc_Switch |
+ X.Warn_On_Ada_2022_Compatibility |
+ X.Warn_On_Elab_Access |
+ X.No_Warn_On_Non_Local_Exception => False,
+ others => True);
+ -- Warning_Doc_Switch is not really a warning to be enabled, but controls
+ -- the form of warnings printed. No_Warn_On_Non_Local_Exception is handled
+ -- specially (see Warn_On_Non_Local_Exception). The others are not part of
+ -- -gnatw.e for historical reasons.
+
+ WA_Warnings : constant Warnings_State := -- Warnings set by -gnatwa
+ (X.Check_Unreferenced | -- -gnatwf/-gnatwu
+ X.Check_Unreferenced_Formals | -- -gnatwf/-gnatwu
+ X.Check_Withs | -- -gnatwu
+ X.Constant_Condition_Warnings | -- -gnatwc
+ X.Implementation_Unit_Warnings | -- -gnatwi
+ X.Ineffective_Inline_Warnings | -- -gnatwp
+ X.Warn_On_Ada_2005_Compatibility | -- -gnatwy
+ X.Warn_On_Ada_2012_Compatibility | -- -gnatwy
+ X.Warn_On_Anonymous_Allocators | -- -gnatw_a
+ X.Warn_On_Assertion_Failure | -- -gnatw.a
+ X.Warn_On_Assumed_Low_Bound | -- -gnatww
+ X.Warn_On_Bad_Fixed_Value | -- -gnatwb
+ X.Warn_On_Biased_Representation | -- -gnatw.b
+ X.Warn_On_Constant | -- -gnatwk
+ X.Warn_On_Export_Import | -- -gnatwx
+ X.Warn_On_Late_Primitives | -- -gnatw.j
+ X.Warn_On_Modified_Unread | -- -gnatwm
+ X.Warn_On_No_Value_Assigned | -- -gnatwv
+ X.Warn_On_Non_Local_Exception | -- -gnatw.x
+ X.Warn_On_Object_Renames_Function | -- -gnatw.r
+ X.Warn_On_Obsolescent_Feature | -- -gnatwj
+ X.Warn_On_Overlap | -- -gnatw.i
+ X.Warn_On_Parameter_Order | -- -gnatw.p
+ X.Warn_On_Questionable_Missing_Parens | -- -gnatwq
+ X.Warn_On_Redundant_Constructs | -- -gnatwr
+ X.Warn_On_Reverse_Bit_Order | -- -gnatw.v
+ X.Warn_On_Size_Alignment | -- -gnatw.z
+ X.Warn_On_Suspicious_Contract | -- -gnatw.t
+ X.Warn_On_Suspicious_Modulus_Value | -- -gnatw.m
+ X.Warn_On_Unchecked_Conversion | -- -gnatwz
+ X.Warn_On_Unrecognized_Pragma | -- -gnatwg
+ X.Warn_On_Unrepped_Components => -- -gnatw.c
+ True,
+
+ others => False);
----------------------
-- Restore_Warnings --
----------------------
- procedure Restore_Warnings (W : Warning_Record) is
+ procedure Restore_Warnings (W : Warnings_State) is
begin
- Address_Clause_Overlay_Warnings :=
- W.Address_Clause_Overlay_Warnings;
- Check_Unreferenced :=
- W.Check_Unreferenced;
- Check_Unreferenced_Formals :=
- W.Check_Unreferenced_Formals;
- Check_Withs :=
- W.Check_Withs;
- Constant_Condition_Warnings :=
- W.Constant_Condition_Warnings;
- Elab_Warnings :=
- W.Elab_Warnings;
- Elab_Info_Messages :=
- W.Elab_Info_Messages;
- Implementation_Unit_Warnings :=
- W.Implementation_Unit_Warnings;
- Ineffective_Inline_Warnings :=
- W.Ineffective_Inline_Warnings;
- List_Body_Required_Info :=
- W.List_Body_Required_Info;
- List_Inherited_Aspects :=
- W.List_Inherited_Aspects;
- No_Warn_On_Non_Local_Exception :=
- W.No_Warn_On_Non_Local_Exception;
- Warning_Doc_Switch :=
- W.Warning_Doc_Switch;
- Warn_On_Ada_2005_Compatibility :=
- W.Warn_On_Ada_2005_Compatibility;
- Warn_On_Ada_2012_Compatibility :=
- W.Warn_On_Ada_2012_Compatibility;
- Warn_On_All_Unread_Out_Parameters :=
- W.Warn_On_All_Unread_Out_Parameters;
- Warn_On_Anonymous_Allocators :=
- W.Warn_On_Anonymous_Allocators;
- Warn_On_Assertion_Failure :=
- W.Warn_On_Assertion_Failure;
- Warn_On_Assumed_Low_Bound :=
- W.Warn_On_Assumed_Low_Bound;
- Warn_On_Atomic_Synchronization :=
- W.Warn_On_Atomic_Synchronization;
- Warn_On_Bad_Fixed_Value :=
- W.Warn_On_Bad_Fixed_Value;
- Warn_On_Biased_Representation :=
- W.Warn_On_Biased_Representation;
- Warn_On_Constant :=
- W.Warn_On_Constant;
- Warn_On_Deleted_Code :=
- W.Warn_On_Deleted_Code;
- Warn_On_Dereference :=
- W.Warn_On_Dereference;
- Warn_On_Export_Import :=
- W.Warn_On_Export_Import;
- Warn_On_Hiding :=
- W.Warn_On_Hiding;
- Warn_On_Late_Primitives :=
- W.Warn_On_Late_Primitives;
- Warn_On_Modified_Unread :=
- W.Warn_On_Modified_Unread;
- Warn_On_No_Value_Assigned :=
- W.Warn_On_No_Value_Assigned;
- Warn_On_Non_Local_Exception :=
- W.Warn_On_Non_Local_Exception;
- Warn_On_Object_Renames_Function :=
- W.Warn_On_Object_Renames_Function;
- Warn_On_Obsolescent_Feature :=
- W.Warn_On_Obsolescent_Feature;
- Warn_On_Overlap :=
- W.Warn_On_Overlap;
- Warn_On_Overridden_Size :=
- W.Warn_On_Overridden_Size;
- Warn_On_Parameter_Order :=
- W.Warn_On_Parameter_Order;
- Warn_On_Pedantic_Checks :=
- W.Warn_On_Pedantic_Checks;
- Warn_On_Questionable_Layout :=
- W.Warn_On_Questionable_Layout;
- Warn_On_Questionable_Missing_Parens :=
- W.Warn_On_Questionable_Missing_Parens;
- Warn_On_Record_Holes :=
- W.Warn_On_Record_Holes;
- Warn_On_Component_Order :=
- W.Warn_On_Component_Order;
- Warn_On_Redundant_Constructs :=
- W.Warn_On_Redundant_Constructs;
- Warn_On_Reverse_Bit_Order :=
- W.Warn_On_Reverse_Bit_Order;
- Warn_On_Size_Alignment :=
- W.Warn_On_Size_Alignment;
- Warn_On_Standard_Redefinition :=
- W.Warn_On_Standard_Redefinition;
- Warn_On_Suspicious_Contract :=
- W.Warn_On_Suspicious_Contract;
- Warn_On_Unchecked_Conversion :=
- W.Warn_On_Unchecked_Conversion;
- Warn_On_Unknown_Compile_Time_Warning :=
- W.Warn_On_Unknown_Compile_Time_Warning;
- Warn_On_Unordered_Enumeration_Type :=
- W.Warn_On_Unordered_Enumeration_Type;
- Warn_On_Unrecognized_Pragma :=
- W.Warn_On_Unrecognized_Pragma;
- Warn_On_Unrepped_Components :=
- W.Warn_On_Unrepped_Components;
- Warn_On_Warnings_Off :=
- W.Warn_On_Warnings_Off;
+ Warning_Flags := W;
end Restore_Warnings;
-------------------
-- Save_Warnings --
-------------------
- function Save_Warnings return Warning_Record is
- W : Warning_Record;
-
+ function Save_Warnings return Warnings_State is
begin
- W.Address_Clause_Overlay_Warnings :=
- Address_Clause_Overlay_Warnings;
- W.Check_Unreferenced :=
- Check_Unreferenced;
- W.Check_Unreferenced_Formals :=
- Check_Unreferenced_Formals;
- W.Check_Withs :=
- Check_Withs;
- W.Constant_Condition_Warnings :=
- Constant_Condition_Warnings;
- W.Elab_Info_Messages :=
- Elab_Info_Messages;
- W.Elab_Warnings :=
- Elab_Warnings;
- W.Implementation_Unit_Warnings :=
- Implementation_Unit_Warnings;
- W.Ineffective_Inline_Warnings :=
- Ineffective_Inline_Warnings;
- W.List_Body_Required_Info :=
- List_Body_Required_Info;
- W.List_Inherited_Aspects :=
- List_Inherited_Aspects;
- W.No_Warn_On_Non_Local_Exception :=
- No_Warn_On_Non_Local_Exception;
- W.Warning_Doc_Switch :=
- Warning_Doc_Switch;
- W.Warn_On_Ada_2005_Compatibility :=
- Warn_On_Ada_2005_Compatibility;
- W.Warn_On_Ada_2012_Compatibility :=
- Warn_On_Ada_2012_Compatibility;
- W.Warn_On_All_Unread_Out_Parameters :=
- Warn_On_All_Unread_Out_Parameters;
- W.Warn_On_Anonymous_Allocators :=
- Warn_On_Anonymous_Allocators;
- W.Warn_On_Assertion_Failure :=
- Warn_On_Assertion_Failure;
- W.Warn_On_Assumed_Low_Bound :=
- Warn_On_Assumed_Low_Bound;
- W.Warn_On_Atomic_Synchronization :=
- Warn_On_Atomic_Synchronization;
- W.Warn_On_Bad_Fixed_Value :=
- Warn_On_Bad_Fixed_Value;
- W.Warn_On_Biased_Representation :=
- Warn_On_Biased_Representation;
- W.Warn_On_Constant :=
- Warn_On_Constant;
- W.Warn_On_Deleted_Code :=
- Warn_On_Deleted_Code;
- W.Warn_On_Dereference :=
- Warn_On_Dereference;
- W.Warn_On_Export_Import :=
- Warn_On_Export_Import;
- W.Warn_On_Hiding :=
- Warn_On_Hiding;
- W.Warn_On_Late_Primitives :=
- Warn_On_Late_Primitives;
- W.Warn_On_Modified_Unread :=
- Warn_On_Modified_Unread;
- W.Warn_On_No_Value_Assigned :=
- Warn_On_No_Value_Assigned;
- W.Warn_On_Non_Local_Exception :=
- Warn_On_Non_Local_Exception;
- W.Warn_On_Object_Renames_Function :=
- Warn_On_Object_Renames_Function;
- W.Warn_On_Obsolescent_Feature :=
- Warn_On_Obsolescent_Feature;
- W.Warn_On_Overlap :=
- Warn_On_Overlap;
- W.Warn_On_Overridden_Size :=
- Warn_On_Overridden_Size;
- W.Warn_On_Parameter_Order :=
- Warn_On_Parameter_Order;
- W.Warn_On_Pedantic_Checks :=
- Warn_On_Pedantic_Checks;
- W.Warn_On_Questionable_Layout :=
- Warn_On_Questionable_Layout;
- W.Warn_On_Questionable_Missing_Parens :=
- Warn_On_Questionable_Missing_Parens;
- W.Warn_On_Record_Holes :=
- Warn_On_Record_Holes;
- W.Warn_On_Component_Order :=
- Warn_On_Component_Order;
- W.Warn_On_Redundant_Constructs :=
- Warn_On_Redundant_Constructs;
- W.Warn_On_Reverse_Bit_Order :=
- Warn_On_Reverse_Bit_Order;
- W.Warn_On_Size_Alignment :=
- Warn_On_Size_Alignment;
- W.Warn_On_Standard_Redefinition :=
- Warn_On_Standard_Redefinition;
- W.Warn_On_Suspicious_Contract :=
- Warn_On_Suspicious_Contract;
- W.Warn_On_Unchecked_Conversion :=
- Warn_On_Unchecked_Conversion;
- W.Warn_On_Unknown_Compile_Time_Warning :=
- Warn_On_Unknown_Compile_Time_Warning;
- W.Warn_On_Unordered_Enumeration_Type :=
- Warn_On_Unordered_Enumeration_Type;
- W.Warn_On_Unrecognized_Pragma :=
- Warn_On_Unrecognized_Pragma;
- W.Warn_On_Unrepped_Components :=
- Warn_On_Unrepped_Components;
- W.Warn_On_Warnings_Off :=
- Warn_On_Warnings_Off;
- return W;
+ return Warning_Flags;
end Save_Warnings;
----------------------------
- -- Set_Dot_Warning_Switch --
- ----------------------------
-
- function Set_Dot_Warning_Switch (C : Character) return Boolean is
- begin
- case C is
- when 'a' =>
- Warn_On_Assertion_Failure := True;
-
- when 'A' =>
- Warn_On_Assertion_Failure := False;
-
- when 'b' =>
- Warn_On_Biased_Representation := True;
-
- when 'B' =>
- Warn_On_Biased_Representation := False;
-
- when 'c' =>
- Warn_On_Unrepped_Components := True;
-
- when 'C' =>
- Warn_On_Unrepped_Components := False;
-
- when 'd' =>
- Warning_Doc_Switch := True;
-
- when 'D' =>
- Warning_Doc_Switch := False;
-
- when 'e' =>
- All_Warnings (True);
-
- when 'f' =>
- Warn_On_Elab_Access := True;
-
- when 'F' =>
- Warn_On_Elab_Access := False;
-
- when 'g' =>
- Set_GNAT_Mode_Warnings;
-
- when 'h' =>
- Warn_On_Record_Holes := True;
-
- when 'H' =>
- Warn_On_Record_Holes := False;
-
- when 'i' =>
- Warn_On_Overlap := True;
-
- when 'I' =>
- Warn_On_Overlap := False;
-
- when 'j' =>
- Warn_On_Late_Primitives := True;
-
- when 'J' =>
- Warn_On_Late_Primitives := False;
-
- when 'k' =>
- Warn_On_Standard_Redefinition := True;
-
- when 'K' =>
- Warn_On_Standard_Redefinition := False;
-
- when 'l' =>
- List_Inherited_Aspects := True;
-
- when 'L' =>
- List_Inherited_Aspects := False;
-
- when 'm' =>
- Warn_On_Suspicious_Modulus_Value := True;
-
- when 'M' =>
- Warn_On_Suspicious_Modulus_Value := False;
-
- when 'n' =>
- Warn_On_Atomic_Synchronization := True;
-
- when 'N' =>
- Warn_On_Atomic_Synchronization := False;
-
- when 'o' =>
- Warn_On_All_Unread_Out_Parameters := True;
-
- when 'O' =>
- Warn_On_All_Unread_Out_Parameters := False;
-
- when 'p' =>
- Warn_On_Parameter_Order := True;
-
- when 'P' =>
- Warn_On_Parameter_Order := False;
-
- when 'q' =>
- Warn_On_Questionable_Layout := True;
-
- when 'Q' =>
- Warn_On_Questionable_Layout := False;
-
- when 'r' =>
- Warn_On_Object_Renames_Function := True;
-
- when 'R' =>
- Warn_On_Object_Renames_Function := False;
-
- when 's' =>
- Warn_On_Overridden_Size := True;
-
- when 'S' =>
- Warn_On_Overridden_Size := False;
-
- when 't' =>
- Warn_On_Suspicious_Contract := True;
-
- when 'T' =>
- Warn_On_Suspicious_Contract := False;
-
- when 'u' =>
- Warn_On_Unordered_Enumeration_Type := True;
-
- when 'U' =>
- Warn_On_Unordered_Enumeration_Type := False;
-
- when 'v' =>
- Warn_On_Reverse_Bit_Order := True;
-
- when 'V' =>
- Warn_On_Reverse_Bit_Order := False;
-
- when 'w' =>
- Warn_On_Warnings_Off := True;
-
- when 'W' =>
- Warn_On_Warnings_Off := False;
-
- when 'x' =>
- Warn_On_Non_Local_Exception := True;
-
- when 'X' =>
- Warn_On_Non_Local_Exception := False;
- No_Warn_On_Non_Local_Exception := True;
-
- when 'y' =>
- List_Body_Required_Info := True;
-
- when 'Y' =>
- List_Body_Required_Info := False;
-
- when 'z' =>
- Warn_On_Size_Alignment := True;
-
- when 'Z' =>
- Warn_On_Size_Alignment := False;
-
- when others =>
- if Ignore_Unrecognized_VWY_Switches then
- Write_Line ("unrecognized switch -gnatw." & C & " ignored");
- else
- return False;
- end if;
- end case;
-
- return True;
- end Set_Dot_Warning_Switch;
-
- -----------------------------------
- -- Set_Underscore_Warning_Switch --
- -----------------------------------
-
- function Set_Underscore_Warning_Switch (C : Character) return Boolean is
- begin
- case C is
- when 'a' =>
- Warn_On_Anonymous_Allocators := True;
-
- when 'A' =>
- Warn_On_Anonymous_Allocators := False;
-
- when 'c' =>
- Warn_On_Unknown_Compile_Time_Warning := True;
-
- when 'C' =>
- Warn_On_Unknown_Compile_Time_Warning := False;
-
- when 'p' =>
- Warn_On_Pedantic_Checks := True;
-
- when 'P' =>
- Warn_On_Pedantic_Checks := False;
-
- when 'r' =>
- Warn_On_Component_Order := True;
-
- when 'R' =>
- Warn_On_Component_Order := False;
-
- when others =>
- if Ignore_Unrecognized_VWY_Switches then
- Write_Line ("unrecognized switch -gnatw_" & C & " ignored");
- else
- return False;
- end if;
- end case;
-
- return True;
- end Set_Underscore_Warning_Switch;
-
- ----------------------------
-- Set_GNAT_Mode_Warnings --
----------------------------
@@ -541,8 +177,7 @@ package body Warnsw is
begin
-- Set -gnatwa warnings and no others
- All_Warnings (False);
- WA_Warnings;
+ Warning_Flags := (Warning_Flags and not All_Warnings) or WA_Warnings;
-- These warnings are added to the -gnatwa set
@@ -564,215 +199,118 @@ package body Warnsw is
-- Set_Warning_Switch --
------------------------
- function Set_Warning_Switch (C : Character) return Boolean is
+ function Set_Warning_Switch
+ (Family : Warning_Family; C : Character) return Boolean
+ is
+ L : constant Character := To_Lower (C);
begin
- case C is
- when 'a' =>
- WA_Warnings;
-
- when 'A' =>
- All_Warnings (False);
- No_Warn_On_Non_Local_Exception := True;
-
- when 'b' =>
- Warn_On_Bad_Fixed_Value := True;
-
- when 'B' =>
- Warn_On_Bad_Fixed_Value := False;
-
- when 'c' =>
- Constant_Condition_Warnings := True;
-
- when 'C' =>
- Constant_Condition_Warnings := False;
-
- when 'd' =>
- Warn_On_Dereference := True;
-
- when 'D' =>
- Warn_On_Dereference := False;
-
- when 'e' =>
- Warning_Mode := Treat_As_Error;
-
- when 'E' =>
- Warning_Mode := Treat_Run_Time_Warnings_As_Errors;
-
- when 'f' =>
- Check_Unreferenced_Formals := True;
-
- when 'F' =>
- Check_Unreferenced_Formals := False;
-
- when 'g' =>
- Warn_On_Unrecognized_Pragma := True;
-
- when 'G' =>
- Warn_On_Unrecognized_Pragma := False;
-
- when 'h' =>
- Warn_On_Hiding := True;
-
- when 'H' =>
- Warn_On_Hiding := False;
-
- when 'i' =>
- Implementation_Unit_Warnings := True;
-
- when 'I' =>
- Implementation_Unit_Warnings := False;
-
- when 'j' =>
- Warn_On_Obsolescent_Feature := True;
-
- when 'J' =>
- Warn_On_Obsolescent_Feature := False;
-
- when 'k' =>
- Warn_On_Constant := True;
-
- when 'K' =>
- Warn_On_Constant := False;
-
- when 'l' =>
- Elab_Warnings := True;
-
- when 'L' =>
- Elab_Warnings := False;
-
- when 'm' =>
- Warn_On_Modified_Unread := True;
-
- when 'M' =>
- Warn_On_Modified_Unread := False;
-
- when 'n' =>
- Warning_Mode := Normal;
-
- when 'o' =>
- Address_Clause_Overlay_Warnings := True;
-
- when 'O' =>
- Address_Clause_Overlay_Warnings := False;
-
- when 'p' =>
- Ineffective_Inline_Warnings := True;
-
- when 'P' =>
- Ineffective_Inline_Warnings := False;
-
- when 'q' =>
- Warn_On_Questionable_Missing_Parens := True;
-
- when 'Q' =>
- Warn_On_Questionable_Missing_Parens := False;
-
- when 'r' =>
- Warn_On_Redundant_Constructs := True;
-
- when 'R' =>
- Warn_On_Redundant_Constructs := False;
-
- when 's' =>
- Warning_Mode := Suppress;
-
- when 't' =>
- Warn_On_Deleted_Code := True;
-
- when 'T' =>
- Warn_On_Deleted_Code := False;
-
- when 'u' =>
- Check_Unreferenced := True;
- Check_Withs := True;
- Check_Unreferenced_Formals := True;
-
- when 'U' =>
- Check_Unreferenced := False;
- Check_Withs := False;
- Check_Unreferenced_Formals := False;
-
- when 'v' =>
- Warn_On_No_Value_Assigned := True;
-
- when 'V' =>
- Warn_On_No_Value_Assigned := False;
-
- when 'w' =>
- Warn_On_Assumed_Low_Bound := True;
-
- when 'W' =>
- Warn_On_Assumed_Low_Bound := False;
-
- when 'x' =>
- Warn_On_Export_Import := True;
-
- when 'X' =>
- Warn_On_Export_Import := False;
-
- when 'y' =>
- Warn_On_Ada_2005_Compatibility := True;
- Warn_On_Ada_2012_Compatibility := True;
-
- when 'Y' =>
- Warn_On_Ada_2005_Compatibility := False;
- Warn_On_Ada_2012_Compatibility := False;
-
- when 'z' =>
- Warn_On_Unchecked_Conversion := True;
-
- when 'Z' =>
- Warn_On_Unchecked_Conversion := False;
-
- when others =>
- if Ignore_Unrecognized_VWY_Switches then
- Write_Line ("unrecognized switch -gnatw" & C & " ignored");
- else
- return False;
- end if;
- end case;
+ -- Error case
+
+ if L not in Lowercase
+ or else Switch_To_Flag_Mapping (Family, L) = No_Such_Warning
+ then
+ if Ignore_Unrecognized_VWY_Switches then
+ declare
+ Family_Switch : constant String :=
+ (case Family is
+ when Plain => "", when '.' => ".", when '_' => "_");
+ begin
+ Write_Line
+ ("unrecognized switch -gnatw" & Family_Switch & C &
+ " ignored");
+ end;
+ return True;
+ else
+ return False;
+ end if;
+ end if;
+
+ -- Special cases that don't fall into the normal pattern below
+
+ if Switch_To_Flag_Mapping (Family, L) = Special_Case then
+ case Family is
+ when Plain =>
+ case C is
+ when 'a' =>
+ -- "or" in the -gnatwa flags, possibly leaving others set
+ Warning_Flags := Warning_Flags or WA_Warnings;
+
+ when 'A' =>
+ -- Turn off the All_Warnings flags, except that
+ -- No_Warn_On_Non_Local_Exception is a special case.
+ Warning_Flags := Warning_Flags and not All_Warnings;
+ No_Warn_On_Non_Local_Exception := True;
+
+ when 'e' =>
+ Warning_Mode := Treat_As_Error;
+
+ when 'E' =>
+ Warning_Mode := Treat_Run_Time_Warnings_As_Errors;
+
+ when 'n' =>
+ Warning_Mode := Normal;
+
+ when 's' =>
+ Warning_Mode := Suppress;
+
+ when 'u' =>
+ Check_Unreferenced := True;
+ Check_Withs := True;
+ Check_Unreferenced_Formals := True;
+
+ when 'U' =>
+ Check_Unreferenced := False;
+ Check_Withs := False;
+ Check_Unreferenced_Formals := False;
+
+ when 'y' =>
+ Warn_On_Ada_2005_Compatibility := True;
+ Warn_On_Ada_2012_Compatibility := True;
+
+ when 'Y' =>
+ Warn_On_Ada_2005_Compatibility := False;
+ Warn_On_Ada_2012_Compatibility := False;
+
+ when others => raise Program_Error;
+ end case;
+
+ when '.' =>
+ case C is
+ when 'e' =>
+ -- "or" in the All_Warnings flags
+ Warning_Flags := Warning_Flags or All_Warnings;
+ when 'g' =>
+ Set_GNAT_Mode_Warnings;
+
+ when 'x' =>
+ Warn_On_Non_Local_Exception := True;
+
+ when 'X' =>
+ Warn_On_Non_Local_Exception := False;
+ No_Warn_On_Non_Local_Exception := True;
+
+ when others => raise Program_Error;
+ end case;
+
+ when '_' =>
+ raise Program_Error;
+ end case;
+
+ return True;
+ end if;
+
+ -- Normal pattern (lower case enables the warning, upper case disables
+ -- the warning).
+
+ if C in Lowercase then
+ Warning_Flags (Switch_To_Flag_Mapping (Family, C)) := True;
+ elsif L in Lowercase then
+ Warning_Flags (Switch_To_Flag_Mapping (Family, L)) := False;
+ else
+ raise Program_Error;
+ end if;
return True;
end Set_Warning_Switch;
- -----------------
- -- WA_Warnings --
- -----------------
-
- procedure WA_Warnings is
- begin
- Check_Unreferenced := True; -- -gnatwf/-gnatwu
- Check_Unreferenced_Formals := True; -- -gnatwf/-gnatwu
- Check_Withs := True; -- -gnatwu
- Constant_Condition_Warnings := True; -- -gnatwc
- Implementation_Unit_Warnings := True; -- -gnatwi
- Ineffective_Inline_Warnings := True; -- -gnatwp
- Warn_On_Ada_2005_Compatibility := True; -- -gnatwy
- Warn_On_Ada_2012_Compatibility := True; -- -gnatwy
- Warn_On_Anonymous_Allocators := True; -- -gnatw_a
- Warn_On_Assertion_Failure := True; -- -gnatw.a
- Warn_On_Assumed_Low_Bound := True; -- -gnatww
- Warn_On_Bad_Fixed_Value := True; -- -gnatwb
- Warn_On_Biased_Representation := True; -- -gnatw.b
- Warn_On_Constant := True; -- -gnatwk
- Warn_On_Export_Import := True; -- -gnatwx
- Warn_On_Late_Primitives := True; -- -gnatw.j
- Warn_On_Modified_Unread := True; -- -gnatwm
- Warn_On_No_Value_Assigned := True; -- -gnatwv
- Warn_On_Non_Local_Exception := True; -- -gnatw.x
- Warn_On_Object_Renames_Function := True; -- -gnatw.r
- Warn_On_Obsolescent_Feature := True; -- -gnatwj
- Warn_On_Overlap := True; -- -gnatw.i
- Warn_On_Parameter_Order := True; -- -gnatw.p
- Warn_On_Questionable_Missing_Parens := True; -- -gnatwq
- Warn_On_Redundant_Constructs := True; -- -gnatwr
- Warn_On_Reverse_Bit_Order := True; -- -gnatw.v
- Warn_On_Size_Alignment := True; -- -gnatw.z
- Warn_On_Suspicious_Contract := True; -- -gnatw.t
- Warn_On_Suspicious_Modulus_Value := True; -- -gnatw.m
- Warn_On_Unchecked_Conversion := True; -- -gnatwz
- Warn_On_Unrecognized_Pragma := True; -- -gnatwg
- Warn_On_Unrepped_Components := True; -- -gnatw.c
- end WA_Warnings;
-
end Warnsw;
diff --git a/gcc/ada/warnsw.ads b/gcc/ada/warnsw.ads
index 8fe5ef7..46ae752 100644
--- a/gcc/ada/warnsw.ads
+++ b/gcc/ada/warnsw.ads
@@ -24,6 +24,7 @@
------------------------------------------------------------------------------
-- This unit contains the routines used to handle setting of warning options
+-- in the GNAT compiler.
package Warnsw is
@@ -34,162 +35,484 @@ package Warnsw is
-- These flags are activated or deactivated by -gnatw switches and control
-- whether warnings of a given class will be generated or not.
- -- Note: most of these flags are still in opt, but the plan is to move them
- -- here as time goes by. And in fact a really nice idea would be to put
- -- them all in a Warn_Record so that they would be easy to save/restore.
+ package Warnings_Package is
+ type Opt_Warnings_Enum is
+ -- List of all warnings that can be enabled, plus the two null-ish
+ -- values.
+ (No_Such_Warning, Special_Case, -- see body
- Warn_On_Anonymous_Allocators : Boolean := False;
+ Address_Clause_Overlay_Warnings,
+ Check_Unreferenced,
+ Check_Unreferenced_Formals,
+ Check_Withs,
+ Constant_Condition_Warnings,
+ Elab_Info_Messages,
+ Elab_Warnings,
+ Implementation_Unit_Warnings,
+ Ineffective_Inline_Warnings,
+ List_Body_Required_Info,
+ List_Inherited_Aspects,
+ Warning_Doc_Switch,
+ Warn_On_Ada_2005_Compatibility,
+ Warn_On_Ada_2012_Compatibility,
+ Warn_On_Ada_2022_Compatibility,
+ Warn_On_All_Unread_Out_Parameters,
+ Warn_On_Anonymous_Allocators,
+ Warn_On_Assertion_Failure,
+ Warn_On_Assumed_Low_Bound,
+ Warn_On_Atomic_Synchronization,
+ Warn_On_Bad_Fixed_Value,
+ Warn_On_Biased_Representation,
+ Warn_On_Component_Order,
+ Warn_On_Constant,
+ Warn_On_Deleted_Code,
+ Warn_On_Dereference,
+ Warn_On_Elab_Access,
+ Warn_On_Export_Import,
+ Warn_On_Hiding,
+ Warn_On_Ignored_Equality,
+ Warn_On_Late_Primitives,
+ Warn_On_Modified_Unread,
+ Warn_On_No_Value_Assigned,
+ Warn_On_Non_Local_Exception,
+ No_Warn_On_Non_Local_Exception,
+ Warn_On_Object_Renames_Function,
+ Warn_On_Obsolescent_Feature,
+ Warn_On_Overlap,
+ Warn_On_Overridden_Size,
+ Warn_On_Parameter_Order,
+ Warn_On_Pedantic_Checks,
+ Warn_On_Questionable_Layout,
+ Warn_On_Questionable_Missing_Parens,
+ Warn_On_Record_Holes,
+ Warn_On_Redundant_Constructs,
+ Warn_On_Reverse_Bit_Order,
+ Warn_On_Size_Alignment,
+ Warn_On_Standard_Redefinition,
+ Warn_On_Suspicious_Contract,
+ Warn_On_Suspicious_Modulus_Value,
+ Warn_On_Unchecked_Conversion,
+ Warn_On_Unknown_Compile_Time_Warning,
+ Warn_On_Unordered_Enumeration_Type,
+ Warn_On_Unrecognized_Pragma,
+ Warn_On_Unrepped_Components,
+ Warn_On_Warnings_Off); -- Opt_Warnings_Enum
+
+ subtype Warnings_Enum is Opt_Warnings_Enum
+ range Opt_Warnings_Enum'Succ (Special_Case) .. Opt_Warnings_Enum'Last;
+ -- Just the warning switches, without the null-ish values
+ end Warnings_Package;
+ use Warnings_Package;
+
+ type Warnings_State is array (Warnings_Enum) of Boolean;
+ pragma Pack (Warnings_State);
+ -- Without Pack, we can have bootstrapping failures, because the compiler
+ -- generates calls to System.Boolean_Array_Operations, which is not
+ -- currently part of the compiler.
+
+ Warning_Flags : Warnings_State :=
+ -- Current state of warnings -- True/False means enabled/disabled.
+ -- The following initializes the flags to their default values,
+ -- and warning switches modify them.
+ (Address_Clause_Overlay_Warnings |
+ Elab_Warnings |
+ Implementation_Unit_Warnings |
+ Warning_Doc_Switch |
+ Warn_On_Ada_2005_Compatibility |
+ Warn_On_Ada_2012_Compatibility |
+ Warn_On_Ada_2022_Compatibility |
+ Warn_On_Assertion_Failure |
+ Warn_On_Assumed_Low_Bound |
+ Warn_On_Biased_Representation |
+ Warn_On_Export_Import |
+ Warn_On_No_Value_Assigned |
+ Warn_On_Questionable_Missing_Parens |
+ Warn_On_Reverse_Bit_Order |
+ Warn_On_Size_Alignment |
+ Warn_On_Suspicious_Contract |
+ Warn_On_Suspicious_Modulus_Value |
+ Warn_On_Unchecked_Conversion |
+ Warn_On_Unknown_Compile_Time_Warning |
+ Warn_On_Unrecognized_Pragma =>
+ True,
+
+ Check_Unreferenced |
+ Check_Unreferenced_Formals |
+ Check_Withs |
+ Constant_Condition_Warnings |
+ Elab_Info_Messages |
+ Ineffective_Inline_Warnings |
+ List_Body_Required_Info |
+ List_Inherited_Aspects |
+ Warn_On_All_Unread_Out_Parameters |
+ Warn_On_Anonymous_Allocators |
+ Warn_On_Atomic_Synchronization |
+ Warn_On_Bad_Fixed_Value |
+ Warn_On_Component_Order |
+ Warn_On_Constant |
+ Warn_On_Deleted_Code |
+ Warn_On_Dereference |
+ Warn_On_Elab_Access |
+ Warn_On_Hiding |
+ Warn_On_Ignored_Equality |
+ Warn_On_Late_Primitives |
+ Warn_On_Modified_Unread |
+ Warn_On_Non_Local_Exception |
+ No_Warn_On_Non_Local_Exception |
+ Warn_On_Object_Renames_Function |
+ Warn_On_Obsolescent_Feature |
+ Warn_On_Overlap |
+ Warn_On_Overridden_Size |
+ Warn_On_Parameter_Order |
+ Warn_On_Pedantic_Checks |
+ Warn_On_Questionable_Layout |
+ Warn_On_Record_Holes |
+ Warn_On_Redundant_Constructs |
+ Warn_On_Standard_Redefinition |
+ Warn_On_Unordered_Enumeration_Type |
+ Warn_On_Unrepped_Components |
+ Warn_On_Warnings_Off =>
+ False);
+
+ package X renames Warnings_Package;
+ F : Warnings_State renames Warning_Flags;
+ -- Short-hand names used only locally to this package
+
+ -- The following rename all the components of Warning_Flags for convenient
+ -- access throughout the compiler.
+
+ pragma Style_Checks ("M120");
+ Address_Clause_Overlay_Warnings : Boolean renames F (X.Address_Clause_Overlay_Warnings);
+ -- Set False to disable address clause warnings. Modified by use of
+ -- -gnatwo/O.
+
+ Check_Unreferenced : Boolean renames F (X.Check_Unreferenced);
+ -- Set to True to enable checking for unreferenced entities other
+ -- than formal parameters (for which see Check_Unreferenced_Formals)
+ -- Modified by use of -gnatwu/U.
+
+ Check_Unreferenced_Formals : Boolean renames F (X.Check_Unreferenced_Formals);
+ -- Set to True to check for unreferenced formals. This is turned on by
+ -- -gnatwa/wf/wu and turned off by -gnatwA/wF/wU.
+
+ Check_Withs : Boolean renames F (X.Check_Withs);
+ -- Set to True to enable checking for unused withs, and also the case
+ -- of withing a package and using none of the entities in the package.
+ -- Modified by use of -gnatwu/U.
+
+ Constant_Condition_Warnings : Boolean renames F (X.Constant_Condition_Warnings);
+ -- Set to True to activate warnings on constant conditions. Modified by
+ -- use of -gnatwc/C.
+
+ Elab_Info_Messages : Boolean renames F (X.Elab_Info_Messages);
+ -- Set to True to output info messages for static elabmodel (-gnatel)
+
+ Elab_Warnings : Boolean renames F (X.Elab_Warnings);
+ -- Set to True to generate elaboration warnings (-gnatwl). The warnings are
+ -- enabled by default because they carry the same importance as errors. The
+ -- compiler cannot emit actual errors because elaboration diagnostics need
+ -- dataflow analysis, which is not available. This behavior parallels that
+ -- of the old ABE mechanism.
+
+ Implementation_Unit_Warnings : Boolean renames F (X.Implementation_Unit_Warnings);
+ -- Set True to active warnings for use of implementation internal units.
+ -- Modified by use of -gnatwi/-gnatwI.
+
+ Ineffective_Inline_Warnings : Boolean renames F (X.Ineffective_Inline_Warnings);
+ -- Set True to activate warnings if front-end inlining (-gnatN) is not able
+ -- to actually inline a particular call (or all calls). Can be controlled
+ -- by use of -gnatwp/-gnatwP. Also set True to activate warnings if
+ -- frontend inlining is not able to inline a subprogram expected to
+ -- be inlined in GNATprove mode.
+
+ List_Body_Required_Info : Boolean renames F (X.List_Body_Required_Info);
+ -- List info messages about why a package requires a body. Modified by use
+ -- of -gnatw.y/.Y.
+
+ List_Inherited_Aspects : Boolean renames F (X.List_Inherited_Aspects);
+ -- List inherited invariants, preconditions, and postconditions from
+ -- Invariant'Class, Pre'Class, and Post'Class aspects. Also list inherited
+ -- subtype predicates. Modified by use of -gnatw.l/.L.
+
+ Warning_Doc_Switch : Boolean renames F (X.Warning_Doc_Switch);
+ -- If this is set True, then the ??/?*?/?$?/?x?/?.x?/?_x? insertion
+ -- sequences in error messages generate appropriate tags for the output
+ -- error messages. If this switch is False, then these sequences are still
+ -- recognized (for the purposes of implementing the pattern matching in
+ -- pragmas Warnings (Off,..) and Warning_As_Error(...) but do not result
+ -- in adding the error message tag. The -gnatw.d switch sets this flag
+ -- True, -gnatw.D sets this flag False.
+
+ Warn_On_Ada_2005_Compatibility : Boolean renames F (X.Warn_On_Ada_2005_Compatibility);
+ -- Set to True to generate all warnings on Ada 2005 compatibility issues,
+ -- including warnings on Ada 2005 obsolescent features used in Ada 2005
+ -- mode. Set by default, modified by use of -gnatwy/Y.
+
+ Warn_On_Ada_2012_Compatibility : Boolean renames F (X.Warn_On_Ada_2012_Compatibility);
+ -- Set to True to generate all warnings on Ada 2012 compatibility issues,
+ -- including warnings on Ada 2012 obsolescent features used in Ada 2012
+ -- mode. Modified by use of -gnatwy/Y.
+
+ Warn_On_Ada_2022_Compatibility : Boolean renames F (X.Warn_On_Ada_2022_Compatibility);
+ -- Set to True to generate all warnings on Ada 2022 compatibility issues,
+ -- including warnings on Ada 2022 obsolescent features used in Ada 2022
+ -- mode. There is no switch controlling this option.
+
+ Warn_On_All_Unread_Out_Parameters : Boolean renames F (X.Warn_On_All_Unread_Out_Parameters);
+ -- Set to True to generate warnings in all cases where a variable is
+ -- modified by being passed as to an OUT formal, but the resulting value is
+ -- never read. The default is that this warning is suppressed. Modified
+ -- by use of gnatw.o/.O.
+
+ Warn_On_Anonymous_Allocators : Boolean renames F (X.Warn_On_Anonymous_Allocators);
-- Warn when allocators for anonymous access types are present, which,
-- although not illegal in Ada, may be confusing to users due to how
-- accessibility checks get generated. Off by default, modified by use
-- of -gnatw_a/_A and set as part of -gnatwa.
- Warn_On_Late_Primitives : Boolean := False;
+ Warn_On_Assertion_Failure : Boolean renames F (X.Warn_On_Assertion_Failure);
+ -- Set to True to activate warnings on assertions that can be determined
+ -- at compile time will always fail. Modified by use of -gnatw.a/.A.
+
+ Warn_On_Assumed_Low_Bound : Boolean renames F (X.Warn_On_Assumed_Low_Bound);
+ -- Set to True to activate warnings for string parameters that are indexed
+ -- with literals or S'Length, presumably assuming a lower bound of one.
+ -- Modified by use of -gnatww/W.
+
+ Warn_On_Atomic_Synchronization : Boolean renames F (X.Warn_On_Atomic_Synchronization);
+ -- Set to True to generate information messages for atomic synchronization.
+ -- Modified by use of -gnatw.n/.N.
+
+ Warn_On_Bad_Fixed_Value : Boolean renames F (X.Warn_On_Bad_Fixed_Value);
+ -- Set to True to generate warnings for static fixed-point expression
+ -- values that are not an exact multiple of the small value of the type.
+ -- Odd by default, modified by use of -gnatwb/B.
+
+ Warn_On_Biased_Representation : Boolean renames F (X.Warn_On_Biased_Representation);
+ -- Set to True to generate warnings for size clauses, component clauses
+ -- and component_size clauses that force biased representation. Modified
+ -- by use of -gnatw.b/.B.
+
+ Warn_On_Component_Order : Boolean renames F (X.Warn_On_Component_Order);
+ -- Warn when record component clauses are out of order with respect to the
+ -- component declarations, or if the memory layout is out of order with
+ -- respect to component declarations and clauses. Off by default, set by
+ -- -gnatw_r (but not -gnatwa).
+
+ Warn_On_Constant : Boolean renames F (X.Warn_On_Constant);
+ -- Set to True to generate warnings for variables that could be declared
+ -- as constants. Modified by use of -gnatwk/K.
+
+ Warn_On_Deleted_Code : Boolean renames F (X.Warn_On_Deleted_Code);
+ -- Set to True to generate warnings for code deleted by the front end
+ -- for conditional statements whose outcome is known at compile time.
+ -- Modified by use of -gnatwt/T.
+
+ Warn_On_Dereference : Boolean renames F (X.Warn_On_Dereference);
+ -- Set to True to generate warnings for implicit dereferences for array
+ -- indexing and record component access. Modified by use of -gnatwd/D.
+
+ Warn_On_Elab_Access : Boolean renames F (X.Warn_On_Elab_Access);
+ -- Set to True to generate warnings for P'Access in the case where
+ -- subprogram P is in the same package as the P'Access, and the P'Access is
+ -- evaluated at package elaboration time, and occurs before the body of P
+ -- has been elaborated. Modified by use of -gnatw.f/.F.
+
+ Warn_On_Export_Import : Boolean renames F (X.Warn_On_Export_Import);
+ -- Set to True to generate warnings for suspicious use of export or
+ -- import pragmas. Modified by use of -gnatwx/X.
+
+ Warn_On_Hiding : Boolean renames F (X.Warn_On_Hiding);
+ -- Set to True to generate warnings if a declared entity hides another
+ -- entity. The default is that this warning is suppressed. Modified by
+ -- use of -gnatwh/H.
+
+ Warn_On_Ignored_Equality : Boolean renames F (X.Warn_On_Ignored_Equality);
+ -- Warn when a user-defined "=" function does not compose (i.e. is ignored
+ -- for a predefined "=" for a composite type containing a component of
+ -- whose type has the user-defined "=" as primitive). Off by default, and
+ -- set by -gnatw_q (but not -gnatwa).
+
+ Warn_On_Late_Primitives : Boolean renames F (X.Warn_On_Late_Primitives);
-- Warn when tagged type public primitives are defined after its private
-- extensions.
- Warn_On_Unknown_Compile_Time_Warning : Boolean := True;
- -- Warn on a pragma Compile_Time_Warning whose condition has a value that
- -- is not known at compile time. On by default, modified by use
- -- of -gnatw_c/_C and set as part of -gnatwa.
+ Warn_On_Modified_Unread : Boolean renames F (X.Warn_On_Modified_Unread);
+ -- Set to True to generate warnings if a variable is assigned but is never
+ -- read. Also controls warnings for similar cases involving out parameters,
+ -- but only if there is only one out parameter for the procedure involved.
+ -- The default is that this warning is suppressed, modified by use of
+ -- -gnatwm/M.
+
+ Warn_On_No_Value_Assigned : Boolean renames F (X.Warn_On_No_Value_Assigned);
+ -- Set to True to generate warnings if no value is ever assigned to a
+ -- variable that is at least partially uninitialized. Set to false to
+ -- suppress such warnings. The default is that such warnings are enabled.
+ -- Modified by use of -gnatwv/V.
- Warn_On_Overridden_Size : Boolean := False;
+ Warn_On_Non_Local_Exception : Boolean renames F (X.Warn_On_Non_Local_Exception);
+ -- Set to True to generate warnings for non-local exception raises and also
+ -- handlers that can never handle a local raise. This warning is only ever
+ -- generated if pragma Restrictions (No_Exception_Propagation) is set. The
+ -- default is not to generate the warnings except that if the source has
+ -- at least one exception handler, and this restriction is set, and the
+ -- warning was not explicitly turned off, then it is turned on by default.
+ -- Modified by use of -gnatw.x/.X.
+
+ No_Warn_On_Non_Local_Exception : Boolean renames F (X.No_Warn_On_Non_Local_Exception);
+ -- This is set to True if the above warning is explicitly suppressed. We
+ -- use this to avoid turning it on by default when No_Exception_Propagation
+ -- restriction is set and an exception handler is present.
+
+ Warn_On_Object_Renames_Function : Boolean renames F (X.Warn_On_Object_Renames_Function);
+ -- Set to True to generate warnings when a function result is renamed as
+ -- an object. The default is that this warning is disabled. Modified by
+ -- use of -gnatw.r/.R.
+
+ Warn_On_Obsolescent_Feature : Boolean renames F (X.Warn_On_Obsolescent_Feature);
+ -- Set to True to generate warnings on use of any feature in Annex or if a
+ -- subprogram is called for which a pragma Obsolescent applies. Modified
+ -- by use of -gnatwj/J.
+
+ Warn_On_Overlap : Boolean renames F (X.Warn_On_Overlap);
+ -- Set to True to generate warnings when a writable actual overlaps with
+ -- another actual in a subprogram call. This applies only in modes before
+ -- Ada 2012. Starting with Ada 2012, such overlaps are illegal.
+ -- Modified by use of -gnatw.i/.I.
+
+ Warn_On_Overridden_Size : Boolean renames F (X.Warn_On_Overridden_Size);
-- Warn when explicit record component clause or array component_size
-- clause specifies a size that overrides a size for the type which was
-- set with an explicit size clause. Off by default, modified by use of
-- -gnatw.s/.S (but not -gnatwa).
- Warn_On_Pedantic_Checks : Boolean := False;
+ Warn_On_Parameter_Order : Boolean renames F (X.Warn_On_Parameter_Order);
+ -- Set to True to generate warnings for cases where the argument list for
+ -- a call is a sequence of identifiers that match the formal identifiers,
+ -- but are in the wrong order.
+
+ Warn_On_Pedantic_Checks : Boolean renames F (X.Warn_On_Pedantic_Checks);
-- Warn for violation of miscellaneous pedantic rules (such as when the
-- subtype of a formal parameter given in a subprogram body's specification
-- comes from a different subtype declaration that the subtype of the
-- formal in the subprogram declaration). Off by default, and set by
-- -gnatw_p (but not -gnatwa).
- Warn_On_Questionable_Layout : Boolean := False;
+ Warn_On_Questionable_Layout : Boolean renames F (X.Warn_On_Questionable_Layout);
-- Warn when default layout of a record type is questionable for run-time
-- efficiency reasons and would be improved by reordering the components.
-- Off by default, modified by use of -gnatw.q/.Q (but not -gnatwa).
- -- WARNING: There is a matching C declaration of this variable in fe.h
+ function Get_Warn_On_Questionable_Layout return Boolean is
+ (Warn_On_Questionable_Layout);
+ -- WARNING: There is a matching C declaration of this function in fe.h
- Warn_On_Record_Holes : Boolean := False;
+ Warn_On_Questionable_Missing_Parens : Boolean renames F (X.Warn_On_Questionable_Missing_Parens);
+ -- Set to True to generate warnings for cases where parentheses are missing
+ -- and the usage is questionable, because the intent is unclear. On by
+ -- default, modified by use of -gnatwq/Q.
+
+ Warn_On_Record_Holes : Boolean renames F (X.Warn_On_Record_Holes);
-- Warn when explicit record component clauses leave uncovered holes (gaps)
-- in a record layout. Off by default, set by -gnatw.h (but not -gnatwa).
- Warn_On_Component_Order : Boolean := False;
- -- Warn when record component clauses are out of order with respect to the
- -- component declarations, or if the memory layout is out of order with
- -- respect to component declarations and clauses. Off by default, set by
- -- -gnatw_r (but not -gnatwa).
+ Warn_On_Redundant_Constructs : Boolean renames F (X.Warn_On_Redundant_Constructs);
+ -- Set to True to generate warnings for redundant constructs (e.g. useless
+ -- assignments/conversions). The default is that this warning is disabled.
+ -- Modified by use of -gnatwr/R.
- Warn_On_Size_Alignment : Boolean := True;
+ Warn_On_Reverse_Bit_Order : Boolean renames F (X.Warn_On_Reverse_Bit_Order);
+ -- Set to True to generate warning (informational) messages for component
+ -- clauses that are affected by non-standard bit-order. The default is
+ -- that this warning is enabled. Modified by -gnatw.v/.V.
+
+ Warn_On_Size_Alignment : Boolean renames F (X.Warn_On_Size_Alignment);
-- Warn when explicit Size and Alignment clauses are given for a type, and
-- the size is not a multiple of the alignment. Off by default, modified
-- by use of -gnatw.z/.Z and set as part of -gnatwa.
- Warn_On_Standard_Redefinition : Boolean := False;
+ Warn_On_Standard_Redefinition : Boolean renames F (X.Warn_On_Standard_Redefinition);
-- Warn when a program defines an identifier that matches a name in
-- Standard. Off by default, modified by use of -gnatw.k/.K (but not
-- by -gnatwa).
+ Warn_On_Suspicious_Contract : Boolean renames F (X.Warn_On_Suspicious_Contract);
+ -- Set to True to generate warnings for suspicious contracts expressed as
+ -- pragmas or aspects precondition and postcondition, as well as other
+ -- suspicious cases of expressions typically found in contracts like
+ -- quantified expressions and uses of Update attribute. The default is that
+ -- this warning is enabled. Modified by use of -gnatw.t/.T.
+
+ Warn_On_Suspicious_Modulus_Value : Boolean renames F (X.Warn_On_Suspicious_Modulus_Value);
+ -- Set to True to generate warnings for suspicious modulus values, as well
+ -- as negative literals of a modular type. The default is that this warning
+ -- is enabled. Modified by -gnatw.m/.M.
+
+ Warn_On_Unchecked_Conversion : Boolean renames F (X.Warn_On_Unchecked_Conversion);
+ -- Set to True to generate warnings for unchecked conversions that may have
+ -- non-portable semantics (e.g. because sizes of types differ). Modified
+ -- by use of -gnatwz/Z.
+
+ Warn_On_Unknown_Compile_Time_Warning : Boolean renames F (X.Warn_On_Unknown_Compile_Time_Warning);
+ -- Warn on a pragma Compile_Time_Warning whose condition has a value that
+ -- is not known at compile time. On by default, modified by use
+ -- of -gnatw_c/_C and set as part of -gnatwa.
+
+ Warn_On_Unordered_Enumeration_Type : Boolean renames F (X.Warn_On_Unordered_Enumeration_Type);
+ -- Set to True to generate warnings for inappropriate uses (comparisons
+ -- and explicit ranges) on unordered enumeration types (which includes
+ -- all enumeration types for which pragma Ordered is not given). The
+ -- default is that this warning is disabled. Modified by -gnat.u/.U.
+
+ Warn_On_Unrecognized_Pragma : Boolean renames F (X.Warn_On_Unrecognized_Pragma);
+ -- Set to True to generate warnings for unrecognized pragmas. The default
+ -- is that this warning is enabled. Modified by use of -gnatwg/G.
+
+ Warn_On_Unrepped_Components : Boolean renames F (X.Warn_On_Unrepped_Components);
+ -- Set to True to generate warnings for the case of components of record
+ -- which have a record representation clause but this component does not
+ -- have a component clause. Modified by use of -gnatw.c/.C.
+
+ Warn_On_Warnings_Off : Boolean renames F (X.Warn_On_Warnings_Off);
+ -- Set to True to generate warnings for use of Pragma Warnings (Off, ent),
+ -- where either the pragma is never used, or it could be replaced by a
+ -- pragma Unmodified or Unreferenced. Also generates warnings for pragma
+ -- Warning (Off, string) which either has no matching pragma Warning On,
+ -- or where no warning has been suppressed by the use of the pragma.
+ -- Modified by use of -gnatw.w/.W.
+ pragma Style_Checks ("M79");
+
-----------------------------------
-- Saving and Restoring Warnings --
-----------------------------------
- -- Type used to save and restore warnings
-
- type Warning_Record is record
- Address_Clause_Overlay_Warnings : Boolean;
- Check_Unreferenced : Boolean;
- Check_Unreferenced_Formals : Boolean;
- Check_Withs : Boolean;
- Constant_Condition_Warnings : Boolean;
- Elab_Info_Messages : Boolean;
- Elab_Warnings : Boolean;
- Implementation_Unit_Warnings : Boolean;
- Ineffective_Inline_Warnings : Boolean;
- List_Body_Required_Info : Boolean;
- List_Inherited_Aspects : Boolean;
- No_Warn_On_Non_Local_Exception : Boolean;
- Warning_Doc_Switch : Boolean;
- Warn_On_Ada_2005_Compatibility : Boolean;
- Warn_On_Ada_2012_Compatibility : Boolean;
- Warn_On_All_Unread_Out_Parameters : Boolean;
- Warn_On_Anonymous_Allocators : Boolean;
- Warn_On_Assertion_Failure : Boolean;
- Warn_On_Assumed_Low_Bound : Boolean;
- Warn_On_Atomic_Synchronization : Boolean;
- Warn_On_Bad_Fixed_Value : Boolean;
- Warn_On_Biased_Representation : Boolean;
- Warn_On_Constant : Boolean;
- Warn_On_Deleted_Code : Boolean;
- Warn_On_Dereference : Boolean;
- Warn_On_Export_Import : Boolean;
- Warn_On_Hiding : Boolean;
- Warn_On_Late_Primitives : Boolean;
- Warn_On_Modified_Unread : Boolean;
- Warn_On_No_Value_Assigned : Boolean;
- Warn_On_Non_Local_Exception : Boolean;
- Warn_On_Object_Renames_Function : Boolean;
- Warn_On_Obsolescent_Feature : Boolean;
- Warn_On_Overlap : Boolean;
- Warn_On_Overridden_Size : Boolean;
- Warn_On_Parameter_Order : Boolean;
- Warn_On_Pedantic_Checks : Boolean;
- Warn_On_Questionable_Layout : Boolean;
- Warn_On_Questionable_Missing_Parens : Boolean;
- Warn_On_Record_Holes : Boolean;
- Warn_On_Component_Order : Boolean;
- Warn_On_Redundant_Constructs : Boolean;
- Warn_On_Reverse_Bit_Order : Boolean;
- Warn_On_Size_Alignment : Boolean;
- Warn_On_Standard_Redefinition : Boolean;
- Warn_On_Suspicious_Contract : Boolean;
- Warn_On_Suspicious_Modulus_Value : Boolean;
- Warn_On_Unchecked_Conversion : Boolean;
- Warn_On_Unknown_Compile_Time_Warning : Boolean;
- Warn_On_Unordered_Enumeration_Type : Boolean;
- Warn_On_Unrecognized_Pragma : Boolean;
- Warn_On_Unrepped_Components : Boolean;
- Warn_On_Warnings_Off : Boolean;
- end record;
-
- function Save_Warnings return Warning_Record;
- -- Returns current settingh of warnings
-
- procedure Restore_Warnings (W : Warning_Record);
+ function Save_Warnings return Warnings_State;
+ -- Returns current settings of warnings
+
+ procedure Restore_Warnings (W : Warnings_State);
-- Restores current settings of warning flags from W
-----------------
-- Subprograms --
-----------------
- function Set_Warning_Switch (C : Character) return Boolean;
- -- This function sets the warning switch or switches corresponding to the
- -- given character. It is used to process a -gnatw switch on the command
- -- line, or a character in a string literal in pragma Warnings. Returns
- -- True for valid warning character C, False for invalid character.
-
- function Set_Dot_Warning_Switch (C : Character) return Boolean;
- -- This function sets the warning switch or switches corresponding to the
- -- given character preceded by a dot. Used to process a -gnatw. switch on
- -- the command line or .C in a string literal in pragma Warnings. Returns
- -- True for valid warning character C, False for invalid character.
-
- function Set_Underscore_Warning_Switch (C : Character) return Boolean;
- -- This function sets the warning switch or switches corresponding to the
- -- given character preceded by an underscore. Used to process a -gnatw_
- -- switch on the command line or _C in a string literal in pragma Warnings.
- -- Returns True for valid warnings character C, False for invalid
- -- character.
+ type Warning_Family is
+ -- The "family" indicates the form of warning switch:
+ (Plain, -- form "-gnatwx"
+ '.', -- form "-gnatw.x"
+ '_'); -- form "-gnatw_x"
+ -- where "x" is a lowercase letter that enables a particular warning.
+ -- Typically, uppercase of "x" disables the warning, but there are some
+ -- switches that do not follow that pattern.
+
+ function Set_Warning_Switch
+ (Family : Warning_Family; C : Character) return Boolean;
+ -- Set the warning switch or switches corresponding to the given family and
+ -- character. Returns True for valid warning switch, False for invalid.
+ -- Called for -gnatw... switches, and for pragma Warnings.
procedure Set_GNAT_Mode_Warnings;
- -- This is called in -gnatg mode to set the warnings for gnat mode. It is
- -- also used to set the proper warning statuses for -gnatw.g. Note that
- -- this set of warnings is neither a subset nor a superset of -gnatwa, it
- -- enables warnings that are not included in -gnatwa and disables warnings
- -- that are included in -gnatwa (such as Warn_On_Implementation_Units, that
- -- we clearly want to be False for units built with -gnatg).
+ -- Called for -gnatg and -gnatw.g to set GNAT mode warnings. This set of
+ -- warnings is neither a subset nor a superset of -gnatwa.
end Warnsw;
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 6e6b056..9118035 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,1371 @@
+2022-12-09 David Malcolm <dmalcolm@redhat.com>
+
+ * analyzer.h (class known_function): Expand comment.
+ * region-model-impl-calls.cc: Rename to...
+ * kf.cc: ...this.
+ * known-function-manager.h (class known_function_manager): Add
+ leading comment.
+
+2022-12-09 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/108003
+ * call-summary.cc
+ (call_summary_replay::convert_region_from_summary_1): Convert
+ heap_regs_in_use from auto_sbitmap to auto_bitmap.
+ * region-model-manager.cc
+ (region_model_manager::get_or_create_region_for_heap_alloc):
+ Convert from sbitmap to bitmap.
+ * region-model-manager.h: Likewise.
+ * region-model.cc
+ (region_model::get_or_create_region_for_heap_alloc): Convert from
+ auto_sbitmap to auto_bitmap.
+ (region_model::get_referenced_base_regions): Likewise.
+ * region-model.h: Include "bitmap.h" rather than "sbitmap.h".
+ (region_model::get_referenced_base_regions): Convert from
+ auto_sbitmap to auto_bitmap.
+
+2022-12-09 David Malcolm <dmalcolm@redhat.com>
+
+ * region-model-impl-calls.cc (class kf_memcpy): Rename to...
+ (class kf_memcpy_memmove): ...this.
+ (kf_memcpy::impl_call_pre): Rename to...
+ (kf_memcpy_memmove::impl_call_pre): ...this, and check the src for
+ poison.
+ (register_known_functions): Update for above renaming, and
+ register BUILT_IN_MEMMOVE and BUILT_IN_MEMMOVE_CHK.
+
+2022-12-06 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107882
+ * region-model.cc (region_model::get_store_value): Return an
+ unknown value for empty regions.
+ (region_model::set_value): Bail on empty regions.
+ * region.cc (region::empty_p): New.
+ * region.h (region::empty_p): New decl.
+ * state-purge.cc (same_binding_p): Bail if either region is empty.
+ * store.cc (binding_key::make): Assert that a concrete binding's
+ bit_size must be > 0.
+ (binding_cluster::mark_region_as_unknown): Bail on empty regions.
+ (binding_cluster::get_binding): Likewise.
+ (binding_cluster::remove_overlapping_bindings): Likewise.
+ (binding_cluster::on_unknown_fncall): Don't conjure values for
+ empty regions.
+ (store::fill_region): Bail on empty regions.
+ * store.h (class concrete_binding): Update comment to reflect that
+ the range of bits must be non-empty.
+ (concrete_binding::concrete_binding): Assert that bit range is
+ non-empty.
+
+2022-12-06 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106325
+ * region-model-manager.cc
+ (region_model_manager::get_or_create_null_ptr): New.
+ * region-model-manager.h
+ (region_model_manager::get_or_create_null_ptr): New decl.
+ * region-model.cc (region_model::on_top_level_param): Add
+ "nonnull" param and make use of it.
+ (region_model::push_frame): When handling a top-level entrypoint
+ to the analysis, determine which params __attribute__((nonnull))
+ applies to, and pass to on_top_level_param.
+ * region-model.h (region_model::on_top_level_param): Add "nonnull"
+ param.
+
+2022-12-06 David Malcolm <dmalcolm@redhat.com>
+
+ * analyzer.h (register_known_analyzer_functions): New decl.
+ (register_known_functions_lang_cp): New decl.
+ * call-details.cc: New file, split out from
+ region-model-impl-calls.cc.
+ * call-details.h: New file, split out from region-model.h.
+ * call-info.cc: Include "analyzer/call-details.h".
+ * call-summary.h: Likewise.
+ * kf-analyzer.cc: New file, split out from
+ region-model-impl-calls.cc.
+ * kf-lang-cp.cc: Likewise.
+ * known-function-manager.cc: Include "analyzer/call-details.h".
+ * region-model-impl-calls.cc: Move definitions of call_details's
+ member functions to call-details.cc. Move class kf_analyzer_* to
+ kf-analyzer.cc. Move kf_operator_new and kf_operator_delete to
+ kf-lang-cp.cc. Refresh #includes accordingly.
+ (register_known_functions): Replace registration of __analyzer_*
+ functions with a call to register_known_analyzer_functions.
+ Replace registration of C++ support functions with a call to
+ register_known_functions_lang_cp.
+ * region-model.h (class call_details): Move to new call-details.h.
+ * sm-fd.cc: Include "analyzer/call-details.h".
+ * sm-file.cc: Likewise.
+ * sm-malloc.cc: Likewise.
+ * varargs.cc: Likewise.
+
+2022-12-02 David Malcolm <dmalcolm@redhat.com>
+
+ * analyzer.h (struct event_loc_info): New forward decl.
+ * bounds-checking.cc: Use event_loc_info throughout to bundle the
+ loc, fndecl, depth triples.
+ * call-info.cc: Likewise.
+ * checker-event.cc: Likewise.
+ * checker-event.h (struct event_loc_info): New decl. Use it
+ throughout to bundle the loc, fndecl, depth triples.
+ * checker-path.cc: Likewise.
+ * checker-path.h: Likewise.
+ * diagnostic-manager.cc: Likewise.
+ * engine.cc: Likewise.
+ * infinite-recursion.cc: Likewise.
+ * pending-diagnostic.cc: Likewise.
+ * pending-diagnostic.h: Likewise.
+ * region-model.cc: Likewise.
+ * sm-signal.cc: Likewise.
+ * varargs.cc: Likewise.
+
+2022-12-02 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107851
+ * analyzer.cc (make_label_text_n): Convert param "n" from int to
+ unsigned HOST_WIDE_INT.
+ * analyzer.h (make_label_text_n): Likewise for decl.
+ * bounds-checking.cc: Include "analyzer/checker-event.h" and
+ "analyzer/checker-path.h".
+ (out_of_bounds::add_region_creation_events): New.
+ (concrete_past_the_end::describe_region_creation_event): Replace
+ with...
+ (concrete_past_the_end::add_region_creation_events): ...this.
+ (symbolic_past_the_end::describe_region_creation_event): Delete.
+ * checker-event.cc (region_creation_event::region_creation_event):
+ Update for dropping all member data.
+ (region_creation_event::get_desc): Delete, splitting out into
+ region_creation_event_memory_space::get_desc,
+ region_creation_event_capacity::get_desc, and
+ region_creation_event_debug::get_desc.
+ (region_creation_event_memory_space::get_desc): New.
+ (region_creation_event_capacity::get_desc): New.
+ (region_creation_event_allocation_size::get_desc): New.
+ (region_creation_event_debug::get_desc): New.
+ * checker-event.h: Include "analyzer/program-state.h".
+ (enum rce_kind): Delete.
+ (class region_creation_event): Drop all member data.
+ (region_creation_event::region_creation_event): Make protected.
+ (region_creation_event::get_desc): Delete.
+ (class region_creation_event_memory_space): New.
+ (class region_creation_event_capacity): New.
+ (class region_creation_event_allocation_size): New.
+ (class region_creation_event_debug): New.
+ * checker-path.cc (checker_path::add_region_creation_events): Add
+ "pd" param. Call pending_diangnostic::add_region_creation_events.
+ Update for conversion of RCE_DEBUG to region_creation_event_debug.
+ * checker-path.h (checker_path::add_region_creation_events): Add
+ "pd" param.
+ * diagnostic-manager.cc (diagnostic_manager::build_emission_path):
+ Pass pending_diagnostic to
+ emission_path::add_region_creation_events.
+ (diagnostic_manager::build_emission_path): Pass path_builder to
+ add_event_on_final_node.
+ (diagnostic_manager::add_event_on_final_node): Add "pb" param.
+ Pass pending_diagnostic to
+ emission_path::add_region_creation_events.
+ (diagnostic_manager::add_events_for_eedge): Pass
+ pending_diagnostic to emission_path::add_region_creation_events.
+ * diagnostic-manager.h
+ (diagnostic_manager::add_event_on_final_node): Add "pb" param.
+ * pending-diagnostic.cc
+ (pending_diagnostic::add_region_creation_events): New.
+ * pending-diagnostic.h (struct region_creation): Delete.
+ (pending_diagnostic::describe_region_creation_event): Delete.
+ (pending_diagnostic::add_region_creation_events): New vfunc.
+ * region-model.cc: Include "analyzer/checker-event.h" and
+ "analyzer/checker-path.h".
+ (dubious_allocation_size::dubious_allocation_size): Initialize
+ m_has_allocation_event.
+ (dubious_allocation_size::describe_region_creation_event): Delete.
+ (dubious_allocation_size::describe_final_event): Update for
+ replacement of m_allocation_event with m_has_allocation_event.
+ (dubious_allocation_size::add_region_creation_events): New.
+ (dubious_allocation_size::m_allocation_event): Replace with...
+ (dubious_allocation_size::m_has_allocation_event): ...this.
+
+2022-12-02 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107948
+ * region-model-manager.cc
+ (region_model_manager::maybe_fold_binop): Fold (0 - VAL) to -VAL.
+ * region-model.cc (region_model::eval_condition): Handle e.g.
+ "-X <= 0" as equivalent to X >= 0".
+
+2022-12-01 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106626
+ * bounds-checking.cc
+ (symbolic_past_the_end::describe_final_event): Delete, moving to
+ symbolic_buffer_overflow::describe_final_event and
+ symbolic_buffer_over_read::describe_final_event, eliminating
+ composition of text strings via "byte_str" and "m_dir_str".
+ (symbolic_past_the_end::m_dir_str): Delete field.
+ (symbolic_buffer_overflow::symbolic_buffer_overflow): Drop
+ m_dir_str.
+ (symbolic_buffer_overflow::describe_final_event): New, as noted
+ above.
+ (symbolic_buffer_over_read::symbolic_buffer_overflow): Drop
+ m_dir_str.
+ (symbolic_buffer_over_read::describe_final_event): New, as noted
+ above.
+
+2022-12-01 David Malcolm <dmalcolm@redhat.com>
+
+ * bounds-checking.cc (class out_of_bounds): Split out from...
+ (class concrete_out_of_bounds): New abstract subclass.
+ (class past_the_end): Rename to...
+ (class concrete_past_the_end): ...this, and make a subclass of
+ concrete_out_of_bounds.
+ (class buffer_overflow): Rename to...
+ (class concrete_buffer_overflow): ...this, and make a subclass of
+ concrete_past_the_end.
+ (class buffer_over_read): Rename to...
+ (class concrete_buffer_over_read): ...this, and make a subclass of
+ concrete_past_the_end.
+ (class buffer_underwrite): Rename to...
+ (class concrete_buffer_underwrite): ...this, and make a subclass
+ of concrete_out_of_bounds.
+ (class buffer_under_read): Rename to...
+ (class concrete_buffer_under_read): ...this, and make a subclass
+ of concrete_out_of_bounds.
+ (class symbolic_past_the_end): Convert to a subclass of
+ out_of_bounds.
+ (symbolic_buffer_overflow::get_kind): New.
+ (symbolic_buffer_over_read::get_kind): New.
+ (region_model::check_region_bounds): Update for renamings.
+ * engine.cc (impl_sm_context::set_next_state): Eliminate
+ "new_ctxt", passing NULL to get_rvalue instead.
+ (impl_sm_context::warn): Likewise.
+
+2022-12-01 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106626
+ * bounds-checking.cc (out_of_bounds::get_memory_space): New.
+ (buffer_overflow::emit): Use it.
+ (class buffer_overread): Rename to...
+ (class buffer_over_read): ...this.
+ (buffer_over_read::emit): Specify which memory space the read is
+ from, where known. Change "overread" to "over-read".
+ (class buffer_underflow): Rename to...
+ (class buffer_underwrite): ...this.
+ (buffer_underwrite::emit): Specify which memory space the write is
+ to, where known. Change "underflow" to "underwrite".
+ (class buffer_underread): Rename to...
+ (class buffer_under_read): Rename to...
+ (buffer_under_read::emit): Specify which memory space the read is
+ from, where known. Change "underread" to "under-read".
+ (symbolic_past_the_end::get_memory_space): New.
+ (symbolic_buffer_overflow::emit): Use it.
+ (class symbolic_buffer_overread): Rename to...
+ (class symbolic_buffer_over_read): ...this.
+ (symbolic_buffer_over_read::emit): Specify which memory space the
+ read is from, where known. Change "overread" to "over-read".
+ (region_model::check_symbolic_bounds): Update for class renaming.
+ (region_model::check_region_bounds): Likewise.
+
+2022-12-01 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106626
+ * bounds-checking.cc (out_of_bounds::maybe_describe_array_bounds):
+ New.
+ (buffer_overflow::emit): Call maybe_describe_array_bounds.
+ (buffer_overread::emit): Likewise.
+ (buffer_underflow::emit): Likewise.
+ (buffer_underread::emit): Likewise.
+
+2022-12-01 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106626
+ * bounds-checking.cc (buffer_overflow::emit): Use inform_n.
+ Update wording to clarify that we're talking about the size of
+ the bad access, rather than its position.
+ (buffer_overread::emit): Likewise.
+
+2022-12-01 David Malcolm <dmalcolm@redhat.com>
+
+ * bounds-checking.cc: New file, taken from region-model.cc.
+ * region-model.cc (class out_of_bounds): Move to
+ bounds-checking.cc.
+ (class past_the_end): Likewise.
+ (class buffer_overflow): Likewise.
+ (class buffer_overread): Likewise.
+ (class buffer_underflow): Likewise.
+ (class buffer_underread): Likewise.
+ (class symbolic_past_the_end): Likewise.
+ (class symbolic_buffer_overflow): Likewise.
+ (class symbolic_buffer_overread): Likewise.
+ (region_model::check_symbolic_bounds): Likewise.
+ (maybe_get_integer_cst_tree): Likewise.
+ (region_model::check_region_bounds): Likewise.
+ * region-model.h: Add comment.
+
+2022-12-01 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107928
+ * sm-fd.cc (fd_state_machine::on_bind): Handle m_constant_fd in
+ the "success" outcome.
+ (fd_state_machine::on_connect): Likewise.
+ * sm-fd.dot: Add "constant_fd" state and its transitions.
+
+2022-11-30 David Malcolm <dmalcolm@redhat.com>
+
+ * region-model-impl-calls.cc (class kf_fgets): Move to sm-file.cc.
+ (kf_fgets::impl_call_pre): Likewise.
+ (class kf_fread): Likewise.
+ (kf_fread::impl_call_pre): Likewise.
+ (class kf_getchar): Likewise.
+ (class kf_stdio_output_fn): Likewise.
+ (register_known_functions): Move registration of
+ BUILT_IN_FPRINTF, BUILT_IN_FPRINTF_UNLOCKED, BUILT_IN_FPUTC,
+ BUILT_IN_FPUTC_UNLOCKED, BUILT_IN_FPUTS, BUILT_IN_FPUTS_UNLOCKED,
+ BUILT_IN_FWRITE, BUILT_IN_FWRITE_UNLOCKED, BUILT_IN_PRINTF,
+ BUILT_IN_PRINTF_UNLOCKED, BUILT_IN_PUTC, BUILT_IN_PUTCHAR,
+ BUILT_IN_PUTCHAR_UNLOCKED, BUILT_IN_PUTC_UNLOCKED, BUILT_IN_PUTS,
+ BUILT_IN_PUTS_UNLOCKED, BUILT_IN_VFPRINTF, BUILT_IN_VPRINTF,
+ "getchar", "fgets", "fgets_unlocked", and "fread" to
+ register_known_file_functions.
+ * sm-file.cc (class kf_stdio_output_fn): Move here from
+ region-model-impl-calls.cc.
+ (class kf_fgets): Likewise.
+ (class kf_fread): Likewise.
+ (class kf_getchar): Likewise.
+ (register_known_file_functions): Move registration of
+ BUILT_IN_FPRINTF, BUILT_IN_FPRINTF_UNLOCKED, BUILT_IN_FPUTC,
+ BUILT_IN_FPUTC_UNLOCKED, BUILT_IN_FPUTS, BUILT_IN_FPUTS_UNLOCKED,
+ BUILT_IN_FWRITE, BUILT_IN_FWRITE_UNLOCKED, BUILT_IN_PRINTF,
+ BUILT_IN_PRINTF_UNLOCKED, BUILT_IN_PUTC, BUILT_IN_PUTCHAR,
+ BUILT_IN_PUTCHAR_UNLOCKED, BUILT_IN_PUTC_UNLOCKED, BUILT_IN_PUTS,
+ BUILT_IN_PUTS_UNLOCKED, BUILT_IN_VFPRINTF, BUILT_IN_VPRINTF,
+ "fgets", "fgets_unlocked", "fread", and "getchar" to here from
+ register_known_functions.
+
+2022-11-30 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/103546
+ * analyzer.h (register_known_file_functions): New decl.
+ * program-state.cc (sm_state_map::replay_call_summary): Rejct
+ attempts to store sm-state for caller_sval that can't have
+ associated state.
+ * region-model-impl-calls.cc (register_known_functions): Call
+ register_known_file_functions.
+ * sm-fd.cc (class kf_isatty): New.
+ (register_known_fd_functions): Register it.
+ * sm-file.cc (class kf_ferror): New.
+ (class kf_fileno): New.
+ (class kf_getc): New.
+ (register_known_file_functions): New.
+
+2022-11-30 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/105784
+ * region-model-manager.cc
+ (region_model_manager::maybe_fold_binop): For POINTER_PLUS_EXPR,
+ PLUS_EXPR and MINUS_EXPR, eliminate requirement that the final
+ type matches that of arg0 in favor of a cast.
+
+2022-11-24 Martin Liska <mliska@suse.cz>
+
+ * varargs.cc: Fix Clang warnings.
+
+2022-11-24 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106473
+ * call-summary.cc
+ (call_summary_replay::convert_region_from_summary_1): Update for
+ change to creation of heap-allocated regions.
+ * program-state.cc (test_program_state_1): Likewise.
+ (test_program_state_merging): Likewise.
+ * region-model-impl-calls.cc (kf_calloc::impl_call_pre): Likewise.
+ (kf_malloc::impl_call_pre): Likewise.
+ (kf_operator_new::impl_call_pre): Likewise.
+ (kf_realloc::impl_call_postsuccess_with_move::update_model): Likewise.
+ * region-model-manager.cc
+ (region_model_manager::create_region_for_heap_alloc): Convert
+ to...
+ (region_model_manager::get_or_create_region_for_heap_alloc):
+ ...this, reusing an existing region if it's unreferenced in the
+ client state.
+ * region-model-manager.h (region_model_manager::get_num_regions): New.
+ (region_model_manager::create_region_for_heap_alloc): Convert to...
+ (region_model_manager::get_or_create_region_for_heap_alloc): ...this.
+ * region-model.cc (region_to_value_map::can_merge_with_p): Reject
+ merger when the values are different.
+ (region_model::create_region_for_heap_alloc): Convert to...
+ (region_model::get_or_create_region_for_heap_alloc): ...this.
+ (region_model::get_referenced_base_regions): New.
+ (selftest::test_state_merging): Update for change to creation of
+ heap-allocated regions.
+ (selftest::test_malloc_constraints): Likewise.
+ (selftest::test_malloc): Likewise.
+ * region-model.h: Include "sbitmap.h".
+ (region_model::create_region_for_heap_alloc): Convert to...
+ (region_model::get_or_create_region_for_heap_alloc): ...this.
+ (region_model::get_referenced_base_regions): New decl.
+ * store.cc (store::canonicalize): Don't purge a heap-allocated region
+ that's been marked as escaping.
+
+2022-11-24 David Malcolm <dmalcolm@redhat.com>
+
+ * checker-path.cc (checker_path::inject_any_inlined_call_events):
+ Don't dump the address of the block when -fdump-noaddr.
+
+2022-11-24 David Malcolm <dmalcolm@redhat.com>
+
+ * region-model.h (region_model::on_socket): Delete decl.
+ (region_model::on_bind): Likewise.
+ (region_model::on_listen): Likewise.
+ (region_model::on_accept): Likewise.
+ (region_model::on_connect): Likewise.
+ * sm-fd.cc (kf_socket::outcome_of_socket::update_model): Move body
+ of region_model::on_socket into here, ...
+ (region_model::on_socket): ...eliminating this function.
+ (kf_bind::outcome_of_bind::update_model): Likewise for on_bind...
+ (region_model::on_bind): ...eliminating this function.
+ (kf_listen::outcome_of_listen::update_model): Likewise fo
+ on_listen...
+ (region_model::on_listen): ...eliminating this function.
+ (kf_accept::outcome_of_accept::update_model): Likewise fo
+ on_accept...
+ (region_model::on_accept): ...eliminating this function.
+ (kf_connect::outcome_of_connect::update_model): Likewise fo
+ on_connect...
+ (region_model::on_connect): ...eliminating this function.
+
+2022-11-24 David Malcolm <dmalcolm@redhat.com>
+
+ * analyzer.h (register_known_fd_functions): New decl.
+ * region-model-impl-calls.cc (class kf_accept): Move to sm-fd.cc.
+ (class kf_bind): Likewise.
+ (class kf_connect): Likewise.
+ (class kf_listen): Likewise.
+ (class kf_pipe): Likewise.
+ (class kf_socket): Likewise.
+ (register_known_functions): Remove registration of the above
+ functions, instead calling register_known_fd_functions.
+ * sm-fd.cc: Include "analyzer/call-info.h".
+ (class kf_socket): Move here from region-model-impl-calls.cc.
+ (class kf_bind): Likewise.
+ (class kf_listen): Likewise.
+ (class kf_accept): Likewise.
+ (class kf_connect): Likewise.
+ (class kf_pipe): Likewise.
+ (register_known_fd_functions): New.
+
+2022-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107788
+ * known-function-manager.cc (known_function_manager::get_match):
+ Don't look up fndecls by name when they're not in the root
+ namespace.
+
+2022-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107783
+ * sm-fd.cc (fd_state_machine::check_for_new_socket_fd): Don't
+ complain when old state is "fd-constant".
+ (fd_state_machine::on_listen): Likewise.
+ (fd_state_machine::on_accept): Likewise.
+
+2022-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107807
+ * region-model-impl-calls.cc (register_known_functions): Register
+ "___errno" and "__error" as synonyms for "__errno_location".
+
+2022-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ * analyzer.h (class internal_known_function): New.
+ (register_varargs_builtins): New decl.
+ * engine.cc (exploded_node::on_stmt_pre): Remove
+ "out_terminate_path" param from call to region_model::on_stmt_pre.
+ (feasibility_state::maybe_update_for_edge): Likewise.
+ * known-function-manager.cc: Include "basic-block.h", "gimple.h",
+ and "analyzer/region-model.h".
+ (known_function_manager::known_function_manager): Initialize
+ m_combined_fns_arr.
+ (known_function_manager::~known_function_manager): Clean up
+ m_combined_fns_arr.
+ (known_function_manager::get_by_identifier): Make const.
+ (known_function_manager::add): New overloaded definitions for
+ enum built_in_function and enum internal_fn.
+ (known_function_manager::get_by_fndecl): Delete.
+ (known_function_manager::get_match): New.
+ (known_function_manager::get_internal_fn): New.
+ (known_function_manager::get_normal_builtin): New.
+ * known-function-manager.h
+ (known_function_manager::get_by_identifier): Make private and
+ add const qualifier.
+ (known_function_manager::get_by_fndecl): Delete.
+ (known_function_manager::add): Add overloaded decls for
+ enum built_in_function name and enum internal_fn.
+ (known_function_manager::get_match): New decl.
+ (known_function_manager::get_internal_fn): New decl.
+ (known_function_manager::get_normal_builtin): New decl.
+ (known_function_manager::m_combined_fns_arr): New field.
+ * region-model-impl-calls.cc (call_details::arg_is_size_p): New.
+ (class kf_alloca): New.
+ (region_model::impl_call_alloca): Convert to...
+ (kf_alloca::impl_call_pre): ...this.
+ (kf_analyzer_dump_capacity::matches_call_types_p): Rewrite check
+ to use call_details::arg_is_pointer_p.
+ (region_model::impl_call_builtin_expect): Convert to...
+ (class kf_expect): ...this.
+ (class kf_calloc): New, adding check that both arguments are
+ size_t.
+ (region_model::impl_call_calloc): Convert to...
+ (kf_calloc::impl_call_pre): ...this.
+ (kf_connect::matches_call_types_p): Rewrite check to use
+ call_details::arg_is_pointer_p.
+ (region_model::impl_call_error): Convert to...
+ (class kf_error): ...this, and...
+ (kf_error::impl_call_pre): ...this.
+ (class kf_fgets): New, adding checks that args 0 and 2 are
+ pointers.
+ (region_model::impl_call_fgets): Convert to...
+ (kf_fgets::impl_call_pre): ...this.
+ (class kf_fread): New, adding checks on the argument types.
+ (region_model::impl_call_fread): Convert to...
+ (kf_fread::impl_call_pre): ...this.
+ (class kf_free): New, adding check that the argument is a pointer.
+ (region_model::impl_call_free): Convert to...
+ (kf_free::impl_call_post): ...this.
+ (class kf_getchar): New.
+ (class kf_malloc): New, adding check that the argument is a
+ size_t.
+ (region_model::impl_call_malloc): Convert to...
+ (kf_malloc::impl_call_pre): ...this.
+ (class kf_memcpy): New, adding checks on arguments.
+ (region_model::impl_call_memcpy): Convert to...
+ (kf_memcpy::impl_call_pre): ...this.
+ (class kf_memset): New.
+ (region_model::impl_call_memset): Convert to...
+ (kf_memset::impl_call_pre): ...this.
+ (kf_pipe::matches_call_types_p): Rewrite check to use
+ call_details::arg_is_pointer_p.
+ (kf_putenv::matches_call_types_p): Likewise.
+ (class kf_realloc): New, adding checks on the argument types.
+ (region_model::impl_call_realloc): Convert to...
+ (kf_realloc::impl_call_post): ...this.
+ (class kf_strchr): New.
+ (region_model::impl_call_strchr): Convert to...
+ (kf_strchr::impl_call_post): ...this.
+ (class kf_stack_restore): New.
+ (class kf_stack_save): New.
+ (class kf_stdio_output_fn): New.
+ (class kf_strcpy): New,
+ (region_model::impl_call_strcpy): Convert to...
+ (kf_strcpy::impl_call_pre): ...this.
+ (class kf_strlen): New.
+ (region_model::impl_call_strlen): Convert to...
+ (kf_strlen::impl_call_pre): ...this.
+ (class kf_ubsan_bounds): New.
+ (region_model::impl_deallocation_call): Reimplement to avoid call
+ to impl_call_free.
+ (register_known_functions): Add handlers for IFN_BUILTIN_EXPECT
+ and IFN_UBSAN_BOUNDS. Add handlers for BUILT_IN_ALLOCA,
+ BUILT_IN_ALLOCA_WITH_ALIGN, BUILT_IN_CALLOC, BUILT_IN_EXPECT,
+ BUILT_IN_EXPECT_WITH_PROBABILITY, BUILT_IN_FPRINTF,
+ BUILT_IN_FPRINTF_UNLOCKED, BUILT_IN_FPUTC,
+ BUILT_IN_FPUTC_UNLOCKED, BUILT_IN_FPUTS, BUILT_IN_FPUTS_UNLOCKED,
+ BUILT_IN_FREE, BUILT_IN_FWRITE, BUILT_IN_FWRITE_UNLOCKED,
+ BUILT_IN_MALLOC, BUILT_IN_MEMCPY, BUILT_IN_MEMCPY_CHK,
+ BUILT_IN_MEMSET, BUILT_IN_MEMSET_CHK, BUILT_IN_PRINTF,
+ BUILT_IN_PRINTF_UNLOCKED, BUILT_IN_PUTC, BUILT_IN_PUTCHAR,
+ BUILT_IN_PUTCHAR_UNLOCKED, BUILT_IN_PUTC_UNLOCKED, BUILT_IN_PUTS,
+ BUILT_IN_PUTS_UNLOCKED, BUILT_IN_REALLOC, BUILT_IN_STACK_RESTORE,
+ BUILT_IN_STACK_SAVE, BUILT_IN_STRCHR, BUILT_IN_STRCPY,
+ BUILT_IN_STRCPY_CHK, BUILT_IN_STRLEN, BUILT_IN_VFPRINTF, and
+ BUILT_IN_VPRINTF. Call register_varargs_builtins. Add handlers
+ for "getchar", "memset", "fgets", "fgets_unlocked", "fread",
+ "error", and "error_at_line".
+ * region-model.cc (region_model::on_stmt_pre): Drop
+ "out_terminate_path" param.
+ (region_model::get_known_function): Reimplement by calling
+ known_function_manager::get_match, passing new "cd" param.
+ Add overload taking enum internal_fn.
+ (region_model::on_call_pre): Drop "out_terminate_path" param.
+ Remove special-case handling of internal fns IFN_BUILTIN_EXPECT,
+ IFN_UBSAN_BOUNDS, and IFN_VA_ARG, of built-in fns BUILT_IN_ALLOCA,
+ BUILT_IN_ALLOCA_WITH_ALIGN, BUILT_IN_CALLOC, BUILT_IN_EXPECT,
+ BUILT_IN_EXPECT_WITH_PROBABILITY, BUILT_IN_FREE, BUILT_IN_MALLOC,
+ BUILT_IN_MEMCPY, BUILT_IN_MEMCPY_CHK, BUILT_IN_MEMSET,
+ BUILT_IN_MEMSET_CHK, BUILT_IN_REALLOC, BUILT_IN_STRCHR,
+ BUILT_IN_STRCPY, BUILT_IN_STRCPY_CHK, BUILT_IN_STRLEN,
+ BUILT_IN_STACK_SAVE, BUILT_IN_STACK_RESTORE, BUILT_IN_FPRINTF,
+ BUILT_IN_FPRINTF_UNLOCKED, BUILT_IN_PUTC, BUILT_IN_PUTC_UNLOCKED,
+ BUILT_IN_FPUTC, BUILT_IN_FPUTC_UNLOCKED, BUILT_IN_FPUTS,
+ BUILT_IN_FPUTS_UNLOCKED, BUILT_IN_FWRITE,
+ BUILT_IN_FWRITE_UNLOCKED, BUILT_IN_PRINTF,
+ BUILT_IN_PRINTF_UNLOCKED, BUILT_IN_PUTCHAR,
+ BUILT_IN_PUTCHAR_UNLOCKED, BUILT_IN_PUTS, BUILT_IN_PUTS_UNLOCKED,
+ BUILT_IN_VFPRINTF, BUILT_IN_VPRINTF, BUILT_IN_VA_START, and
+ BUILT_IN_VA_COPY, and of named functions "malloc", "calloc",
+ "alloca", "realloc", "error", "error_at_line", "fgets",
+ "fgets_unlocked", "fread", "getchar", "memset", "strchr", and
+ "strlen". Replace all this special-casing with calls to
+ get_known_function for internal fns and for fn decls.
+ (region_model::on_call_post): Remove special-casing handling for
+ "free" and "strchr", and for BUILT_IN_REALLOC, BUILT_IN_STRCHR,
+ and BUILT_IN_VA_END. Replace by consolidating on usage of
+ get_known_function.
+ * region-model.h (call_details::arg_is_size_p): New.
+ (region_model::on_stmt_pre): Drop "out_terminate_path" param.
+ (region_model::on_call_pre): Likewise.
+ (region_model::impl_call_alloca): Delete.
+ (region_model::impl_call_builtin_expect): Delete.
+ (region_model::impl_call_calloc): Delete.
+ (region_model::impl_call_error): Delete.
+ (region_model::impl_call_fgets): Delete.
+ (region_model::impl_call_fread): Delete.
+ (region_model::impl_call_free): Delete.
+ (region_model::impl_call_malloc): Delete.
+ (region_model::impl_call_memcpy): Delete.
+ (region_model::impl_call_memset): Delete.
+ (region_model::impl_call_realloc): Delete.
+ (region_model::impl_call_strchr): Delete.
+ (region_model::impl_call_strcpy): Delete.
+ (region_model::impl_call_strlen): Delete.
+ (region_model::impl_call_va_start): Delete.
+ (region_model::impl_call_va_copy): Delete.
+ (region_model::impl_call_va_arg): Delete.
+ (region_model::impl_call_va_end): Delete.
+ (region_model::check_region_for_write): Public.
+ (region_model::get_known_function): Add "cd" param. Add
+ overloaded decl taking enum internal_fn.
+ * sm-malloc.cc: Update comments.
+ * varargs.cc (class kf_va_start): New.
+ (region_model::impl_call_va_start): Convert to...
+ (kf_va_start::impl_call_pre): ...this.
+ (class kf_va_copy): New.
+ (region_model::impl_call_va_copy): Convert to...
+ (kf_va_copy::impl_call_pre): ...this.
+ (class kf_va_arg): New.
+ (region_model::impl_call_va_arg): Convert to...
+ (kf_va_arg::impl_call_pre): ...this.
+ (class kf_va_end): New.
+ (region_model::impl_call_va_end): Delete.
+ (register_varargs_builtins): New.
+
+2022-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107788
+ * region-model.cc (region_model::update_for_int_cst_return):
+ Require that the return type be an integer type.
+ (region_model::update_for_nonzero_return): Likewise.
+
+2022-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107783
+ * region-model-impl-calls.cc (kf_accept::matches_call_types_p):
+ Require that args 1 and 2 be pointers.
+ (kf_bind::matches_call_types_p): Require that arg 1 be a pointer.
+ * region-model.h (call_details::arg_is_pointer_p): New
+
+2022-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107777
+ * call-summary.cc
+ (call_summary_replay::convert_region_from_summary_1): Handle
+ RK_THREAD_LOCAL and RK_ERRNO in switch.
+ * region-model.cc (region_model::get_representative_path_var_1):
+ Likewise.
+
+2022-11-19 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107582
+ * engine.cc (dynamic_call_info_t::update_model): Update the model
+ by pushing or pop a frame, rather than by clobbering it with the
+ model from the exploded_node's state.
+
+2022-11-18 David Malcolm <dmalcolm@redhat.com>
+
+ * analyzer.cc (is_pipe_call_p): Delete.
+ * analyzer.h (is_pipe_call_p): Delete.
+ * region-model-impl-calls.cc (call_details::get_location): New.
+ (class kf_analyzer_break): New, adapted from
+ region_model::on_stmt_pre.
+ (region_model::impl_call_analyzer_describe): Convert to...
+ (class kf_analyzer_describe): ...this.
+ (region_model::impl_call_analyzer_dump_capacity): Convert to...
+ (class kf_analyzer_dump_capacity): ...this.
+ (region_model::impl_call_analyzer_dump_escaped): Convert to...
+ (class kf_analyzer_dump_escaped): ...this.
+ (class kf_analyzer_dump_exploded_nodes): New.
+ (region_model::impl_call_analyzer_dump_named_constant): Convert
+ to...
+ (class kf_analyzer_dump_named_constant): ...this.
+ (class dump_path_diagnostic): Move here from region-model.cc.
+ (class kf_analyzer_dump_path) New, adapted from
+ region_model::on_stmt_pre.
+ (class kf_analyzer_dump_region_model): Likewise.
+ (region_model::impl_call_analyzer_eval): Convert to...
+ (class kf_analyzer_eval): ...this.
+ (region_model::impl_call_analyzer_get_unknown_ptr): Convert to...
+ (class kf_analyzer_get_unknown_ptr): ...this.
+ (class known_function_accept): Rename to...
+ (class kf_accept): ...this.
+ (class known_function_bind): Rename to...
+ (class kf_bind): ...this.
+ (class known_function_connect): Rename to...
+ (class kf_connect): ...this.
+ (region_model::impl_call_errno_location): Convert to...
+ (class kf_errno_location): ...this.
+ (class known_function_listen): Rename to...
+ (class kf_listen): ...this.
+ (region_model::impl_call_pipe): Convert to...
+ (class kf_pipe): ...this.
+ (region_model::impl_call_putenv): Convert to...
+ (class kf_putenv): ...this.
+ (region_model::impl_call_operator_new): Convert to...
+ (class kf_operator_new): ...this.
+ (region_model::impl_call_operator_delete): Convert to...
+ (class kf_operator_delete): ...this.
+ (class known_function_socket): Rename to...
+ (class kf_socket): ...this.
+ (register_known_functions): Rename param to KFM. Break out
+ existing known functions into a "POSIX" section, and add "pipe",
+ "pipe2", and "putenv". Add debugging functions
+ "__analyzer_break", "__analyzer_describe",
+ "__analyzer_dump_capacity", "__analyzer_dump_escaped",
+ "__analyzer_dump_exploded_nodes",
+ "__analyzer_dump_named_constant", "__analyzer_dump_path",
+ "__analyzer_dump_region_model", "__analyzer_eval",
+ "__analyzer_get_unknown_ptr". Add C++ support functions
+ "operator new", "operator new []", "operator delete", and
+ "operator delete []".
+ * region-model.cc (class dump_path_diagnostic): Move to
+ region-model-impl-calls.cc.
+ (region_model::on_stmt_pre): Eliminate special-casing of
+ "__analyzer_describe", "__analyzer_dump_capacity",
+ "__analyzer_dump_escaped", "__analyzer_dump_named_constant",
+ "__analyzer_dump_path", "__analyzer_dump_region_model",
+ "__analyzer_eval", "__analyzer_break",
+ "__analyzer_dump_exploded_nodes", "__analyzer_get_unknown_ptr",
+ "__errno_location", "pipe", "pipe2", "putenv", "operator new",
+ "operator new []", "operator delete", "operator delete []"
+ "pipe" and "pipe2", handling them instead via the known_functions
+ mechanism.
+ * region-model.h (call_details::get_location): New decl.
+ (region_model::impl_call_analyzer_describe): Delete decl.
+ (region_model::impl_call_analyzer_dump_capacity): Delete decl.
+ (region_model::impl_call_analyzer_dump_escaped): Delete decl.
+ (region_model::impl_call_analyzer_dump_named_constant): Delete decl.
+ (region_model::impl_call_analyzer_eval): Delete decl.
+ (region_model::impl_call_analyzer_get_unknown_ptr): Delete decl.
+ (region_model::impl_call_errno_location): Delete decl.
+ (region_model::impl_call_pipe): Delete decl.
+ (region_model::impl_call_putenv): Delete decl.
+ (region_model::impl_call_operator_new): Delete decl.
+ (region_model::impl_call_operator_delete): Delete decl.
+ * sm-fd.cc: Update comments.
+
+2022-11-16 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107711
+ * analyzer-language.cc: Include "diagnostic.h".
+ (maybe_stash_named_constant): Add logger param and use it to log
+ the name being looked up, and the result.
+ (stash_named_constants): New, splitting out from...
+ (on_finish_translation_unit): ...this function. Call
+ get_or_create_logfile and use the result to create a logger
+ instance, passing it to stash_named_constants.
+ * analyzer.h (get_or_create_any_logfile): New decl.
+ * engine.cc (dump_fout, owns_dump_fout): New globals, split out
+ from run_checkers.
+ (get_or_create_any_logfile): New function, split out from...
+ (run_checkers): ...here, so that the logfile can be opened by
+ on_finish_translation_unit. Clear the globals when closing the
+ dump file.
+
+2022-11-16 David Malcolm <dmalcolm@redhat.com>
+
+ * analyzer.h (known_function::matches_call_types_p): New vfunc.
+ (known_function::impl_call_pre): Provide base implementation.
+ (known_function::impl_call_post): New vfunc.
+ (register_known_functions): New.
+ * engine.cc (impl_run_checkers): Call register_known_functions.
+ * region-model-impl-calls.cc (region_model::impl_call_accept):
+ Convert to...
+ (class known_function_accept): ...this.
+ (region_model::impl_call_bind): Convert to...
+ (class known_function_bind): ...this.
+ (region_model::impl_call_connect): Convert to...
+ (class known_function_connect): ...this.
+ (region_model::impl_call_listen): Convert to...
+ (class known_function_listen): ...this.
+ (region_model::impl_call_socket): Convert to...
+ (class known_function_socket): ...this.
+ (register_known_functions): New.
+ * region-model.cc (region_model::on_call_pre): Remove special
+ case for "bind" in favor of the known_function-handling dispatch.
+ Add call to known_function::matches_call_types_p to latter.
+ (region_model::on_call_post): Remove special cases for "accept",
+ "bind", "connect", "listen", and "socket" in favor of dispatch
+ to known_function::impl_call_post.
+ * region-model.h (region_model::impl_call_accept): Delete decl.
+ (region_model::impl_call_bind): Delete decl.
+ (region_model::impl_call_connect): Delete decl.
+ (region_model::impl_call_listen): Delete decl.
+ (region_model::impl_call_socket): Delete decl.
+ * sm-fd.cc: Update comments.
+
+2022-11-16 David Malcolm <dmalcolm@redhat.com>
+
+ * checker-event.cc: New file, split out from...
+ * checker-path.cc: ...this file.
+
+2022-11-15 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106140
+ * analyzer-language.cc (on_finish_translation_unit): Stash named
+ constants "SOCK_STREAM" and "SOCK_DGRAM".
+ * analyzer.opt (Wanalyzer-fd-phase-mismatch): New.
+ (Wanalyzer-fd-type-mismatch): New.
+ * engine.cc (impl_region_model_context::get_state_map_by_name):
+ Add "out_sm_context" param. Allow out_sm_idx to be NULL.
+ * exploded-graph.h
+ (impl_region_model_context::get_state_map_by_name):
+ Add "out_sm_context" param.
+ * region-model-impl-calls.cc (region_model::impl_call_accept): New.
+ (region_model::impl_call_bind): New.
+ (region_model::impl_call_connect): New.
+ (region_model::impl_call_listen): New.
+ (region_model::impl_call_socket): New.
+ * region-model.cc (region_model::on_call_pre): Special-case
+ "bind".
+ (region_model::on_call_post): Special-case "accept", "bind",
+ "connect", "listen", and "socket".
+ * region-model.h (region_model::impl_call_accept): New decl.
+ (region_model::impl_call_bind): New decl.
+ (region_model::impl_call_connect): New decl.
+ (region_model::impl_call_listen): New decl.
+ (region_model::impl_call_socket): New decl.
+ (region_model::on_socket): New decl.
+ (region_model::on_bind): New decl.
+ (region_model::on_listen): New decl.
+ (region_model::on_accept): New decl.
+ (region_model::on_connect): New decl.
+ (region_model::add_constraint): Make public.
+ (region_model::check_for_poison): Make public.
+ (region_model_context::get_state_map_by_name): Add out_sm_context param.
+ (region_model_context::get_fd_map): Likewise.
+ (region_model_context::get_malloc_map): Likewise.
+ (region_model_context::get_taint_map): Likewise.
+ (noop_region_model_context::get_state_map_by_name): Likewise.
+ (region_model_context_decorator::get_state_map_by_name): Likewise.
+ * sm-fd.cc: Include "analyzer/supergraph.h" and
+ "analyzer/analyzer-language.h".
+ (enum expected_phase): New enum.
+ (fd_state_machine::m_new_datagram_socket): New.
+ (fd_state_machine::m_new_stream_socket): New.
+ (fd_state_machine::m_new_unknown_socket): New.
+ (fd_state_machine::m_bound_datagram_socket): New.
+ (fd_state_machine::m_bound_stream_socket): New.
+ (fd_state_machine::m_bound_unknown_socket): New.
+ (fd_state_machine::m_listening_stream_socket): New.
+ (fd_state_machine::m_m_connected_stream_socket): New.
+ (fd_state_machine::m_SOCK_STREAM): New.
+ (fd_state_machine::m_SOCK_DGRAM): New.
+ (fd_diagnostic::describe_state_change): Handle socket states.
+ (fd_diagnostic::get_meaning_for_state_change): Likewise.
+ (class fd_phase_mismatch): New.
+ (enum expected_type): New enum.
+ (class fd_type_mismatch): New.
+ (fd_state_machine::fd_state_machine): Initialize new states and
+ stashed named constants.
+ (fd_state_machine::is_socket_fd_p): New.
+ (fd_state_machine::is_datagram_socket_fd_p): New.
+ (fd_state_machine::is_stream_socket_fd_p): New.
+ (fd_state_machine::on_close): Handle the socket states.
+ (fd_state_machine::check_for_open_fd): Complain about fncalls on
+ sockets in the wrong phase. Support socket FDs.
+ (add_constraint_ge_zero): New.
+ (fd_state_machine::get_state_for_socket_type): New.
+ (fd_state_machine::on_socket): New.
+ (fd_state_machine::check_for_socket_fd): New.
+ (fd_state_machine::check_for_new_socket_fd): New.
+ (fd_state_machine::on_bind): New.
+ (fd_state_machine::on_listen): New.
+ (fd_state_machine::on_accept): New.
+ (fd_state_machine::on_connect): New.
+ (fd_state_machine::can_purge_p): Don't purge socket values.
+ (get_fd_state): New.
+ (region_model::mark_as_valid_fd): Use get_fd_state.
+ (region_model::on_socket): New.
+ (region_model::on_bind): New.
+ (region_model::on_listen): New.
+ (region_model::on_accept): New.
+ (region_model::on_connect): New.
+ * sm-fd.dot: Update to reflect sm-fd.cc changes.
+
+2022-11-15 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106302
+ * analyzer-language.cc: New file.
+ * analyzer-language.h: New file.
+ * analyzer.h (get_stashed_constant_by_name): New decl.
+ (log_stashed_constants): New decl.
+ * engine.cc (impl_run_checkers): Call log_stashed_constants.
+ * region-model-impl-calls.cc
+ (region_model::impl_call_analyzer_dump_named_constant): New.
+ * region-model.cc (region_model::on_stmt_pre): Handle
+ __analyzer_dump_named_constant.
+ * region-model.h
+ (region_model::impl_call_analyzer_dump_named_constant): New decl.
+ * sm-fd.cc (fd_state_machine::m_O_ACCMODE): New.
+ (fd_state_machine::m_O_RDONLY): New.
+ (fd_state_machine::m_O_WRONLY): New.
+ (fd_state_machine::fd_state_machine): Initialize the new fields.
+ (fd_state_machine::get_access_mode_from_flag): Use the new fields,
+ rather than using the host values.
+
+2022-11-13 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106235
+ * analyzer.opt (Wanalyzer-tainted-assertion): New.
+ * checker-path.cc (checker_path::fixup_locations): Pass false to
+ pending_diagnostic::fixup_location.
+ * diagnostic-manager.cc (get_emission_location): Pass true to
+ pending_diagnostic::fixup_location.
+ * pending-diagnostic.cc (pending_diagnostic::fixup_location): Add
+ bool param.
+ * pending-diagnostic.h (pending_diagnostic::fixup_location): Add
+ bool param to decl.
+ * sm-taint.cc (taint_state_machine::m_tainted_control_flow): New.
+ (taint_diagnostic::describe_state_change): Drop "final".
+ (class tainted_assertion): New.
+ (taint_state_machine::taint_state_machine): Initialize
+ m_tainted_control_flow.
+ (taint_state_machine::alt_get_inherited_state): Support
+ comparisons being tainted, based on their arguments.
+ (is_assertion_failure_handler_p): New.
+ (taint_state_machine::on_stmt): Complain about calls to assertion
+ failure handlers guarded by an attacker-controller conditional.
+ Detect attacker-controlled gcond conditionals and gswitch index
+ values.
+ (taint_state_machine::check_control_flow_arg_for_taint): New.
+
+2022-11-11 David Malcolm <dmalcolm@redhat.com>
+
+ * sm-fd.dot: Fix typo in comment.
+ * sm-file.dot: New file.
+ * varargs.cc: Fix typo in comment.
+ * varargs.dot: New file.
+
+2022-11-11 David Malcolm <dmalcolm@redhat.com>
+
+ * checker-path.h: Split out checker_event and its subclasses to...
+ * checker-event.h: ...this new header.
+
+2022-11-11 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106147
+ * analyzer.opt (Wanalyzer-infinite-recursion): New.
+ * call-string.cc (call_string::count_occurrences_of_function):
+ New.
+ * call-string.h (call_string::count_occurrences_of_function): New
+ decl.
+ * checker-path.cc (function_entry_event::function_entry_event):
+ New ctor.
+ (checker_path::add_final_event): Delete.
+ * checker-path.h (function_entry_event::function_entry_event): New
+ ctor.
+ (function_entry_event::get_desc): Drop "final".
+ (checker_path::add_final_event): Delete.
+ * diagnostic-manager.cc
+ (diagnostic_manager::emit_saved_diagnostic): Create the final
+ event via a new pending_diagnostic::add_final_event vfunc, rather
+ than checker_path::add_final_event.
+ (diagnostic_manager::add_events_for_eedge): Create function entry
+ events via a new pending_diagnostic::add_function_entry_event
+ vfunc.
+ * engine.cc (exploded_graph::process_node): When creating a new
+ PK_BEFORE_SUPERNODE node, call
+ exploded_graph::detect_infinite_recursion on it after adding the
+ in-edge.
+ * exploded-graph.h (exploded_graph::detect_infinite_recursion):
+ New decl.
+ (exploded_graph::find_previous_entry_to): New decl.
+ * infinite-recursion.cc: New file.
+ * pending-diagnostic.cc
+ (pending_diagnostic::add_function_entry_event): New.
+ (pending_diagnostic::add_final_event): New.
+ * pending-diagnostic.h
+ (pending_diagnostic::add_function_entry_event): New vfunc.
+ (pending_diagnostic::add_final_event): New vfunc.
+
+2022-11-10 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/99671
+ * analyzer.opt (Wanalyzer-deref-before-check): New warning.
+ * diagnostic-manager.cc
+ (null_assignment_sm_context::set_next_state): Only add state
+ change events for transition to "null" state.
+ (null_assignment_sm_context::is_transition_to_null): New.
+ * engine.cc (impl_region_model_context::on_pop_frame): New.
+ * exploded-graph.h (impl_region_model_context::on_pop_frame): New
+ decl.
+ * program-state.cc (sm_state_map::clear_any_state): New.
+ (sm_state_map::can_merge_with_p): New.
+ (program_state::can_merge_with_p): Replace requirement that
+ sm-states be equal in favor of an attempt to merge them.
+ * program-state.h (sm_state_map::clear_any_state): New decl.
+ (sm_state_map::can_merge_with_p): New decl.
+ * region-model.cc (region_model::eval_condition): Make const.
+ (region_model::pop_frame): Call ctxt->on_pop_frame.
+ * region-model.h (region_model::eval_condition): Make const.
+ (region_model_context::on_pop_frame): New vfunc.
+ (noop_region_model_context::on_pop_frame): New.
+ (region_model_context_decorator::on_pop_frame): New.
+ * sm-malloc.cc (enum resource_state): Add RS_ASSUMED_NON_NULL.
+ (allocation_state::dump_to_pp): Drop "final".
+ (struct assumed_non_null_state): New subclass.
+ (malloc_state_machine::m_assumed_non_null): New.
+ (assumed_non_null_p): New.
+ (class deref_before_check): New.
+ (assumed_non_null_state::dump_to_pp): New.
+ (malloc_state_machine::get_or_create_assumed_non_null_state_for_frame):
+ New.
+ (malloc_state_machine::maybe_assume_non_null): New.
+ (malloc_state_machine::on_stmt): Transition from start state to
+ "assumed-non-null" state for pointers passed to
+ __attribute__((nonnull)) arguments, and for pointers explicitly
+ dereferenced. Call maybe_complain_about_deref_before_check for
+ pointers explicitly compared against NULL.
+ (malloc_state_machine::maybe_complain_about_deref_before_check):
+ New.
+ (malloc_state_machine::on_deallocator_call): Also transition
+ "assumed-non-null" states to "freed".
+ (malloc_state_machine::on_pop_frame): New.
+ (malloc_state_machine::maybe_get_merged_states_nonequal): New.
+ * sm-malloc.dot: Update for changes to sm-malloc.cc.
+ * sm.h (state_machine::on_pop_frame): New.
+ (state_machine::maybe_get_merged_state): New.
+ (state_machine::maybe_get_merged_states_nonequal): New.
+
+2022-11-09 David Malcolm <dmalcolm@redhat.com>
+
+ * checker-path.cc (checker_event::debug): New.
+ (checker_path::add_event): Move here from checker-path.h. Add
+ logging.
+ * checker-path.h (checker_event::debug): New decl.
+ (checker_path::checker_path): Add logger param.
+ (checker_path::add_event): Move definition from here to
+ checker-path.cc.
+ (checker_path::m_logger): New field.
+ * diagnostic-manager.cc
+ (diagnostic_manager::emit_saved_diagnostic): Pass logger to
+ checker_path ctor.
+ (diagnostic_manager::add_events_for_eedge): Log scope when
+ processing a run of stmts.
+
+2022-11-08 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/101962
+ * region-model-impl-calls.cc: Update comment.
+ * region-model.cc (region_model::check_symbolic_bounds): Fix
+ layout of "void" return. Replace usage of
+ eval_condition_without_cm with eval_condition.
+ (region_model::eval_condition): Take over body of...
+ (region_model::eval_condition_without_cm): ...this subroutine,
+ dropping the latter. Eliminating this distinction avoids issues
+ where constraints were not considered when recursing.
+ (region_model::compare_initial_and_pointer): Update comment.
+ (region_model::symbolic_greater_than): Replace usage of
+ eval_condition_without_cm with eval_condition.
+ * region-model.h
+ (region_model::eval_condition_without_cm): Delete decl.
+
+2022-11-08 David Malcolm <dmalcolm@redhat.com>
+
+ * region-model-impl-calls.cc
+ (region_model::impl_call_errno_location): New.
+ * region-model-manager.cc
+ (region_model_manager::region_model_manager): Initialize
+ m_thread_local_region and m_errno_region.
+ * region-model-manager.h (region_model_manager::get_errno_region):
+ New accessor.
+ (region_model_manager::m_thread_local_region): New.
+ (region_model_manager::m_errno_region): New.
+ * region-model.cc (region_model::on_call_pre): Special-case
+ "__errno_location".
+ (region_model::set_errno): New.
+ * region-model.h (impl_call_errno_location): New decl.
+ (region_model::set_errno): New decl.
+ * region.cc (thread_local_region::dump_to_pp): New.
+ (errno_region::dump_to_pp): New.
+ * region.h (enum memory_space): Add MEMSPACE_THREAD_LOCAL.
+ (enum region_kind): Add RK_THREAD_LOCAL and RK_ERRNO.
+ (class thread_local_region): New.
+ (is_a_helper <const thread_local_region *>::test): New.
+ (class errno_region): New.
+ (is_a_helper <const errno_region *>::test): New.
+ * store.cc (binding_cluster::escaped_p): New.
+ (store::escaped_p): Treat errno as always having escaped.
+ (store::replay_call_summary_cluster): Handle RK_THREAD_LOCAL and
+ RK_ERRNO.
+ * store.h (binding_cluster::escaped_p): Remove definition.
+
+2022-11-08 David Malcolm <dmalcolm@redhat.com>
+
+ * call-info.cc (success_call_info::get_desc): Delete.
+ (failed_call_info::get_desc): Likewise.
+ (succeed_or_fail_call_info::get_desc): New.
+ * call-info.h (class succeed_or_fail_call_info): New.
+ (class success_call_info): Convert to a subclass of
+ succeed_or_fail_call_info.
+ (class failed_call_info): Likewise.
+
+2022-11-08 David Malcolm <dmalcolm@redhat.com>
+
+ * region-model-impl-calls.cc (region_model::impl_call_strchr):
+ Move to on_call_post. Handle both outcomes using bifurcation,
+ rather than just the "not found" case.
+ * region-model.cc (region_model::on_call_pre): Move
+ BUILT_IN_STRCHR and "strchr" to...
+ (region_model::on_call_post): ...here.
+
+2022-11-03 David Malcolm <dmalcolm@redhat.com>
+
+ * analyzer.h: Use std::unique_ptr for state machines from plugins.
+ * engine.cc: Likewise.
+
+2022-11-03 David Malcolm <dmalcolm@redhat.com>
+
+ * analyzer.h: Use std::unique_ptr for known functions.
+ * engine.cc: Likewise.
+ * known-function-manager.cc: Likewise.
+ * known-function-manager.h: Likewise.
+
+2022-11-03 David Malcolm <dmalcolm@redhat.com>
+
+ * analysis-plan.cc: Define INCLUDE_MEMORY before including
+ system.h.
+ * analyzer-pass.cc: Likewise.
+ * analyzer-selftests.cc: Likewise.
+ * analyzer.cc: Likewise.
+ * analyzer.h: Use std::unique_ptr in bifurcation code.
+ * call-string.cc: Define INCLUDE_MEMORY before including system.h.
+ * complexity.cc: Likewise.
+ * engine.cc: Use std::unique_ptr in bifurcation code.
+ * exploded-graph.h: Likewise.
+ * known-function-manager.cc: Define INCLUDE_MEMORY before
+ including system.h.
+ * region-model-impl-calls.cc: Use std::unique_ptr in bifurcation
+ code.
+ * region-model.cc: Likewise.
+ * region-model.h: Likewise.
+ * supergraph.cc: Define INCLUDE_MEMORY before including system.h.
+
+2022-11-03 David Malcolm <dmalcolm@redhat.com>
+
+ * call-info.cc: Use std::unique_ptr for checker_event.
+ * checker-path.cc: Likewise.
+ * checker-path.h: Likewise.
+ * diagnostic-manager.cc: Likewise.
+ * engine.cc: Likewise.
+ * pending-diagnostic.cc: Likewise.
+ * sm-signal.cc: Likewise.
+ * varargs.cc: Likewise.
+
+2022-11-03 David Malcolm <dmalcolm@redhat.com>
+
+ * diagnostic-manager.cc: Include "make-unique.h".
+ Use std::unique_ptr for feasibility_problems and exploded_path.
+ Delete explicit saved_diagnostic dtor.
+ * diagnostic-manager.h: Likewise.
+ * engine.cc: Likewise.
+ * exploded-graph.h: Likewise.
+ * feasible-graph.cc: Likewise.
+ * feasible-graph.h: Likewise.
+
+2022-11-03 David Malcolm <dmalcolm@redhat.com>
+
+ * checker-path.cc (rewind_event::rewind_event): Update for usage of
+ std::unique_ptr on custom_edge_info.
+ * engine.cc (exploded_node::on_longjmp): Likewise.
+ (exploded_edge::exploded_edge): Likewise.
+ (exploded_edge::~exploded_edge): Delete.
+ (exploded_graph::add_function_entry): Update for usage of
+ std::unique_ptr on custom_edge_info.
+ (exploded_graph::add_edge): Likewise.
+ (add_tainted_args_callback): Likewise.
+ (exploded_graph::maybe_create_dynamic_call): Likewise.
+ (exploded_graph::process_node): Likewise.
+ * exploded-graph.h (exploded_edge::~exploded_edge): Delete.
+ (exploded_edge::m_custom_info): Use std::unique_ptr.
+ (exploded_edge::add_edge): Likewise.
+ * sm-signal.cc (register_signal_handler::impl_transition): Use
+ make_unique.
+
+2022-11-03 David Malcolm <dmalcolm@redhat.com>
+
+ * diagnostic-manager.cc (saved_diagnostic::saved_diagnostic): Make
+ stmt_finder const.
+ (saved_diagnostic::~saved_diagnostic): Remove explicit delete of
+ m_stmt_finder.
+ (diagnostic_manager::add_diagnostic): Make stmt_finder const.
+ * diagnostic-manager.h (saved_diagnostic::saved_diagnostic):
+ Likewise.
+ (saved_diagnostic::m_stmt_finder): Convert to std::unique_ptr.
+ (diagnostic_manager::add_diagnostic): Make stmt_finder const.
+ * engine.cc (impl_sm_context::impl_sm_context): Likewise.
+ (impl_sm_context::m_stmt_finder): Likewise.
+ (leak_stmt_finder::clone): Convert return type to std::unique_ptr.
+ * exploded-graph.h (stmt_finder::clone): Likewise.
+
+2022-11-03 David Malcolm <dmalcolm@redhat.com>
+
+ * call-info.cc: Add define of INCLUDE_MEMORY.
+ * call-summary.cc: Likewise.
+ * checker-path.cc: Likewise.
+ * constraint-manager.cc: Likewise.
+ * diagnostic-manager.cc: Likewise.
+ (saved_diagnostic::saved_diagnostic): Use std::unique_ptr for
+ param d and field m_d.
+ (saved_diagnostic::~saved_diagnostic): Remove explicit delete of m_d.
+ (saved_diagnostic::add_note): Use std::unique_ptr for
+ param pn.
+ (saved_diagnostic::get_pending_diagnostic): Update for conversion
+ of m_sd.m_d to unique_ptr.
+ (diagnostic_manager::add_diagnostic): Use std::unique_ptr for
+ param d. Remove explicit deletion.
+ (diagnostic_manager::add_note): Use std::unique_ptr for param pn.
+ (diagnostic_manager::emit_saved_diagnostic): Update for conversion
+ of m_sd.m_d to unique_ptr.
+ (null_assignment_sm_context::warn): Use std::unique_ptr for
+ param d. Remove explicit deletion.
+ * diagnostic-manager.h (saved_diagnostic::saved_diagnostic): Use
+ std::unique_ptr for param d.
+ (saved_diagnostic::add_note): Likewise for param pn.
+ (saved_diagnostic::m_d): Likewise.
+ (diagnostic_manager::add_diagnostic): Use std::unique_ptr for
+ param d.
+ (diagnostic_manager::add_note): Use std::unique_ptr for param pn.
+ * engine.cc: Include "make-unique.h".
+ (impl_region_model_context::warn): Update to use std::unique_ptr
+ for param, removing explicit deletion.
+ (impl_region_model_context::add_note): Likewise.
+ (impl_sm_context::warn): Update to use std::unique_ptr
+ for param.
+ (impl_region_model_context::on_state_leak): Likewise for result of
+ on_leak.
+ (exploded_node::on_longjmp): Use make_unique when creating
+ pending_diagnostic.
+ (exploded_graph::process_node): Likewise.
+ * exploded-graph.h (impl_region_model_context::warn): Update to
+ use std::unique_ptr for param.
+ (impl_region_model_context::add_note): Likewise.
+ * feasible-graph.cc: Add define of INCLUDE_MEMORY.
+ * pending-diagnostic.cc: Likewise.
+ * pending-diagnostic.h: Include analyzer.sm.h"
+ * program-point.cc: Add define of INCLUDE_MEMORY.
+ * program-state.cc: Likewise.
+ * region-model-asm.cc: Likewise.
+ * region-model-impl-calls.cc: Likewise. Include "make-unique.h".
+ (region_model::impl_call_putenv): Use make_unique when creating
+ pending_diagnostic.
+ * region-model-manager.cc: Add define of INCLUDE_MEMORY.
+ * region-model-reachability.cc: Likewise.
+ * region-model.cc: Likewise. Include "make-unique.h".
+ (region_model::get_gassign_result): Use make_unique when creating
+ pending_diagnostic.
+ (region_model::check_for_poison): Likewise.
+ (region_model::on_stmt_pre): Likewise.
+ (region_model::check_symbolic_bounds): Likewise.
+ (region_model::check_region_bounds): Likewise.
+ (annotating_ctxt: make_note): Use std::unique_ptr for result.
+ (region_model::deref_rvalue): Use make_unique when creating
+ pending_diagnostic.
+ (region_model::check_for_writable_region): Likewise.
+ (region_model::check_region_size): Likewise.
+ (region_model::check_dynamic_size_for_floats): Likewise.
+ (region_model::maybe_complain_about_infoleak): Likewise.
+ (noop_region_model_context::add_note): Use std::unique_ptr for
+ param. Remove explicit deletion.
+ * region-model.h: Include "analyzer/pending-diagnostic.h".
+ (region_model_context::warn): Convert param to std::unique_ptr.
+ (region_model_context::add_note): Likewise.
+ (noop_region_model_context::warn): Likewise.
+ (noop_region_model_context::add_note): Likewise.
+ (region_model_context_decorator::warn): Likewise.
+ (region_model_context_decorator::add_note): Likewise.
+ (note_adding_context::warn): Likewise.
+ (note_adding_context::make_note): Likewise for return type.
+ (test_region_model_context::warn): Convert param to
+ std::unique_ptr.
+ * region.cc: Add define of INCLUDE_MEMORY.
+ * sm-fd.cc: Likewise. Include "make-unique.h".
+ (fd_state_machine::check_for_fd_attrs): Use make_unique when
+ creating pending_diagnostics.
+ (fd_state_machine::on_open): Likewise.
+ (fd_state_machine::on_creat): Likewise.
+ (fd_state_machine::check_for_dup): Likewise.
+ (fd_state_machine::on_close): Likewise.
+ (fd_state_machine::check_for_open_fd): Likewise.
+ (fd_state_machine::on_leak): Likewise, converting return type to
+ std::unique_ptr.
+ * sm-file.cc: Add define of INCLUDE_MEMORY. Include
+ "make-unique.h".
+ (fileptr_state_machine::on_stmt): Use make_unique when creating
+ pending_diagnostic.
+ (fileptr_state_machine::on_leak): Likewise, converting return type
+ to std::unique_ptr.
+ * sm-malloc.cc: Add define of INCLUDE_MEMORY. Include
+ "make-unique.h".
+ (malloc_state_machine::on_stmt): Use make_unique when creating
+ pending_diagnostic.
+ (malloc_state_machine::handle_free_of_non_heap): Likewise.
+ (malloc_state_machine::on_deallocator_call): Likewise.
+ (malloc_state_machine::on_realloc_call): Likewise.
+ (malloc_state_machine::on_leak): Likewise, converting return type
+ to std::unique_ptr.
+ * sm-pattern-test.cc: Add define of INCLUDE_MEMORY. Include
+ "make-unique.h".
+ (pattern_test_state_machine::on_condition): Use make_unique when
+ creating pending_diagnostic.
+ * sm-sensitive.cc: Add define of INCLUDE_MEMORY. Include
+ "make-unique.h".
+ (sensitive_state_machine::warn_for_any_exposure): Use make_unique
+ when creating pending_diagnostic.
+ * sm-signal.cc: Add define of INCLUDE_MEMORY. Include
+ "make-unique.h".
+ (signal_state_machine::on_stmt): Use make_unique when creating
+ pending_diagnostic.
+ * sm-taint.cc: Add define of INCLUDE_MEMORY. Include
+ "make-unique.h".
+ (taint_state_machine::check_for_tainted_size_arg): Use make_unique
+ when creating pending_diagnostic.
+ (taint_state_machine::check_for_tainted_divisor): Likewise.
+ (region_model::check_region_for_taint): Likewise.
+ (region_model::check_dynamic_size_for_taint): Likewise.
+ * sm.cc: Add define of INCLUDE_MEMORY. Include
+ "analyzer/pending-diagnostic.h".
+ (state_machine::on_leak): Move here from sm.h, changing return
+ type to std::unique_ptr.
+ * sm.h (state_machine::on_leak): Change return type to
+ std::unique_ptr. Move defn of base impl to sm.cc
+ (sm_context::warn): Convert param d to std_unique_ptr.
+ * state-purge.cc: Add define of INCLUDE_MEMORY.
+ * store.cc: Likewise.
+ * svalue.cc: Likewise.
+ * trimmed-graph.cc: Likewise.
+ * varargs.cc: Likewise. Include "make-unique.h".
+ (va_list_state_machine::check_for_ended_va_list): Use make_unique
+ when creating pending_diagnostic.
+ (va_list_state_machine::on_leak): Likewise, converting return type
+ to std::unique_ptr.
+ (region_model::impl_call_va_arg): Use make_unique when creating
+ pending_diagnostic.
+
+2022-11-03 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107486
+ * analyzer.cc (is_pipe_call_p): New.
+ * analyzer.h (is_pipe_call_p): New decl.
+ * region-model.cc (region_model::on_call_pre): Use it.
+ (region_model::on_call_post): Likewise.
+
2022-10-26 David Malcolm <dmalcolm@redhat.com>
* sm-fd.cc (fd_state_machine::on_open): Transition to "unchecked"
@@ -181,7 +1549,7 @@
2022-10-05 Martin Liska <mliska@suse.cz>
* call-summary.cc (call_summary_replay::call_summary_replay):
- Remove unused variable and arguments.
+ Remove unused variable and arguments.
* call-summary.h: Likewise.
* engine.cc (exploded_node::on_stmt): Likewise.
(exploded_node::replay_call_summaries): Likewise.
@@ -298,7 +1666,7 @@
2022-09-12 Martin Liska <mliska@suse.cz>
* region-model.cc (region_model::maybe_complain_about_infoleak):
- Remove unused fields.
+ Remove unused fields.
2022-09-11 Tim Lange <mail@tim-lange.me>
@@ -472,7 +1840,7 @@
2022-08-16 Martin Liska <mliska@suse.cz>
* region-model.cc: Fix -Winconsistent-missing-override clang
- warning.
+ warning.
* region.h: Likewise.
2022-08-15 David Malcolm <dmalcolm@redhat.com>
diff --git a/gcc/analyzer/analysis-plan.cc b/gcc/analyzer/analysis-plan.cc
index a4a42c5..aa75bd6 100644
--- a/gcc/analyzer/analysis-plan.cc
+++ b/gcc/analyzer/analysis-plan.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
diff --git a/gcc/analyzer/analyzer-language.cc b/gcc/analyzer/analyzer-language.cc
new file mode 100644
index 0000000..0fb4344
--- /dev/null
+++ b/gcc/analyzer/analyzer-language.cc
@@ -0,0 +1,140 @@
+/* Interface between analyzer and frontends.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#define INCLUDE_MEMORY
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "analyzer/analyzer.h"
+#include "analyzer/analyzer-language.h"
+#include "analyzer/analyzer-logging.h"
+#include "diagnostic.h"
+
+/* Map from identifier to INTEGER_CST. */
+static GTY (()) hash_map <tree, tree> *analyzer_stashed_constants;
+
+#if ENABLE_ANALYZER
+
+namespace ana {
+
+/* Call into TU to try to find a value for NAME.
+ If found, stash its value within analyzer_stashed_constants. */
+
+static void
+maybe_stash_named_constant (logger *logger,
+ const translation_unit &tu,
+ const char *name)
+{
+ LOG_FUNC_1 (logger, "name: %qs", name);
+
+ if (!analyzer_stashed_constants)
+ analyzer_stashed_constants = hash_map<tree, tree>::create_ggc ();
+
+ tree id = get_identifier (name);
+ if (tree t = tu.lookup_constant_by_id (id))
+ {
+ gcc_assert (TREE_CODE (t) == INTEGER_CST);
+ analyzer_stashed_constants->put (id, t);
+ if (logger)
+ logger->log ("%qs: %qE", name, t);
+ }
+ else
+ {
+ if (logger)
+ logger->log ("%qs: not found", name);
+ }
+}
+
+/* Call into TU to try to find values for the names we care about.
+ If found, stash their values within analyzer_stashed_constants. */
+
+static void
+stash_named_constants (logger *logger, const translation_unit &tu)
+{
+ LOG_SCOPE (logger);
+
+ /* Stash named constants for use by sm-fd.cc */
+ maybe_stash_named_constant (logger, tu, "O_ACCMODE");
+ maybe_stash_named_constant (logger, tu, "O_RDONLY");
+ maybe_stash_named_constant (logger, tu, "O_WRONLY");
+ maybe_stash_named_constant (logger, tu, "SOCK_STREAM");
+ maybe_stash_named_constant (logger, tu, "SOCK_DGRAM");
+}
+
+/* Hook for frontend to call into analyzer when TU finishes.
+ This exists so that the analyzer can stash named constant values from
+ header files (e.g. macros and enums) for later use when modeling the
+ behaviors of APIs.
+
+ By doing it this way, the analyzer can use the precise values for those
+ constants from the user's headers, rather than attempting to model them
+ as properties of the target. */
+
+void
+on_finish_translation_unit (const translation_unit &tu)
+{
+ /* Bail if the analyzer isn't enabled. */
+ if (!flag_analyzer)
+ return;
+
+ FILE *logfile = get_or_create_any_logfile ();
+ log_user the_logger (NULL);
+ if (logfile)
+ the_logger.set_logger (new logger (logfile, 0, 0,
+ *global_dc->printer));
+ stash_named_constants (the_logger.get_logger (), tu);
+}
+
+/* Lookup NAME in the named constants stashed when the frontend TU finished.
+ Return either an INTEGER_CST, or NULL_TREE. */
+
+tree
+get_stashed_constant_by_name (const char *name)
+{
+ if (!analyzer_stashed_constants)
+ return NULL_TREE;
+ tree id = get_identifier (name);
+ if (tree *slot = analyzer_stashed_constants->get (id))
+ {
+ gcc_assert (TREE_CODE (*slot) == INTEGER_CST);
+ return *slot;
+ }
+ return NULL_TREE;
+}
+
+/* Log all stashed named constants to LOGGER. */
+
+void
+log_stashed_constants (logger *logger)
+{
+ gcc_assert (logger);
+ LOG_SCOPE (logger);
+ if (analyzer_stashed_constants)
+ for (auto iter : *analyzer_stashed_constants)
+ logger->log ("%qE: %qE", iter.first, iter.second);
+}
+
+} // namespace ana
+
+#endif /* #if ENABLE_ANALYZER */
+
+#include "gt-analyzer-language.h"
diff --git a/gcc/analyzer/analyzer-language.h b/gcc/analyzer/analyzer-language.h
new file mode 100644
index 0000000..33c4dd6
--- /dev/null
+++ b/gcc/analyzer/analyzer-language.h
@@ -0,0 +1,48 @@
+/* Interface between analyzer and frontends.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_ANALYZER_LANGUAGE_H
+#define GCC_ANALYZER_LANGUAGE_H
+
+#if ENABLE_ANALYZER
+
+namespace ana {
+
+/* Abstract base class for representing a specific TU
+ to the analyzer. */
+
+class translation_unit
+{
+ public:
+ /* Attempt to look up an value for identifier ID (e.g. in the headers that
+ have been seen). If it is defined and an integer (e.g. either as a
+ macro or enum), return the INTEGER_CST value, otherwise return NULL. */
+ virtual tree lookup_constant_by_id (tree id) const = 0;
+};
+
+/* Analyzer hook for frontends to call at the end of the TU. */
+
+void on_finish_translation_unit (const translation_unit &tu);
+
+} // namespace ana
+
+#endif /* #if ENABLE_ANALYZER */
+
+#endif /* GCC_ANALYZER_LANGUAGE_H */
diff --git a/gcc/analyzer/analyzer-pass.cc b/gcc/analyzer/analyzer-pass.cc
index fc7098d..423595f 100644
--- a/gcc/analyzer/analyzer-pass.cc
+++ b/gcc/analyzer/analyzer-pass.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "context.h"
diff --git a/gcc/analyzer/analyzer-selftests.cc b/gcc/analyzer/analyzer-selftests.cc
index 278c245..028cc5e 100644
--- a/gcc/analyzer/analyzer-selftests.cc
+++ b/gcc/analyzer/analyzer-selftests.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
diff --git a/gcc/analyzer/analyzer.cc b/gcc/analyzer/analyzer.cc
index 8a2a773..77d622d 100644
--- a/gcc/analyzer/analyzer.cc
+++ b/gcc/analyzer/analyzer.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
@@ -448,7 +449,7 @@ make_label_text (bool can_colorize, const char *fmt, ...)
/* As above, but with singular vs plural. */
label_text
-make_label_text_n (bool can_colorize, int n,
+make_label_text_n (bool can_colorize, unsigned HOST_WIDE_INT n,
const char *singular_fmt,
const char *plural_fmt, ...)
{
diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index a2d79e4..19e5b90 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -92,6 +92,7 @@ class bounded_ranges_manager;
class pending_diagnostic;
class pending_note;
+struct event_loc_info;
class state_change_event;
class checker_path;
class extrinsic_state;
@@ -228,23 +229,51 @@ extern location_t get_stmt_location (const gimple *stmt, function *fun);
extern bool compat_types_p (tree src_type, tree dst_type);
/* Abstract base class for simulating the behavior of known functions,
- supplied by plugins. */
+ supplied by the core of the analyzer, or by plugins.
+ The former are typically implemented in the various kf*.cc */
class known_function
{
public:
virtual ~known_function () {}
- virtual void impl_call_pre (const call_details &cd) const = 0;
+ virtual bool matches_call_types_p (const call_details &cd) const = 0;
+ virtual void impl_call_pre (const call_details &) const
+ {
+ return;
+ }
+ virtual void impl_call_post (const call_details &) const
+ {
+ return;
+ }
+};
+
+/* Subclass of known_function for IFN_* functions. */
+
+class internal_known_function : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &) const final override
+ {
+ /* Types are assumed to be correct. */
+ return true;
+ }
};
+extern void register_known_functions (known_function_manager &mgr);
+extern void register_known_analyzer_functions (known_function_manager &kfm);
+extern void register_known_fd_functions (known_function_manager &kfm);
+extern void register_known_file_functions (known_function_manager &kfm);
+extern void register_known_functions_lang_cp (known_function_manager &kfm);
+extern void register_varargs_builtins (known_function_manager &kfm);
+
/* Passed by pointer to PLUGIN_ANALYZER_INIT callbacks. */
class plugin_analyzer_init_iface
{
public:
- virtual void register_state_machine (state_machine *) = 0;
+ virtual void register_state_machine (std::unique_ptr<state_machine>) = 0;
virtual void register_known_function (const char *name,
- known_function *) = 0;
+ std::unique_ptr<known_function>) = 0;
virtual logger *get_logger () const = 0;
};
@@ -300,9 +329,8 @@ class path_context
public:
virtual ~path_context () {}
- /* Hook for clients to split state with a non-standard path.
- Take ownership of INFO. */
- virtual void bifurcate (custom_edge_info *info) = 0;
+ /* Hook for clients to split state with a non-standard path. */
+ virtual void bifurcate (std::unique_ptr<custom_edge_info> info) = 0;
/* Hook for clients to terminate the standard path. */
virtual void terminate_path () = 0;
@@ -312,6 +340,11 @@ public:
virtual bool terminate_path_p () const = 0;
};
+extern tree get_stashed_constant_by_name (const char *name);
+extern void log_stashed_constants (logger *logger);
+
+extern FILE *get_or_create_any_logfile ();
+
} // namespace ana
extern bool is_special_named_call_p (const gcall *call, const char *funcname,
@@ -330,7 +363,8 @@ extern const char *get_user_facing_name (const gcall *call);
extern void register_analyzer_pass ();
extern label_text make_label_text (bool can_colorize, const char *fmt, ...);
-extern label_text make_label_text_n (bool can_colorize, int n,
+extern label_text make_label_text_n (bool can_colorize,
+ unsigned HOST_WIDE_INT n,
const char *singular_fmt,
const char *plural_fmt, ...);
diff --git a/gcc/analyzer/analyzer.opt b/gcc/analyzer/analyzer.opt
index dbab3b8..c4e7906 100644
--- a/gcc/analyzer/analyzer.opt
+++ b/gcc/analyzer/analyzer.opt
@@ -58,6 +58,10 @@ Wanalyzer-allocation-size
Common Var(warn_analyzer_allocation_size) Init(1) Warning
Warn about code paths in which a pointer to a buffer is assigned to an incompatible type.
+Wanalyzer-deref-before-check
+Common Var(warn_analyzer_deref_before_check) Init(1) Warning
+Warn about code paths in which a pointer is checked for NULL after it has already been dereferenced.
+
Wanalyzer-double-fclose
Common Var(warn_analyzer_double_fclose) Init(1) Warning
Warn about code paths in which a stdio FILE can be closed more than once.
@@ -86,6 +90,14 @@ Wanalyzer-fd-leak
Common Var(warn_analyzer_fd_leak) Init(1) Warning
Warn about code paths in which a file descriptor is not closed.
+Wanalyzer-fd-phase-mismatch
+Common Var(warn_analyzer_fd_phase_mismatch) Init(1) Warning
+Warn about code paths in which an operation is attempted in the wrong phase of a file descriptor's lifetime.
+
+Wanalyzer-fd-type-mismatch
+Common Var(warn_analyzer_fd_type_mismatch) Init(1) Warning
+Warn about code paths in which an operation is attempted on the wrong type of file descriptor.
+
Wanalyzer-fd-use-after-close
Common Var(warn_analyzer_fd_use_after_close) Init(1) Warning
Warn about code paths in which a read or write is performed on a closed file descriptor.
@@ -106,6 +118,10 @@ Wanalyzer-imprecise-fp-arithmetic
Common Var(warn_analyzer_imprecise_fp_arithmetic) Init(1) Warning
Warn about code paths in which floating-point arithmetic is used in locations where precise computation is needed.
+Wanalyzer-infinite-recursion
+Common Var(warn_analyzer_infinite_recursion) Init(1) Warning
+Warn about code paths which appear to lead to infinite recursion.
+
Wanalyzer-jump-through-null
Common Var(warn_analyzer_jump_through_null) Init(1) Warning
Warn about code paths in which a NULL function pointer is called.
@@ -166,6 +182,10 @@ Wanalyzer-tainted-array-index
Common Var(warn_analyzer_tainted_array_index) Init(1) Warning
Warn about code paths in which an unsanitized value is used as an array index.
+Wanalyzer-tainted-assertion
+Common Var(warn_analyzer_tainted_assertion) Init(1) Warning
+Warn about code paths in which an 'assert()' is made involving an unsanitized value.
+
Wanalyzer-tainted-divisor
Common Var(warn_analyzer_tainted_divisor) Init(1) Warning
Warn about code paths in which an unsanitized value is used as a divisor.
diff --git a/gcc/analyzer/bounds-checking.cc b/gcc/analyzer/bounds-checking.cc
new file mode 100644
index 0000000..4b43c43
--- /dev/null
+++ b/gcc/analyzer/bounds-checking.cc
@@ -0,0 +1,943 @@
+/* Bounds-checking of reads and writes to memory regions.
+ Copyright (C) 2019-2022 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#define INCLUDE_MEMORY
+#include "system.h"
+#include "coretypes.h"
+#include "make-unique.h"
+#include "tree.h"
+#include "function.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "diagnostic-core.h"
+#include "diagnostic-metadata.h"
+#include "analyzer/analyzer.h"
+#include "analyzer/analyzer-logging.h"
+#include "analyzer/region-model.h"
+#include "analyzer/checker-event.h"
+#include "analyzer/checker-path.h"
+
+#if ENABLE_ANALYZER
+
+namespace ana {
+
+/* Abstract base class for all out-of-bounds warnings. */
+
+class out_of_bounds : public pending_diagnostic
+{
+public:
+ out_of_bounds (const region *reg, tree diag_arg)
+ : m_reg (reg), m_diag_arg (diag_arg)
+ {}
+
+ bool subclass_equal_p (const pending_diagnostic &base_other) const override
+ {
+ const out_of_bounds &other
+ (static_cast <const out_of_bounds &>(base_other));
+ return (m_reg == other.m_reg
+ && pending_diagnostic::same_tree_p (m_diag_arg, other.m_diag_arg));
+ }
+
+ int get_controlling_option () const final override
+ {
+ return OPT_Wanalyzer_out_of_bounds;
+ }
+
+ void mark_interesting_stuff (interesting_t *interest) final override
+ {
+ interest->add_region_creation (m_reg);
+ }
+
+ void add_region_creation_events (const region *,
+ tree capacity,
+ const event_loc_info &loc_info,
+ checker_path &emission_path) override
+ {
+ /* The memory space is described in the diagnostic message itself,
+ so we don't need an event for that. */
+ if (capacity)
+ emission_path.add_event
+ (make_unique<region_creation_event_capacity> (capacity, loc_info));
+ }
+
+protected:
+ enum memory_space get_memory_space () const
+ {
+ return m_reg->get_memory_space ();
+ }
+
+ /* Potentially add a note about valid ways to index this array, such
+ as (given "int arr[10];"):
+ note: valid subscripts for 'arr' are '[0]' to '[9]'
+ We print the '[' and ']' characters so as to express the valid
+ subscripts using C syntax, rather than just as byte ranges,
+ which hopefully is more clear to the user. */
+ void
+ maybe_describe_array_bounds (location_t loc) const
+ {
+ if (!m_diag_arg)
+ return;
+ tree t = TREE_TYPE (m_diag_arg);
+ if (!t)
+ return;
+ if (TREE_CODE (t) != ARRAY_TYPE)
+ return;
+ tree domain = TYPE_DOMAIN (t);
+ if (!domain)
+ return;
+ tree max_idx = TYPE_MAX_VALUE (domain);
+ if (!max_idx)
+ return;
+ tree min_idx = TYPE_MIN_VALUE (domain);
+ inform (loc,
+ "valid subscripts for %qE are %<[%E]%> to %<[%E]%>",
+ m_diag_arg, min_idx, max_idx);
+ }
+
+ const region *m_reg;
+ tree m_diag_arg;
+};
+
+/* Abstract base class for all out-of-bounds warnings where the
+ out-of-bounds range is concrete. */
+
+class concrete_out_of_bounds : public out_of_bounds
+{
+public:
+ concrete_out_of_bounds (const region *reg, tree diag_arg,
+ byte_range out_of_bounds_range)
+ : out_of_bounds (reg, diag_arg),
+ m_out_of_bounds_range (out_of_bounds_range)
+ {}
+
+ bool subclass_equal_p (const pending_diagnostic &base_other) const override
+ {
+ const concrete_out_of_bounds &other
+ (static_cast <const concrete_out_of_bounds &>(base_other));
+ return (out_of_bounds::subclass_equal_p (other)
+ && m_out_of_bounds_range == other.m_out_of_bounds_range);
+ }
+
+protected:
+ byte_range m_out_of_bounds_range;
+};
+
+/* Abstract subclass to complaing about concrete out-of-bounds
+ past the end of the buffer. */
+
+class concrete_past_the_end : public concrete_out_of_bounds
+{
+public:
+ concrete_past_the_end (const region *reg, tree diag_arg, byte_range range,
+ tree byte_bound)
+ : concrete_out_of_bounds (reg, diag_arg, range), m_byte_bound (byte_bound)
+ {}
+
+ bool
+ subclass_equal_p (const pending_diagnostic &base_other) const final override
+ {
+ const concrete_past_the_end &other
+ (static_cast <const concrete_past_the_end &>(base_other));
+ return (concrete_out_of_bounds::subclass_equal_p (other)
+ && pending_diagnostic::same_tree_p (m_byte_bound,
+ other.m_byte_bound));
+ }
+
+ void add_region_creation_events (const region *,
+ tree,
+ const event_loc_info &loc_info,
+ checker_path &emission_path) final override
+ {
+ if (m_byte_bound && TREE_CODE (m_byte_bound) == INTEGER_CST)
+ emission_path.add_event
+ (make_unique<region_creation_event_capacity> (m_byte_bound, loc_info));
+ }
+
+protected:
+ tree m_byte_bound;
+};
+
+/* Concrete subclass to complain about buffer overflows. */
+
+class concrete_buffer_overflow : public concrete_past_the_end
+{
+public:
+ concrete_buffer_overflow (const region *reg, tree diag_arg,
+ byte_range range, tree byte_bound)
+ : concrete_past_the_end (reg, diag_arg, range, byte_bound)
+ {}
+
+ const char *get_kind () const final override
+ {
+ return "concrete_buffer_overflow";
+ }
+
+ bool emit (rich_location *rich_loc) final override
+ {
+ diagnostic_metadata m;
+ bool warned;
+ switch (get_memory_space ())
+ {
+ default:
+ m.add_cwe (787);
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "buffer overflow");
+ break;
+ case MEMSPACE_STACK:
+ m.add_cwe (121);
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "stack-based buffer overflow");
+ break;
+ case MEMSPACE_HEAP:
+ m.add_cwe (122);
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "heap-based buffer overflow");
+ break;
+ }
+
+ if (warned)
+ {
+ if (wi::fits_uhwi_p (m_out_of_bounds_range.m_size_in_bytes))
+ {
+ unsigned HOST_WIDE_INT num_bad_bytes
+ = m_out_of_bounds_range.m_size_in_bytes.to_uhwi ();
+ if (m_diag_arg)
+ inform_n (rich_loc->get_loc (),
+ num_bad_bytes,
+ "write of %wu byte to beyond the end of %qE",
+ "write of %wu bytes to beyond the end of %qE",
+ num_bad_bytes,
+ m_diag_arg);
+ else
+ inform_n (rich_loc->get_loc (),
+ num_bad_bytes,
+ "write of %wu byte to beyond the end of the region",
+ "write of %wu bytes to beyond the end of the region",
+ num_bad_bytes);
+ }
+ else if (m_diag_arg)
+ inform (rich_loc->get_loc (),
+ "write to beyond the end of %qE",
+ m_diag_arg);
+
+ maybe_describe_array_bounds (rich_loc->get_loc ());
+ }
+
+ return warned;
+ }
+
+ label_text describe_final_event (const evdesc::final_event &ev)
+ final override
+ {
+ byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
+ byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
+ char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (start, start_buf, SIGNED);
+ char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (end, end_buf, SIGNED);
+
+ if (start == end)
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds write at byte %s but %qE"
+ " ends at byte %E", start_buf, m_diag_arg,
+ m_byte_bound);
+ return ev.formatted_print ("out-of-bounds write at byte %s but region"
+ " ends at byte %E", start_buf,
+ m_byte_bound);
+ }
+ else
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds write from byte %s till"
+ " byte %s but %qE ends at byte %E",
+ start_buf, end_buf, m_diag_arg,
+ m_byte_bound);
+ return ev.formatted_print ("out-of-bounds write from byte %s till"
+ " byte %s but region ends at byte %E",
+ start_buf, end_buf, m_byte_bound);
+ }
+ }
+};
+
+/* Concrete subclass to complain about buffer over-reads. */
+
+class concrete_buffer_over_read : public concrete_past_the_end
+{
+public:
+ concrete_buffer_over_read (const region *reg, tree diag_arg,
+ byte_range range, tree byte_bound)
+ : concrete_past_the_end (reg, diag_arg, range, byte_bound)
+ {}
+
+ const char *get_kind () const final override
+ {
+ return "concrete_buffer_over_read";
+ }
+
+ bool emit (rich_location *rich_loc) final override
+ {
+ diagnostic_metadata m;
+ bool warned;
+ m.add_cwe (126);
+ switch (get_memory_space ())
+ {
+ default:
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "buffer over-read");
+ break;
+ case MEMSPACE_STACK:
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "stack-based buffer over-read");
+ break;
+ case MEMSPACE_HEAP:
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "heap-based buffer over-read");
+ break;
+ }
+
+ if (warned)
+ {
+ if (wi::fits_uhwi_p (m_out_of_bounds_range.m_size_in_bytes))
+ {
+ unsigned HOST_WIDE_INT num_bad_bytes
+ = m_out_of_bounds_range.m_size_in_bytes.to_uhwi ();
+ if (m_diag_arg)
+ inform_n (rich_loc->get_loc (),
+ num_bad_bytes,
+ "read of %wu byte from after the end of %qE",
+ "read of %wu bytes from after the end of %qE",
+ num_bad_bytes,
+ m_diag_arg);
+ else
+ inform_n (rich_loc->get_loc (),
+ num_bad_bytes,
+ "read of %wu byte from after the end of the region",
+ "read of %wu bytes from after the end of the region",
+ num_bad_bytes);
+ }
+ else if (m_diag_arg)
+ inform (rich_loc->get_loc (),
+ "read from after the end of %qE",
+ m_diag_arg);
+
+ maybe_describe_array_bounds (rich_loc->get_loc ());
+ }
+
+ return warned;
+ }
+
+ label_text describe_final_event (const evdesc::final_event &ev)
+ final override
+ {
+ byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
+ byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
+ char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (start, start_buf, SIGNED);
+ char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (end, end_buf, SIGNED);
+
+ if (start == end)
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds read at byte %s but %qE"
+ " ends at byte %E", start_buf, m_diag_arg,
+ m_byte_bound);
+ return ev.formatted_print ("out-of-bounds read at byte %s but region"
+ " ends at byte %E", start_buf,
+ m_byte_bound);
+ }
+ else
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds read from byte %s till"
+ " byte %s but %qE ends at byte %E",
+ start_buf, end_buf, m_diag_arg,
+ m_byte_bound);
+ return ev.formatted_print ("out-of-bounds read from byte %s till"
+ " byte %s but region ends at byte %E",
+ start_buf, end_buf, m_byte_bound);
+ }
+ }
+};
+
+/* Concrete subclass to complain about buffer underwrites. */
+
+class concrete_buffer_underwrite : public concrete_out_of_bounds
+{
+public:
+ concrete_buffer_underwrite (const region *reg, tree diag_arg,
+ byte_range range)
+ : concrete_out_of_bounds (reg, diag_arg, range)
+ {}
+
+ const char *get_kind () const final override
+ {
+ return "concrete_buffer_underwrite";
+ }
+
+ bool emit (rich_location *rich_loc) final override
+ {
+ diagnostic_metadata m;
+ bool warned;
+ m.add_cwe (124);
+ switch (get_memory_space ())
+ {
+ default:
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "buffer underwrite");
+ break;
+ case MEMSPACE_STACK:
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "stack-based buffer underwrite");
+ break;
+ case MEMSPACE_HEAP:
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "heap-based buffer underwrite");
+ break;
+ }
+ if (warned)
+ maybe_describe_array_bounds (rich_loc->get_loc ());
+ return warned;
+ }
+
+ label_text describe_final_event (const evdesc::final_event &ev)
+ final override
+ {
+ byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
+ byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
+ char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (start, start_buf, SIGNED);
+ char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (end, end_buf, SIGNED);
+
+ if (start == end)
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds write at byte %s but %qE"
+ " starts at byte 0", start_buf,
+ m_diag_arg);
+ return ev.formatted_print ("out-of-bounds write at byte %s but region"
+ " starts at byte 0", start_buf);
+ }
+ else
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds write from byte %s till"
+ " byte %s but %qE starts at byte 0",
+ start_buf, end_buf, m_diag_arg);
+ return ev.formatted_print ("out-of-bounds write from byte %s till"
+ " byte %s but region starts at byte 0",
+ start_buf, end_buf);;
+ }
+ }
+};
+
+/* Concrete subclass to complain about buffer under-reads. */
+
+class concrete_buffer_under_read : public concrete_out_of_bounds
+{
+public:
+ concrete_buffer_under_read (const region *reg, tree diag_arg,
+ byte_range range)
+ : concrete_out_of_bounds (reg, diag_arg, range)
+ {}
+
+ const char *get_kind () const final override
+ {
+ return "concrete_buffer_under_read";
+ }
+
+ bool emit (rich_location *rich_loc) final override
+ {
+ diagnostic_metadata m;
+ bool warned;
+ m.add_cwe (127);
+ switch (get_memory_space ())
+ {
+ default:
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "buffer under-read");
+ break;
+ case MEMSPACE_STACK:
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "stack-based buffer under-read");
+ break;
+ case MEMSPACE_HEAP:
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "heap-based buffer under-read");
+ break;
+ }
+ if (warned)
+ maybe_describe_array_bounds (rich_loc->get_loc ());
+ return warned;
+ }
+
+ label_text describe_final_event (const evdesc::final_event &ev)
+ final override
+ {
+ byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
+ byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
+ char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (start, start_buf, SIGNED);
+ char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (end, end_buf, SIGNED);
+
+ if (start == end)
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds read at byte %s but %qE"
+ " starts at byte 0", start_buf,
+ m_diag_arg);
+ return ev.formatted_print ("out-of-bounds read at byte %s but region"
+ " starts at byte 0", start_buf);
+ }
+ else
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds read from byte %s till"
+ " byte %s but %qE starts at byte 0",
+ start_buf, end_buf, m_diag_arg);
+ return ev.formatted_print ("out-of-bounds read from byte %s till"
+ " byte %s but region starts at byte 0",
+ start_buf, end_buf);;
+ }
+ }
+};
+
+/* Abstract class to complain about out-of-bounds read/writes where
+ the values are symbolic. */
+
+class symbolic_past_the_end : public out_of_bounds
+{
+public:
+ symbolic_past_the_end (const region *reg, tree diag_arg, tree offset,
+ tree num_bytes, tree capacity)
+ : out_of_bounds (reg, diag_arg),
+ m_offset (offset),
+ m_num_bytes (num_bytes),
+ m_capacity (capacity)
+ {}
+
+ bool
+ subclass_equal_p (const pending_diagnostic &base_other) const final override
+ {
+ const symbolic_past_the_end &other
+ (static_cast <const symbolic_past_the_end &>(base_other));
+ return (out_of_bounds::subclass_equal_p (other)
+ && pending_diagnostic::same_tree_p (m_offset, other.m_offset)
+ && pending_diagnostic::same_tree_p (m_num_bytes, other.m_num_bytes)
+ && pending_diagnostic::same_tree_p (m_capacity, other.m_capacity));
+ }
+
+protected:
+ tree m_offset;
+ tree m_num_bytes;
+ tree m_capacity;
+};
+
+/* Concrete subclass to complain about overflows with symbolic values. */
+
+class symbolic_buffer_overflow : public symbolic_past_the_end
+{
+public:
+ symbolic_buffer_overflow (const region *reg, tree diag_arg, tree offset,
+ tree num_bytes, tree capacity)
+ : symbolic_past_the_end (reg, diag_arg, offset, num_bytes, capacity)
+ {
+ }
+
+ const char *get_kind () const final override
+ {
+ return "symbolic_buffer_overflow";
+ }
+
+ bool emit (rich_location *rich_loc) final override
+ {
+ diagnostic_metadata m;
+ switch (get_memory_space ())
+ {
+ default:
+ m.add_cwe (787);
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "buffer overflow");
+ case MEMSPACE_STACK:
+ m.add_cwe (121);
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "stack-based buffer overflow");
+ case MEMSPACE_HEAP:
+ m.add_cwe (122);
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "heap-based buffer overflow");
+ }
+ }
+
+ label_text
+ describe_final_event (const evdesc::final_event &ev) final override
+ {
+ if (m_offset)
+ {
+ /* Known offset. */
+ if (m_num_bytes)
+ {
+ /* Known offset, known size. */
+ if (TREE_CODE (m_num_bytes) == INTEGER_CST)
+ {
+ /* Known offset, known constant size. */
+ if (pending_diagnostic::same_tree_p (m_num_bytes,
+ integer_one_node))
+ {
+ /* Singular m_num_bytes. */
+ if (m_diag_arg)
+ return ev.formatted_print
+ ("write of %E byte at offset %qE exceeds %qE",
+ m_num_bytes, m_offset, m_diag_arg);
+ else
+ return ev.formatted_print
+ ("write of %E byte at offset %qE exceeds the buffer",
+ m_num_bytes, m_offset);
+ }
+ else
+ {
+ /* Plural m_num_bytes. */
+ if (m_diag_arg)
+ return ev.formatted_print
+ ("write of %E bytes at offset %qE exceeds %qE",
+ m_num_bytes, m_offset, m_diag_arg);
+ else
+ return ev.formatted_print
+ ("write of %E bytes at offset %qE exceeds the buffer",
+ m_num_bytes, m_offset);
+ }
+ }
+ else
+ {
+ /* Known offset, known symbolic size. */
+ if (m_diag_arg)
+ return ev.formatted_print
+ ("write of %qE bytes at offset %qE exceeds %qE",
+ m_num_bytes, m_offset, m_diag_arg);
+ else
+ return ev.formatted_print
+ ("write of %qE bytes at offset %qE exceeds the buffer",
+ m_num_bytes, m_offset);
+ }
+ }
+ else
+ {
+ /* Known offset, unknown size. */
+ if (m_diag_arg)
+ return ev.formatted_print ("write at offset %qE exceeds %qE",
+ m_offset, m_diag_arg);
+ else
+ return ev.formatted_print ("write at offset %qE exceeds the"
+ " buffer", m_offset);
+ }
+ }
+ /* Unknown offset. */
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds write on %qE",
+ m_diag_arg);
+ return ev.formatted_print ("out-of-bounds write");
+ }
+};
+
+/* Concrete subclass to complain about over-reads with symbolic values. */
+
+class symbolic_buffer_over_read : public symbolic_past_the_end
+{
+public:
+ symbolic_buffer_over_read (const region *reg, tree diag_arg, tree offset,
+ tree num_bytes, tree capacity)
+ : symbolic_past_the_end (reg, diag_arg, offset, num_bytes, capacity)
+ {
+ }
+
+ const char *get_kind () const final override
+ {
+ return "symbolic_buffer_over_read";
+ }
+
+ bool emit (rich_location *rich_loc) final override
+ {
+ diagnostic_metadata m;
+ m.add_cwe (126);
+ switch (get_memory_space ())
+ {
+ default:
+ m.add_cwe (787);
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "buffer over-read");
+ case MEMSPACE_STACK:
+ m.add_cwe (121);
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "stack-based buffer over-read");
+ case MEMSPACE_HEAP:
+ m.add_cwe (122);
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "heap-based buffer over-read");
+ }
+ }
+
+ label_text
+ describe_final_event (const evdesc::final_event &ev) final override
+ {
+ if (m_offset)
+ {
+ /* Known offset. */
+ if (m_num_bytes)
+ {
+ /* Known offset, known size. */
+ if (TREE_CODE (m_num_bytes) == INTEGER_CST)
+ {
+ /* Known offset, known constant size. */
+ if (pending_diagnostic::same_tree_p (m_num_bytes,
+ integer_one_node))
+ {
+ /* Singular m_num_bytes. */
+ if (m_diag_arg)
+ return ev.formatted_print
+ ("read of %E byte at offset %qE exceeds %qE",
+ m_num_bytes, m_offset, m_diag_arg);
+ else
+ return ev.formatted_print
+ ("read of %E byte at offset %qE exceeds the buffer",
+ m_num_bytes, m_offset);
+ }
+ else
+ {
+ /* Plural m_num_bytes. */
+ if (m_diag_arg)
+ return ev.formatted_print
+ ("read of %E bytes at offset %qE exceeds %qE",
+ m_num_bytes, m_offset, m_diag_arg);
+ else
+ return ev.formatted_print
+ ("read of %E bytes at offset %qE exceeds the buffer",
+ m_num_bytes, m_offset);
+ }
+ }
+ else
+ {
+ /* Known offset, known symbolic size. */
+ if (m_diag_arg)
+ return ev.formatted_print
+ ("read of %qE bytes at offset %qE exceeds %qE",
+ m_num_bytes, m_offset, m_diag_arg);
+ else
+ return ev.formatted_print
+ ("read of %qE bytes at offset %qE exceeds the buffer",
+ m_num_bytes, m_offset);
+ }
+ }
+ else
+ {
+ /* Known offset, unknown size. */
+ if (m_diag_arg)
+ return ev.formatted_print ("read at offset %qE exceeds %qE",
+ m_offset, m_diag_arg);
+ else
+ return ev.formatted_print ("read at offset %qE exceeds the"
+ " buffer", m_offset);
+ }
+ }
+ /* Unknown offset. */
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds read on %qE",
+ m_diag_arg);
+ return ev.formatted_print ("out-of-bounds read");
+ }
+};
+
+/* Check whether an access is past the end of the BASE_REG. */
+
+void
+region_model::check_symbolic_bounds (const region *base_reg,
+ const svalue *sym_byte_offset,
+ const svalue *num_bytes_sval,
+ const svalue *capacity,
+ enum access_direction dir,
+ region_model_context *ctxt) const
+{
+ gcc_assert (ctxt);
+
+ const svalue *next_byte
+ = m_mgr->get_or_create_binop (num_bytes_sval->get_type (), PLUS_EXPR,
+ sym_byte_offset, num_bytes_sval);
+
+ if (eval_condition (next_byte, GT_EXPR, capacity).is_true ())
+ {
+ tree diag_arg = get_representative_tree (base_reg);
+ tree offset_tree = get_representative_tree (sym_byte_offset);
+ tree num_bytes_tree = get_representative_tree (num_bytes_sval);
+ tree capacity_tree = get_representative_tree (capacity);
+ switch (dir)
+ {
+ default:
+ gcc_unreachable ();
+ break;
+ case DIR_READ:
+ ctxt->warn (make_unique<symbolic_buffer_over_read> (base_reg,
+ diag_arg,
+ offset_tree,
+ num_bytes_tree,
+ capacity_tree));
+ break;
+ case DIR_WRITE:
+ ctxt->warn (make_unique<symbolic_buffer_overflow> (base_reg,
+ diag_arg,
+ offset_tree,
+ num_bytes_tree,
+ capacity_tree));
+ break;
+ }
+ }
+}
+
+static tree
+maybe_get_integer_cst_tree (const svalue *sval)
+{
+ tree cst_tree = sval->maybe_get_constant ();
+ if (cst_tree && TREE_CODE (cst_tree) == INTEGER_CST)
+ return cst_tree;
+
+ return NULL_TREE;
+}
+
+/* May complain when the access on REG is out-of-bounds. */
+
+void
+region_model::check_region_bounds (const region *reg,
+ enum access_direction dir,
+ region_model_context *ctxt) const
+{
+ gcc_assert (ctxt);
+
+ /* Get the offset. */
+ region_offset reg_offset = reg->get_offset (m_mgr);
+ const region *base_reg = reg_offset.get_base_region ();
+
+ /* Bail out on symbolic regions.
+ (e.g. because the analyzer did not see previous offsets on the latter,
+ it might think that a negative access is before the buffer). */
+ if (base_reg->symbolic_p ())
+ return;
+
+ /* Find out how many bytes were accessed. */
+ const svalue *num_bytes_sval = reg->get_byte_size_sval (m_mgr);
+ tree num_bytes_tree = maybe_get_integer_cst_tree (num_bytes_sval);
+ /* Bail out if 0 bytes are accessed. */
+ if (num_bytes_tree && zerop (num_bytes_tree))
+ return;
+
+ /* Get the capacity of the buffer. */
+ const svalue *capacity = get_capacity (base_reg);
+ tree cst_capacity_tree = maybe_get_integer_cst_tree (capacity);
+
+ /* The constant offset from a pointer is represented internally as a sizetype
+ but should be interpreted as a signed value here. The statement below
+ converts the offset from bits to bytes and then to a signed integer with
+ the same precision the sizetype has on the target system.
+
+ For example, this is needed for out-of-bounds-3.c test1 to pass when
+ compiled with a 64-bit gcc build targeting 32-bit systems. */
+ byte_offset_t offset;
+ if (!reg_offset.symbolic_p ())
+ offset = wi::sext (reg_offset.get_bit_offset () >> LOG2_BITS_PER_UNIT,
+ TYPE_PRECISION (size_type_node));
+
+ /* If either the offset or the number of bytes accessed are symbolic,
+ we have to reason about symbolic values. */
+ if (reg_offset.symbolic_p () || !num_bytes_tree)
+ {
+ const svalue* byte_offset_sval;
+ if (!reg_offset.symbolic_p ())
+ {
+ tree offset_tree = wide_int_to_tree (integer_type_node, offset);
+ byte_offset_sval
+ = m_mgr->get_or_create_constant_svalue (offset_tree);
+ }
+ else
+ byte_offset_sval = reg_offset.get_symbolic_byte_offset ();
+ check_symbolic_bounds (base_reg, byte_offset_sval, num_bytes_sval,
+ capacity, dir, ctxt);
+ return;
+ }
+
+ /* Otherwise continue to check with concrete values. */
+ byte_range out (0, 0);
+ /* NUM_BYTES_TREE should always be interpreted as unsigned. */
+ byte_offset_t num_bytes_unsigned = wi::to_offset (num_bytes_tree);
+ byte_range read_bytes (offset, num_bytes_unsigned);
+ /* If read_bytes has a subset < 0, we do have an underwrite. */
+ if (read_bytes.falls_short_of_p (0, &out))
+ {
+ tree diag_arg = get_representative_tree (base_reg);
+ switch (dir)
+ {
+ default:
+ gcc_unreachable ();
+ break;
+ case DIR_READ:
+ ctxt->warn (make_unique<concrete_buffer_under_read> (reg, diag_arg,
+ out));
+ break;
+ case DIR_WRITE:
+ ctxt->warn (make_unique<concrete_buffer_underwrite> (reg, diag_arg,
+ out));
+ break;
+ }
+ }
+
+ /* For accesses past the end, we do need a concrete capacity. No need to
+ do a symbolic check here because the inequality check does not reason
+ whether constants are greater than symbolic values. */
+ if (!cst_capacity_tree)
+ return;
+
+ byte_range buffer (0, wi::to_offset (cst_capacity_tree));
+ /* If READ_BYTES exceeds BUFFER, we do have an overflow. */
+ if (read_bytes.exceeds_p (buffer, &out))
+ {
+ tree byte_bound = wide_int_to_tree (size_type_node,
+ buffer.get_next_byte_offset ());
+ tree diag_arg = get_representative_tree (base_reg);
+
+ switch (dir)
+ {
+ default:
+ gcc_unreachable ();
+ break;
+ case DIR_READ:
+ ctxt->warn (make_unique<concrete_buffer_over_read> (reg, diag_arg,
+ out, byte_bound));
+ break;
+ case DIR_WRITE:
+ ctxt->warn (make_unique<concrete_buffer_overflow> (reg, diag_arg,
+ out, byte_bound));
+ break;
+ }
+ }
+}
+
+} // namespace ana
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/call-details.cc b/gcc/analyzer/call-details.cc
new file mode 100644
index 0000000..b63b8a3
--- /dev/null
+++ b/gcc/analyzer/call-details.cc
@@ -0,0 +1,231 @@
+/* Helper class for handling a call with specific arguments.
+ Copyright (C) 2020-2022 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#define INCLUDE_MEMORY
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "function.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "diagnostic-core.h"
+#include "analyzer/analyzer.h"
+#include "analyzer/analyzer-logging.h"
+#include "diagnostic.h"
+#include "tree-diagnostic.h" /* for default_tree_printer. */
+#include "gimple-pretty-print.h"
+#include "analyzer/region-model.h"
+#include "analyzer/call-details.h"
+
+#if ENABLE_ANALYZER
+
+namespace ana {
+
+/* class call_details. */
+
+/* call_details's ctor. */
+
+call_details::call_details (const gcall *call, region_model *model,
+ region_model_context *ctxt)
+: m_call (call), m_model (model), m_ctxt (ctxt),
+ m_lhs_type (NULL_TREE), m_lhs_region (NULL)
+{
+ m_lhs_type = NULL_TREE;
+ if (tree lhs = gimple_call_lhs (call))
+ {
+ m_lhs_region = model->get_lvalue (lhs, ctxt);
+ m_lhs_type = TREE_TYPE (lhs);
+ }
+}
+
+/* Get the manager from m_model. */
+
+region_model_manager *
+call_details::get_manager () const
+{
+ return m_model->get_manager ();
+}
+
+/* Get any logger associated with this object. */
+
+logger *
+call_details::get_logger () const
+{
+ if (m_ctxt)
+ return m_ctxt->get_logger ();
+ else
+ return NULL;
+}
+
+/* Get any uncertainty_t associated with the region_model_context. */
+
+uncertainty_t *
+call_details::get_uncertainty () const
+{
+ if (m_ctxt)
+ return m_ctxt->get_uncertainty ();
+ else
+ return NULL;
+}
+
+/* If the callsite has a left-hand-side region, set it to RESULT
+ and return true.
+ Otherwise do nothing and return false. */
+
+bool
+call_details::maybe_set_lhs (const svalue *result) const
+{
+ gcc_assert (result);
+ if (m_lhs_region)
+ {
+ m_model->set_value (m_lhs_region, result, m_ctxt);
+ return true;
+ }
+ else
+ return false;
+}
+
+/* Return the number of arguments used by the call statement. */
+
+unsigned
+call_details::num_args () const
+{
+ return gimple_call_num_args (m_call);
+}
+
+/* Return true if argument IDX is a size_t (or compatible with it). */
+
+bool
+call_details::arg_is_size_p (unsigned idx) const
+{
+ return types_compatible_p (get_arg_type (idx), size_type_node);
+}
+
+/* Get the location of the call statement. */
+
+location_t
+call_details::get_location () const
+{
+ return m_call->location;
+}
+
+/* Get argument IDX at the callsite as a tree. */
+
+tree
+call_details::get_arg_tree (unsigned idx) const
+{
+ return gimple_call_arg (m_call, idx);
+}
+
+/* Get the type of argument IDX. */
+
+tree
+call_details::get_arg_type (unsigned idx) const
+{
+ return TREE_TYPE (gimple_call_arg (m_call, idx));
+}
+
+/* Get argument IDX at the callsite as an svalue. */
+
+const svalue *
+call_details::get_arg_svalue (unsigned idx) const
+{
+ tree arg = get_arg_tree (idx);
+ return m_model->get_rvalue (arg, m_ctxt);
+}
+
+/* Attempt to get the string literal for argument IDX, or return NULL
+ otherwise.
+ For use when implementing "__analyzer_*" functions that take
+ string literals. */
+
+const char *
+call_details::get_arg_string_literal (unsigned idx) const
+{
+ const svalue *str_arg = get_arg_svalue (idx);
+ if (const region *pointee = str_arg->maybe_get_region ())
+ if (const string_region *string_reg = pointee->dyn_cast_string_region ())
+ {
+ tree string_cst = string_reg->get_string_cst ();
+ return TREE_STRING_POINTER (string_cst);
+ }
+ return NULL;
+}
+
+/* Attempt to get the fndecl used at this call, if known, or NULL_TREE
+ otherwise. */
+
+tree
+call_details::get_fndecl_for_call () const
+{
+ return m_model->get_fndecl_for_call (m_call, m_ctxt);
+}
+
+/* Dump a multiline representation of this call to PP. */
+
+void
+call_details::dump_to_pp (pretty_printer *pp, bool simple) const
+{
+ pp_string (pp, "gcall: ");
+ pp_gimple_stmt_1 (pp, m_call, 0 /* spc */, TDF_NONE /* flags */);
+ pp_newline (pp);
+ pp_string (pp, "return region: ");
+ if (m_lhs_region)
+ m_lhs_region->dump_to_pp (pp, simple);
+ else
+ pp_string (pp, "NULL");
+ pp_newline (pp);
+ for (unsigned i = 0; i < gimple_call_num_args (m_call); i++)
+ {
+ const svalue *arg_sval = get_arg_svalue (i);
+ pp_printf (pp, "arg %i: ", i);
+ arg_sval->dump_to_pp (pp, simple);
+ pp_newline (pp);
+ }
+}
+
+/* Dump a multiline representation of this call to stderr. */
+
+DEBUG_FUNCTION void
+call_details::dump (bool simple) const
+{
+ pretty_printer pp;
+ pp_format_decoder (&pp) = default_tree_printer;
+ pp_show_color (&pp) = pp_show_color (global_dc->printer);
+ pp.buffer->stream = stderr;
+ dump_to_pp (&pp, simple);
+ pp_flush (&pp);
+}
+
+/* Get a conjured_svalue for this call for REG,
+ and purge any state already relating to that conjured_svalue. */
+
+const svalue *
+call_details::get_or_create_conjured_svalue (const region *reg) const
+{
+ region_model_manager *mgr = m_model->get_manager ();
+ return mgr->get_or_create_conjured_svalue (reg->get_type (), m_call, reg,
+ conjured_purge (m_model, m_ctxt));
+}
+
+} // namespace ana
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/call-details.h b/gcc/analyzer/call-details.h
new file mode 100644
index 0000000..144ca0c
--- /dev/null
+++ b/gcc/analyzer/call-details.h
@@ -0,0 +1,77 @@
+/* Helper class for handling a call with specific arguments.
+ Copyright (C) 2019-2022 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_ANALYZER_CALL_DETAILS_H
+#define GCC_ANALYZER_CALL_DETAILS_H
+
+namespace ana {
+
+/* Helper class for handling calls to functions with known behavior. */
+
+class call_details
+{
+public:
+ call_details (const gcall *call, region_model *model,
+ region_model_context *ctxt);
+
+ region_model *get_model () const { return m_model; }
+ region_model_manager *get_manager () const;
+ region_model_context *get_ctxt () const { return m_ctxt; }
+ logger *get_logger () const;
+
+ uncertainty_t *get_uncertainty () const;
+ tree get_lhs_type () const { return m_lhs_type; }
+ const region *get_lhs_region () const { return m_lhs_region; }
+
+ bool maybe_set_lhs (const svalue *result) const;
+
+ unsigned num_args () const;
+ bool arg_is_pointer_p (unsigned idx) const
+ {
+ return POINTER_TYPE_P (get_arg_type (idx));
+ }
+ bool arg_is_size_p (unsigned idx) const;
+
+ const gcall *get_call_stmt () const { return m_call; }
+ location_t get_location () const;
+
+ tree get_arg_tree (unsigned idx) const;
+ tree get_arg_type (unsigned idx) const;
+ const svalue *get_arg_svalue (unsigned idx) const;
+ const char *get_arg_string_literal (unsigned idx) const;
+
+ tree get_fndecl_for_call () const;
+
+ void dump_to_pp (pretty_printer *pp, bool simple) const;
+ void dump (bool simple) const;
+
+ const svalue *get_or_create_conjured_svalue (const region *) const;
+
+private:
+ const gcall *m_call;
+ region_model *m_model;
+ region_model_context *m_ctxt;
+ tree m_lhs_type;
+ const region *m_lhs_region;
+};
+
+} // namespace ana
+
+#endif /* GCC_ANALYZER_CALL_DETAILS_H */
diff --git a/gcc/analyzer/call-info.cc b/gcc/analyzer/call-info.cc
index 56059ac..cbd21f7 100644
--- a/gcc/analyzer/call-info.cc
+++ b/gcc/analyzer/call-info.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
@@ -53,7 +54,9 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/checker-path.h"
#include "analyzer/diagnostic-manager.h"
#include "analyzer/exploded-graph.h"
+#include "analyzer/call-details.h"
#include "analyzer/call-info.h"
+#include "make-unique.h"
#if ENABLE_ANALYZER
@@ -92,10 +95,10 @@ call_info::add_events_to_path (checker_path *emission_path,
class call_event : public custom_event
{
public:
- call_event (location_t loc, tree fndecl, int depth,
+ call_event (const event_loc_info &loc_info,
const call_info *call_info)
- : custom_event (loc, fndecl, depth),
- m_call_info (call_info)
+ : custom_event (loc_info),
+ m_call_info (call_info)
{}
label_text get_desc (bool can_colorize) const final override
@@ -112,10 +115,11 @@ call_info::add_events_to_path (checker_path *emission_path,
tree caller_fndecl = src_point.get_fndecl ();
const int stack_depth = src_point.get_stack_depth ();
- emission_path->add_event (new call_event (get_call_stmt ()->location,
- caller_fndecl,
- stack_depth,
- this));
+ emission_path->add_event
+ (make_unique<call_event> (event_loc_info (get_call_stmt ()->location,
+ caller_fndecl,
+ stack_depth),
+ this));
}
/* Recreate a call_details instance from this call_info. */
@@ -139,24 +143,15 @@ call_info::call_info (const call_details &cd)
gcc_assert (m_fndecl);
}
-/* class success_call_info : public call_info. */
-
-/* Implementation of call_info::get_desc vfunc for success_call_info. */
-
-label_text
-success_call_info::get_desc (bool can_colorize) const
-{
- return make_label_text (can_colorize, "when %qE succeeds", get_fndecl ());
-}
-
-/* class failed_call_info : public call_info. */
-
-/* Implementation of call_info::get_desc vfunc for failed_call_info. */
+/* class succeed_or_fail_call_info : public call_info. */
label_text
-failed_call_info::get_desc (bool can_colorize) const
+succeed_or_fail_call_info::get_desc (bool can_colorize) const
{
- return make_label_text (can_colorize, "when %qE fails", get_fndecl ());
+ if (m_success)
+ return make_label_text (can_colorize, "when %qE succeeds", get_fndecl ());
+ else
+ return make_label_text (can_colorize, "when %qE fails", get_fndecl ());
}
} // namespace ana
diff --git a/gcc/analyzer/call-info.h b/gcc/analyzer/call-info.h
index 4bb7dd7..2fd5077 100644
--- a/gcc/analyzer/call-info.h
+++ b/gcc/analyzer/call-info.h
@@ -51,17 +51,36 @@ private:
};
/* Subclass of call_info for a "success" outcome of a call,
- adding a "when `FNDECL' succeeds" message.
+ adding either a
+ "when `FNDECL' succeeds" message (when 'success' is true)
+ or a
+ "when `FNDECL' fails" message (when 'success' is false).
This is still abstract: the custom_edge_info::update_model vfunc
must be implemented. */
-class success_call_info : public call_info
+class succeed_or_fail_call_info : public call_info
{
public:
label_text get_desc (bool can_colorize) const final override;
protected:
- success_call_info (const call_details &cd) : call_info (cd) {}
+ succeed_or_fail_call_info (const call_details &cd, bool success)
+ : call_info (cd), m_success (success) {}
+
+ bool m_success;
+};
+
+/* Subclass of call_info for a "success" outcome of a call,
+ adding a "when `FNDECL' succeeds" message.
+ This is still abstract: the custom_edge_info::update_model vfunc
+ must be implemented. */
+
+class success_call_info : public succeed_or_fail_call_info
+{
+protected:
+ success_call_info (const call_details &cd)
+ : succeed_or_fail_call_info (cd, true)
+ {}
};
/* Subclass of call_info for a "failure" outcome of a call,
@@ -69,13 +88,12 @@ protected:
This is still abstract: the custom_edge_info::update_model vfunc
must be implemented. */
-class failed_call_info : public call_info
+class failed_call_info : public succeed_or_fail_call_info
{
-public:
- label_text get_desc (bool can_colorize) const final override;
-
protected:
- failed_call_info (const call_details &cd) : call_info (cd) {}
+ failed_call_info (const call_details &cd)
+ : succeed_or_fail_call_info (cd, false)
+ {}
};
} // namespace ana
diff --git a/gcc/analyzer/call-string.cc b/gcc/analyzer/call-string.cc
index f0a30d9..d78ae81 100644
--- a/gcc/analyzer/call-string.cc
+++ b/gcc/analyzer/call-string.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "pretty-print.h"
@@ -169,6 +170,22 @@ call_string::calc_recursion_depth () const
return result;
}
+/* Count the number of times FUN appears in the string. */
+
+int
+call_string::count_occurrences_of_function (function *fun) const
+{
+ int result = 0;
+ for (const call_string::element_t &e : m_elements)
+ {
+ if (e.get_callee_function () == fun)
+ result++;
+ if (e.get_caller_function () == fun)
+ result++;
+ }
+ return result;
+}
+
/* Comparator for call strings.
This implements a version of lexicographical order.
Return negative if A is before B.
diff --git a/gcc/analyzer/call-string.h b/gcc/analyzer/call-string.h
index c3cea90..d97ff84 100644
--- a/gcc/analyzer/call-string.h
+++ b/gcc/analyzer/call-string.h
@@ -105,6 +105,8 @@ public:
return m_elements[m_elements.length () - 1];
}
+ int count_occurrences_of_function (function *) const;
+
void validate () const;
private:
diff --git a/gcc/analyzer/call-summary.cc b/gcc/analyzer/call-summary.cc
index 12ef82d..a18a1b1 100644
--- a/gcc/analyzer/call-summary.cc
+++ b/gcc/analyzer/call-summary.cc
@@ -18,6 +18,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
@@ -574,6 +575,7 @@ call_summary_replay::convert_region_from_summary_1 (const region *summary_reg)
case RK_CODE:
case RK_STACK:
case RK_HEAP:
+ case RK_THREAD_LOCAL:
case RK_ROOT:
/* These should never be pointed to by a region_svalue. */
gcc_unreachable ();
@@ -581,6 +583,7 @@ call_summary_replay::convert_region_from_summary_1 (const region *summary_reg)
case RK_FUNCTION:
case RK_LABEL:
case RK_STRING:
+ case RK_ERRNO:
case RK_UNKNOWN:
/* We can reuse these regions directly. */
return summary_reg;
@@ -723,7 +726,9 @@ call_summary_replay::convert_region_from_summary_1 (const region *summary_reg)
/* If we have a heap-allocated region in the summary, then
it was allocated within the callee.
Create a new heap-allocated region to summarize this. */
- return mgr->create_region_for_heap_alloc ();
+ auto_bitmap heap_regs_in_use;
+ get_caller_model ()->get_referenced_base_regions (heap_regs_in_use);
+ return mgr->get_or_create_region_for_heap_alloc (heap_regs_in_use);
}
break;
case RK_ALLOCA:
diff --git a/gcc/analyzer/call-summary.h b/gcc/analyzer/call-summary.h
index 07cd3f5..73f21ac 100644
--- a/gcc/analyzer/call-summary.h
+++ b/gcc/analyzer/call-summary.h
@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_ANALYZER_CALL_SUMMARY_H
#define GCC_ANALYZER_CALL_SUMMARY_H
+#include "call-details.h"
+
namespace ana {
/* A class summarizing one particular outcome of a function that
diff --git a/gcc/analyzer/checker-event.cc b/gcc/analyzer/checker-event.cc
new file mode 100644
index 0000000..4985f63
--- /dev/null
+++ b/gcc/analyzer/checker-event.cc
@@ -0,0 +1,1209 @@
+/* Subclasses of diagnostic_event for analyzer diagnostics.
+ Copyright (C) 2019-2022 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#define INCLUDE_MEMORY
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "function.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "diagnostic-core.h"
+#include "gimple-pretty-print.h"
+#include "fold-const.h"
+#include "diagnostic-path.h"
+#include "options.h"
+#include "cgraph.h"
+#include "cfg.h"
+#include "digraph.h"
+#include "diagnostic-event-id.h"
+#include "analyzer/analyzer.h"
+#include "analyzer/analyzer-logging.h"
+#include "analyzer/sm.h"
+#include "sbitmap.h"
+#include "bitmap.h"
+#include "ordered-hash-map.h"
+#include "analyzer/call-string.h"
+#include "analyzer/program-point.h"
+#include "analyzer/store.h"
+#include "analyzer/region-model.h"
+#include "analyzer/program-state.h"
+#include "analyzer/checker-path.h"
+#include "gimple-iterator.h"
+#include "inlining-iterator.h"
+#include "analyzer/supergraph.h"
+#include "analyzer/pending-diagnostic.h"
+#include "analyzer/diagnostic-manager.h"
+#include "analyzer/constraint-manager.h"
+#include "analyzer/checker-event.h"
+#include "analyzer/exploded-graph.h"
+
+#if ENABLE_ANALYZER
+
+namespace ana {
+
+/* Get a string for EK. */
+
+const char *
+event_kind_to_string (enum event_kind ek)
+{
+ switch (ek)
+ {
+ default:
+ gcc_unreachable ();
+ case EK_DEBUG:
+ return "EK_DEBUG";
+ case EK_CUSTOM:
+ return "EK_CUSTOM";
+ case EK_STMT:
+ return "EK_STMT";
+ case EK_REGION_CREATION:
+ return "EK_REGION_CREATION";
+ case EK_FUNCTION_ENTRY:
+ return "EK_FUNCTION_ENTRY";
+ case EK_STATE_CHANGE:
+ return "EK_STATE_CHANGE";
+ case EK_START_CFG_EDGE:
+ return "EK_START_CFG_EDGE";
+ case EK_END_CFG_EDGE:
+ return "EK_END_CFG_EDGE";
+ case EK_CALL_EDGE:
+ return "EK_CALL_EDGE";
+ case EK_RETURN_EDGE:
+ return "EK_RETURN_EDGE";
+ case EK_START_CONSOLIDATED_CFG_EDGES:
+ return "EK_START_CONSOLIDATED_CFG_EDGES";
+ case EK_END_CONSOLIDATED_CFG_EDGES:
+ return "EK_END_CONSOLIDATED_CFG_EDGES";
+ case EK_INLINED_CALL:
+ return "EK_INLINED_CALL";
+ case EK_SETJMP:
+ return "EK_SETJMP";
+ case EK_REWIND_FROM_LONGJMP:
+ return "EK_REWIND_FROM_LONGJMP";
+ case EK_REWIND_TO_SETJMP:
+ return "EK_REWIND_TO_SETJMP";
+ case EK_WARNING:
+ return "EK_WARNING";
+ }
+}
+
+/* A class for fixing up fndecls and stack depths in checker_event, based
+ on inlining records.
+
+ The early inliner runs before the analyzer, which can lead to confusing
+ output.
+
+ Tne base fndecl and depth within a checker_event are from call strings
+ in program_points, which reflect the call strings after inlining.
+ This class lets us offset the depth and fix up the reported fndecl and
+ stack depth to better reflect the user's original code. */
+
+class inlining_info
+{
+public:
+ inlining_info (location_t loc)
+ {
+ inlining_iterator iter (loc);
+ m_inner_fndecl = iter.get_fndecl ();
+ int num_frames = 0;
+ while (!iter.done_p ())
+ {
+ m_outer_fndecl = iter.get_fndecl ();
+ num_frames++;
+ iter.next ();
+ }
+ if (num_frames > 1)
+ m_extra_frames = num_frames - 1;
+ else
+ m_extra_frames = 0;
+ }
+
+ tree get_inner_fndecl () const { return m_inner_fndecl; }
+ int get_extra_frames () const { return m_extra_frames; }
+
+private:
+ tree m_outer_fndecl;
+ tree m_inner_fndecl;
+ int m_extra_frames;
+};
+
+/* class checker_event : public diagnostic_event. */
+
+/* checker_event's ctor. */
+
+checker_event::checker_event (enum event_kind kind,
+ const event_loc_info &loc_info)
+: m_kind (kind), m_loc (loc_info.m_loc),
+ m_original_fndecl (loc_info.m_fndecl),
+ m_effective_fndecl (loc_info.m_fndecl),
+ m_original_depth (loc_info.m_depth),
+ m_effective_depth (loc_info.m_depth),
+ m_pending_diagnostic (NULL), m_emission_id (),
+ m_logical_loc (loc_info.m_fndecl)
+{
+ /* Update effective fndecl and depth if inlining has been recorded. */
+ if (flag_analyzer_undo_inlining)
+ {
+ inlining_info info (m_loc);
+ if (info.get_inner_fndecl ())
+ {
+ m_effective_fndecl = info.get_inner_fndecl ();
+ m_effective_depth += info.get_extra_frames ();
+ m_logical_loc = tree_logical_location (m_effective_fndecl);
+ }
+ }
+}
+
+/* No-op implementation of diagnostic_event::get_meaning vfunc for
+ checker_event: checker events have no meaning by default. */
+
+diagnostic_event::meaning
+checker_event::get_meaning () const
+{
+ return meaning ();
+}
+
+/* Dump this event to PP (for debugging/logging purposes). */
+
+void
+checker_event::dump (pretty_printer *pp) const
+{
+ label_text event_desc (get_desc (false));
+ pp_printf (pp, "\"%s\" (depth %i",
+ event_desc.get (), m_effective_depth);
+
+ if (m_effective_depth != m_original_depth)
+ pp_printf (pp, " corrected from %i",
+ m_original_depth);
+ if (m_effective_fndecl)
+ {
+ pp_printf (pp, ", fndecl %qE", m_effective_fndecl);
+ if (m_effective_fndecl != m_original_fndecl)
+ pp_printf (pp, " corrected from %qE", m_original_fndecl);
+ }
+ pp_printf (pp, ", m_loc=%x)",
+ get_location ());
+}
+
+/* Dump this event to stderr (for debugging/logging purposes). */
+
+DEBUG_FUNCTION void
+checker_event::debug () const
+{
+ pretty_printer pp;
+ pp_format_decoder (&pp) = default_tree_printer;
+ pp_show_color (&pp) = pp_show_color (global_dc->printer);
+ pp.buffer->stream = stderr;
+ dump (&pp);
+ pp_newline (&pp);
+ pp_flush (&pp);
+}
+
+/* Hook for being notified when this event has its final id EMISSION_ID
+ and is about to emitted for PD.
+
+ Base implementation of checker_event::prepare_for_emission vfunc;
+ subclasses that override this should chain up to it.
+
+ Record PD and EMISSION_ID, and call the get_desc vfunc, so that any
+ side-effects of the call to get_desc take place before
+ pending_diagnostic::emit is called.
+
+ For example, state_change_event::get_desc can call
+ pending_diagnostic::describe_state_change; free_of_non_heap can use this
+ to tweak the message (TODO: would be neater to simply capture the
+ pertinent data within the sm-state). */
+
+void
+checker_event::prepare_for_emission (checker_path *,
+ pending_diagnostic *pd,
+ diagnostic_event_id_t emission_id)
+{
+ m_pending_diagnostic = pd;
+ m_emission_id = emission_id;
+
+ label_text desc = get_desc (false);
+}
+
+/* class debug_event : public checker_event. */
+
+/* Implementation of diagnostic_event::get_desc vfunc for
+ debug_event.
+ Use the saved string as the event's description. */
+
+label_text
+debug_event::get_desc (bool) const
+{
+ return label_text::borrow (m_desc);
+}
+
+/* class precanned_custom_event : public custom_event. */
+
+/* Implementation of diagnostic_event::get_desc vfunc for
+ precanned_custom_event.
+ Use the saved string as the event's description. */
+
+label_text
+precanned_custom_event::get_desc (bool) const
+{
+ return label_text::borrow (m_desc);
+}
+
+/* class statement_event : public checker_event. */
+
+/* statement_event's ctor. */
+
+statement_event::statement_event (const gimple *stmt, tree fndecl, int depth,
+ const program_state &dst_state)
+: checker_event (EK_STMT,
+ event_loc_info (gimple_location (stmt), fndecl, depth)),
+ m_stmt (stmt),
+ m_dst_state (dst_state)
+{
+}
+
+/* Implementation of diagnostic_event::get_desc vfunc for
+ statement_event.
+ Use the statement's dump form as the event's description. */
+
+label_text
+statement_event::get_desc (bool) const
+{
+ pretty_printer pp;
+ pp_string (&pp, "stmt: ");
+ pp_gimple_stmt_1 (&pp, m_stmt, 0, (dump_flags_t)0);
+ return label_text::take (xstrdup (pp_formatted_text (&pp)));
+}
+
+/* class region_creation_event : public checker_event. */
+
+region_creation_event::region_creation_event (const event_loc_info &loc_info)
+: checker_event (EK_REGION_CREATION, loc_info)
+{
+}
+
+/* The various region_creation_event subclasses' get_desc
+ implementations. */
+
+label_text
+region_creation_event_memory_space::get_desc (bool) const
+{
+ switch (m_mem_space)
+ {
+ default:
+ return label_text::borrow ("region created here");
+ case MEMSPACE_STACK:
+ return label_text::borrow ("region created on stack here");
+ case MEMSPACE_HEAP:
+ return label_text::borrow ("region created on heap here");
+ }
+}
+
+label_text
+region_creation_event_capacity::get_desc (bool can_colorize) const
+{
+ gcc_assert (m_capacity);
+ if (TREE_CODE (m_capacity) == INTEGER_CST)
+ {
+ unsigned HOST_WIDE_INT hwi = tree_to_uhwi (m_capacity);
+ return make_label_text_n (can_colorize,
+ hwi,
+ "capacity: %wu byte",
+ "capacity: %wu bytes",
+ hwi);
+ }
+ else
+ return make_label_text (can_colorize,
+ "capacity: %qE bytes", m_capacity);
+}
+
+label_text
+region_creation_event_allocation_size::get_desc (bool can_colorize) const
+{
+ if (m_capacity)
+ {
+ if (TREE_CODE (m_capacity) == INTEGER_CST)
+ return make_label_text_n (can_colorize,
+ tree_to_uhwi (m_capacity),
+ "allocated %E byte here",
+ "allocated %E bytes here",
+ m_capacity);
+ else
+ return make_label_text (can_colorize,
+ "allocated %qE bytes here",
+ m_capacity);
+ }
+ return make_label_text (can_colorize, "allocated here");
+}
+
+label_text
+region_creation_event_debug::get_desc (bool) const
+{
+ pretty_printer pp;
+ pp_format_decoder (&pp) = default_tree_printer;
+ pp_string (&pp, "region creation: ");
+ m_reg->dump_to_pp (&pp, true);
+ if (m_capacity)
+ pp_printf (&pp, " capacity: %qE", m_capacity);
+ return label_text::take (xstrdup (pp_formatted_text (&pp)));
+}
+
+/* class function_entry_event : public checker_event. */
+
+function_entry_event::function_entry_event (const program_point &dst_point)
+: checker_event (EK_FUNCTION_ENTRY,
+ event_loc_info (dst_point.get_supernode
+ ()->get_start_location (),
+ dst_point.get_fndecl (),
+ dst_point.get_stack_depth ()))
+{
+}
+
+/* Implementation of diagnostic_event::get_desc vfunc for
+ function_entry_event.
+
+ Use a string such as "entry to 'foo'" as the event's description. */
+
+label_text
+function_entry_event::get_desc (bool can_colorize) const
+{
+ return make_label_text (can_colorize, "entry to %qE", m_effective_fndecl);
+}
+
+/* Implementation of diagnostic_event::get_meaning vfunc for
+ function entry. */
+
+diagnostic_event::meaning
+function_entry_event::get_meaning () const
+{
+ return meaning (VERB_enter, NOUN_function);
+}
+
+/* class state_change_event : public checker_event. */
+
+/* state_change_event's ctor. */
+
+state_change_event::state_change_event (const supernode *node,
+ const gimple *stmt,
+ int stack_depth,
+ const state_machine &sm,
+ const svalue *sval,
+ state_machine::state_t from,
+ state_machine::state_t to,
+ const svalue *origin,
+ const program_state &dst_state)
+: checker_event (EK_STATE_CHANGE,
+ event_loc_info (stmt->location,
+ node->m_fun->decl,
+ stack_depth)),
+ m_node (node), m_stmt (stmt), m_sm (sm),
+ m_sval (sval), m_from (from), m_to (to),
+ m_origin (origin),
+ m_dst_state (dst_state)
+{
+}
+
+/* Implementation of diagnostic_event::get_desc vfunc for
+ state_change_event.
+
+ Attempt to generate a nicer human-readable description.
+ For greatest precision-of-wording, give the pending diagnostic
+ a chance to describe this state change (in terms of the
+ diagnostic).
+ Note that we only have a pending_diagnostic set on the event once
+ the diagnostic is about to being emitted, so the description for
+ an event can change. */
+
+label_text
+state_change_event::get_desc (bool can_colorize) const
+{
+ if (m_pending_diagnostic)
+ {
+ region_model *model = m_dst_state.m_region_model;
+ tree var = model->get_representative_tree (m_sval);
+ tree origin = model->get_representative_tree (m_origin);
+ label_text custom_desc
+ = m_pending_diagnostic->describe_state_change
+ (evdesc::state_change (can_colorize, var, origin,
+ m_from, m_to, m_emission_id, *this));
+ if (custom_desc.get ())
+ {
+ if (flag_analyzer_verbose_state_changes)
+ {
+ /* Get any "meaning" of event. */
+ diagnostic_event::meaning meaning = get_meaning ();
+ pretty_printer meaning_pp;
+ meaning.dump_to_pp (&meaning_pp);
+
+ /* Append debug version. */
+ if (m_origin)
+ return make_label_text
+ (can_colorize,
+ "%s (state of %qE: %qs -> %qs, origin: %qE, meaning: %s)",
+ custom_desc.get (),
+ var,
+ m_from->get_name (),
+ m_to->get_name (),
+ origin,
+ pp_formatted_text (&meaning_pp));
+ else
+ return make_label_text
+ (can_colorize,
+ "%s (state of %qE: %qs -> %qs, NULL origin, meaning: %s)",
+ custom_desc.get (),
+ var,
+ m_from->get_name (),
+ m_to->get_name (),
+ pp_formatted_text (&meaning_pp));
+ }
+ else
+ return custom_desc;
+ }
+ }
+
+ /* Fallback description. */
+ if (m_sval)
+ {
+ label_text sval_desc = m_sval->get_desc ();
+ if (m_origin)
+ {
+ label_text origin_desc = m_origin->get_desc ();
+ return make_label_text
+ (can_colorize,
+ "state of %qs: %qs -> %qs (origin: %qs)",
+ sval_desc.get (),
+ m_from->get_name (),
+ m_to->get_name (),
+ origin_desc.get ());
+ }
+ else
+ return make_label_text
+ (can_colorize,
+ "state of %qs: %qs -> %qs (NULL origin)",
+ sval_desc.get (),
+ m_from->get_name (),
+ m_to->get_name ());
+ }
+ else
+ {
+ gcc_assert (m_origin == NULL);
+ return make_label_text
+ (can_colorize,
+ "global state: %qs -> %qs",
+ m_from->get_name (),
+ m_to->get_name ());
+ }
+}
+
+/* Implementation of diagnostic_event::get_meaning vfunc for
+ state change events: delegate to the pending_diagnostic to
+ get any meaning. */
+
+diagnostic_event::meaning
+state_change_event::get_meaning () const
+{
+ if (m_pending_diagnostic)
+ {
+ region_model *model = m_dst_state.m_region_model;
+ tree var = model->get_representative_tree (m_sval);
+ tree origin = model->get_representative_tree (m_origin);
+ return m_pending_diagnostic->get_meaning_for_state_change
+ (evdesc::state_change (false, var, origin,
+ m_from, m_to, m_emission_id, *this));
+ }
+ else
+ return meaning ();
+}
+
+/* class superedge_event : public checker_event. */
+
+/* Get the callgraph_superedge for this superedge_event, which must be
+ for an interprocedural edge, rather than a CFG edge. */
+
+const callgraph_superedge&
+superedge_event::get_callgraph_superedge () const
+{
+ gcc_assert (m_sedge->m_kind != SUPEREDGE_CFG_EDGE);
+ return *m_sedge->dyn_cast_callgraph_superedge ();
+}
+
+/* Determine if this event should be filtered at the given verbosity
+ level. */
+
+bool
+superedge_event::should_filter_p (int verbosity) const
+{
+ switch (m_sedge->m_kind)
+ {
+ case SUPEREDGE_CFG_EDGE:
+ {
+ if (verbosity < 2)
+ return true;
+
+ if (verbosity < 4)
+ {
+ /* Filter events with empty descriptions. This ought to filter
+ FALLTHRU, but retain true/false/switch edges. */
+ label_text desc = get_desc (false);
+ gcc_assert (desc.get ());
+ if (desc.get ()[0] == '\0')
+ return true;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return false;
+}
+
+/* superedge_event's ctor. */
+
+superedge_event::superedge_event (enum event_kind kind,
+ const exploded_edge &eedge,
+ const event_loc_info &loc_info)
+: checker_event (kind, loc_info),
+ m_eedge (eedge), m_sedge (eedge.m_sedge),
+ m_var (NULL_TREE), m_critical_state (0)
+{
+}
+
+/* class cfg_edge_event : public superedge_event. */
+
+/* Get the cfg_superedge for this cfg_edge_event. */
+
+const cfg_superedge &
+cfg_edge_event::get_cfg_superedge () const
+{
+ return *m_sedge->dyn_cast_cfg_superedge ();
+}
+
+/* cfg_edge_event's ctor. */
+
+cfg_edge_event::cfg_edge_event (enum event_kind kind,
+ const exploded_edge &eedge,
+ const event_loc_info &loc_info)
+: superedge_event (kind, eedge, loc_info)
+{
+ gcc_assert (eedge.m_sedge->m_kind == SUPEREDGE_CFG_EDGE);
+}
+
+/* Implementation of diagnostic_event::get_meaning vfunc for
+ CFG edge events. */
+
+diagnostic_event::meaning
+cfg_edge_event::get_meaning () const
+{
+ const cfg_superedge& cfg_sedge = get_cfg_superedge ();
+ if (cfg_sedge.true_value_p ())
+ return meaning (VERB_branch, PROPERTY_true);
+ else if (cfg_sedge.false_value_p ())
+ return meaning (VERB_branch, PROPERTY_false);
+ else
+ return meaning ();
+}
+
+/* class start_cfg_edge_event : public cfg_edge_event. */
+
+/* Implementation of diagnostic_event::get_desc vfunc for
+ start_cfg_edge_event.
+
+ If -fanalyzer-verbose-edges, then generate low-level descriptions, such
+ as
+ "taking 'true' edge SN:7 -> SN:8".
+
+ Otherwise, generate strings using the label of the underlying CFG if
+ any, such as:
+ "following 'true' branch..." or
+ "following 'case 3' branch..."
+ "following 'default' branch..."
+
+ For conditionals, attempt to supply a description of the condition that
+ holds, such as:
+ "following 'false' branch (when 'ptr' is non-NULL)..."
+
+ Failing that, return an empty description (which will lead to this event
+ being filtered). */
+
+label_text
+start_cfg_edge_event::get_desc (bool can_colorize) const
+{
+ bool user_facing = !flag_analyzer_verbose_edges;
+ label_text edge_desc (m_sedge->get_description (user_facing));
+ if (user_facing)
+ {
+ if (edge_desc.get () && strlen (edge_desc.get ()) > 0)
+ {
+ label_text cond_desc = maybe_describe_condition (can_colorize);
+ label_text result;
+ if (cond_desc.get ())
+ return make_label_text (can_colorize,
+ "following %qs branch (%s)...",
+ edge_desc.get (), cond_desc.get ());
+ else
+ return make_label_text (can_colorize,
+ "following %qs branch...",
+ edge_desc.get ());
+ }
+ else
+ return label_text::borrow ("");
+ }
+ else
+ {
+ if (strlen (edge_desc.get ()) > 0)
+ return make_label_text (can_colorize,
+ "taking %qs edge SN:%i -> SN:%i",
+ edge_desc.get (),
+ m_sedge->m_src->m_index,
+ m_sedge->m_dest->m_index);
+ else
+ return make_label_text (can_colorize,
+ "taking edge SN:%i -> SN:%i",
+ m_sedge->m_src->m_index,
+ m_sedge->m_dest->m_index);
+ }
+}
+
+/* Attempt to generate a description of any condition that holds at this edge.
+
+ The intent is to make the user-facing messages more clear, especially for
+ cases where there's a single or double-negative, such as
+ when describing the false branch of an inverted condition.
+
+ For example, rather than printing just:
+
+ | if (!ptr)
+ | ~
+ | |
+ | (1) following 'false' branch...
+
+ it's clearer to spell out the condition that holds:
+
+ | if (!ptr)
+ | ~
+ | |
+ | (1) following 'false' branch (when 'ptr' is non-NULL)...
+ ^^^^^^^^^^^^^^^^^^^^^^
+
+ In the above example, this function would generate the highlighted
+ string: "when 'ptr' is non-NULL".
+
+ If the edge is not a condition, or it's not clear that a description of
+ the condition would be helpful to the user, return NULL. */
+
+label_text
+start_cfg_edge_event::maybe_describe_condition (bool can_colorize) const
+{
+ const cfg_superedge& cfg_sedge = get_cfg_superedge ();
+
+ if (cfg_sedge.true_value_p () || cfg_sedge.false_value_p ())
+ {
+ const gimple *last_stmt = m_sedge->m_src->get_last_stmt ();
+ if (const gcond *cond_stmt = dyn_cast <const gcond *> (last_stmt))
+ {
+ enum tree_code op = gimple_cond_code (cond_stmt);
+ tree lhs = gimple_cond_lhs (cond_stmt);
+ tree rhs = gimple_cond_rhs (cond_stmt);
+ if (cfg_sedge.false_value_p ())
+ op = invert_tree_comparison (op, false /* honor_nans */);
+ return maybe_describe_condition (can_colorize,
+ lhs, op, rhs);
+ }
+ }
+ return label_text::borrow (NULL);
+}
+
+/* Subroutine of maybe_describe_condition above.
+
+ Attempt to generate a user-facing description of the condition
+ LHS OP RHS, but only if it is likely to make it easier for the
+ user to understand a condition. */
+
+label_text
+start_cfg_edge_event::maybe_describe_condition (bool can_colorize,
+ tree lhs,
+ enum tree_code op,
+ tree rhs)
+{
+ /* In theory we could just build a tree via
+ fold_build2 (op, boolean_type_node, lhs, rhs)
+ and print it with %qE on it, but this leads to warts such as
+ parenthesizing vars, such as '(i) <= 9', and uses of '<unknown>'. */
+
+ /* Special-case: describe testing the result of strcmp, as figuring
+ out what the "true" or "false" path is can be confusing to the user. */
+ if (TREE_CODE (lhs) == SSA_NAME
+ && zerop (rhs))
+ {
+ if (gcall *call = dyn_cast <gcall *> (SSA_NAME_DEF_STMT (lhs)))
+ if (is_special_named_call_p (call, "strcmp", 2))
+ {
+ if (op == EQ_EXPR)
+ return label_text::borrow ("when the strings are equal");
+ if (op == NE_EXPR)
+ return label_text::borrow ("when the strings are non-equal");
+ }
+ }
+
+ /* Only attempt to generate text for sufficiently simple expressions. */
+ if (!should_print_expr_p (lhs))
+ return label_text::borrow (NULL);
+ if (!should_print_expr_p (rhs))
+ return label_text::borrow (NULL);
+
+ /* Special cases for pointer comparisons against NULL. */
+ if (POINTER_TYPE_P (TREE_TYPE (lhs))
+ && POINTER_TYPE_P (TREE_TYPE (rhs))
+ && zerop (rhs))
+ {
+ if (op == EQ_EXPR)
+ return make_label_text (can_colorize, "when %qE is NULL",
+ lhs);
+ if (op == NE_EXPR)
+ return make_label_text (can_colorize, "when %qE is non-NULL",
+ lhs);
+ }
+
+ return make_label_text (can_colorize, "when %<%E %s %E%>",
+ lhs, op_symbol_code (op), rhs);
+}
+
+/* Subroutine of maybe_describe_condition.
+
+ Return true if EXPR is we will get suitable user-facing output
+ from %E on it. */
+
+bool
+start_cfg_edge_event::should_print_expr_p (tree expr)
+{
+ if (TREE_CODE (expr) == SSA_NAME)
+ {
+ if (SSA_NAME_VAR (expr))
+ return should_print_expr_p (SSA_NAME_VAR (expr));
+ else
+ return false;
+ }
+
+ if (DECL_P (expr))
+ return true;
+
+ if (CONSTANT_CLASS_P (expr))
+ return true;
+
+ return false;
+}
+
+/* class call_event : public superedge_event. */
+
+/* call_event's ctor. */
+
+call_event::call_event (const exploded_edge &eedge,
+ const event_loc_info &loc_info)
+: superedge_event (EK_CALL_EDGE, eedge, loc_info)
+{
+ if (eedge.m_sedge)
+ gcc_assert (eedge.m_sedge->m_kind == SUPEREDGE_CALL);
+
+ m_src_snode = eedge.m_src->get_supernode ();
+ m_dest_snode = eedge.m_dest->get_supernode ();
+}
+
+/* Implementation of diagnostic_event::get_desc vfunc for
+ call_event.
+
+ If this call event passes critical state for an sm-based warning,
+ allow the diagnostic to generate a precise description, such as:
+
+ "passing freed pointer 'ptr' in call to 'foo' from 'bar'"
+
+ Otherwise, generate a description of the form
+ "calling 'foo' from 'bar'". */
+
+label_text
+call_event::get_desc (bool can_colorize) const
+{
+ if (m_critical_state && m_pending_diagnostic)
+ {
+ gcc_assert (m_var);
+ tree var = fixup_tree_for_diagnostic (m_var);
+ label_text custom_desc
+ = m_pending_diagnostic->describe_call_with_state
+ (evdesc::call_with_state (can_colorize,
+ m_src_snode->m_fun->decl,
+ m_dest_snode->m_fun->decl,
+ var,
+ m_critical_state));
+ if (custom_desc.get ())
+ return custom_desc;
+ }
+
+ return make_label_text (can_colorize,
+ "calling %qE from %qE",
+ get_callee_fndecl (),
+ get_caller_fndecl ());
+}
+
+/* Implementation of diagnostic_event::get_meaning vfunc for
+ function call events. */
+
+diagnostic_event::meaning
+call_event::get_meaning () const
+{
+ return meaning (VERB_call, NOUN_function);
+}
+
+/* Override of checker_event::is_call_p for calls. */
+
+bool
+call_event::is_call_p () const
+{
+ return true;
+}
+
+tree
+call_event::get_caller_fndecl () const
+{
+ return m_src_snode->m_fun->decl;
+}
+
+tree
+call_event::get_callee_fndecl () const
+{
+ return m_dest_snode->m_fun->decl;
+}
+
+/* class return_event : public superedge_event. */
+
+/* return_event's ctor. */
+
+return_event::return_event (const exploded_edge &eedge,
+ const event_loc_info &loc_info)
+: superedge_event (EK_RETURN_EDGE, eedge, loc_info)
+{
+ if (eedge.m_sedge)
+ gcc_assert (eedge.m_sedge->m_kind == SUPEREDGE_RETURN);
+
+ m_src_snode = eedge.m_src->get_supernode ();
+ m_dest_snode = eedge.m_dest->get_supernode ();
+}
+
+/* Implementation of diagnostic_event::get_desc vfunc for
+ return_event.
+
+ If this return event returns critical state for an sm-based warning,
+ allow the diagnostic to generate a precise description, such as:
+
+ "possible of NULL to 'foo' from 'bar'"
+
+ Otherwise, generate a description of the form
+ "returning to 'foo' from 'bar'. */
+
+label_text
+return_event::get_desc (bool can_colorize) const
+{
+ /* For greatest precision-of-wording, if this is returning the
+ state involved in the pending diagnostic, give the pending
+ diagnostic a chance to describe this return (in terms of
+ itself). */
+ if (m_critical_state && m_pending_diagnostic)
+ {
+ label_text custom_desc
+ = m_pending_diagnostic->describe_return_of_state
+ (evdesc::return_of_state (can_colorize,
+ m_dest_snode->m_fun->decl,
+ m_src_snode->m_fun->decl,
+ m_critical_state));
+ if (custom_desc.get ())
+ return custom_desc;
+ }
+ return make_label_text (can_colorize,
+ "returning to %qE from %qE",
+ m_dest_snode->m_fun->decl,
+ m_src_snode->m_fun->decl);
+}
+
+/* Implementation of diagnostic_event::get_meaning vfunc for
+ function return events. */
+
+diagnostic_event::meaning
+return_event::get_meaning () const
+{
+ return meaning (VERB_return, NOUN_function);
+}
+
+/* Override of checker_event::is_return_p for returns. */
+
+bool
+return_event::is_return_p () const
+{
+ return true;
+}
+
+/* class start_consolidated_cfg_edges_event : public checker_event. */
+
+label_text
+start_consolidated_cfg_edges_event::get_desc (bool can_colorize) const
+{
+ return make_label_text (can_colorize,
+ "following %qs branch...",
+ m_edge_sense ? "true" : "false");
+}
+
+/* Implementation of diagnostic_event::get_meaning vfunc for
+ start_consolidated_cfg_edges_event. */
+
+diagnostic_event::meaning
+start_consolidated_cfg_edges_event::get_meaning () const
+{
+ return meaning (VERB_branch,
+ (m_edge_sense ? PROPERTY_true : PROPERTY_false));
+}
+
+/* class inlined_call_event : public checker_event. */
+
+label_text
+inlined_call_event::get_desc (bool can_colorize) const
+{
+ return make_label_text (can_colorize,
+ "inlined call to %qE from %qE",
+ m_apparent_callee_fndecl,
+ m_apparent_caller_fndecl);
+}
+
+/* Implementation of diagnostic_event::get_meaning vfunc for
+ reconstructed inlined function calls. */
+
+diagnostic_event::meaning
+inlined_call_event::get_meaning () const
+{
+ return meaning (VERB_call, NOUN_function);
+}
+
+/* class setjmp_event : public checker_event. */
+
+/* Implementation of diagnostic_event::get_desc vfunc for
+ setjmp_event. */
+
+label_text
+setjmp_event::get_desc (bool can_colorize) const
+{
+ return make_label_text (can_colorize,
+ "%qs called here",
+ get_user_facing_name (m_setjmp_call));
+}
+
+/* Implementation of checker_event::prepare_for_emission vfunc for setjmp_event.
+
+ Record this setjmp's event ID into the path, so that rewind events can
+ use it. */
+
+void
+setjmp_event::prepare_for_emission (checker_path *path,
+ pending_diagnostic *pd,
+ diagnostic_event_id_t emission_id)
+{
+ checker_event::prepare_for_emission (path, pd, emission_id);
+ path->record_setjmp_event (m_enode, emission_id);
+}
+
+/* class rewind_event : public checker_event. */
+
+/* Get the fndecl containing the site of the longjmp call. */
+
+tree
+rewind_event::get_longjmp_caller () const
+{
+ return m_eedge->m_src->get_function ()->decl;
+}
+
+/* Get the fndecl containing the site of the setjmp call. */
+
+tree
+rewind_event::get_setjmp_caller () const
+{
+ return m_eedge->m_dest->get_function ()->decl;
+}
+
+/* rewind_event's ctor. */
+
+rewind_event::rewind_event (const exploded_edge *eedge,
+ enum event_kind kind,
+ const event_loc_info &loc_info,
+ const rewind_info_t *rewind_info)
+: checker_event (kind, loc_info),
+ m_rewind_info (rewind_info),
+ m_eedge (eedge)
+{
+ gcc_assert (m_eedge->m_custom_info.get () == m_rewind_info);
+}
+
+/* class rewind_from_longjmp_event : public rewind_event. */
+
+/* Implementation of diagnostic_event::get_desc vfunc for
+ rewind_from_longjmp_event. */
+
+label_text
+rewind_from_longjmp_event::get_desc (bool can_colorize) const
+{
+ const char *src_name
+ = get_user_facing_name (m_rewind_info->get_longjmp_call ());
+
+ if (get_longjmp_caller () == get_setjmp_caller ())
+ /* Special-case: purely intraprocedural rewind. */
+ return make_label_text (can_colorize,
+ "rewinding within %qE from %qs...",
+ get_longjmp_caller (),
+ src_name);
+ else
+ return make_label_text (can_colorize,
+ "rewinding from %qs in %qE...",
+ src_name,
+ get_longjmp_caller ());
+}
+
+/* class rewind_to_setjmp_event : public rewind_event. */
+
+/* Implementation of diagnostic_event::get_desc vfunc for
+ rewind_to_setjmp_event. */
+
+label_text
+rewind_to_setjmp_event::get_desc (bool can_colorize) const
+{
+ const char *dst_name
+ = get_user_facing_name (m_rewind_info->get_setjmp_call ());
+
+ /* If we can, identify the ID of the setjmp_event. */
+ if (m_original_setjmp_event_id.known_p ())
+ {
+ if (get_longjmp_caller () == get_setjmp_caller ())
+ /* Special-case: purely intraprocedural rewind. */
+ return make_label_text (can_colorize,
+ "...to %qs (saved at %@)",
+ dst_name,
+ &m_original_setjmp_event_id);
+ else
+ return make_label_text (can_colorize,
+ "...to %qs in %qE (saved at %@)",
+ dst_name,
+ get_setjmp_caller (),
+ &m_original_setjmp_event_id);
+ }
+ else
+ {
+ if (get_longjmp_caller () == get_setjmp_caller ())
+ /* Special-case: purely intraprocedural rewind. */
+ return make_label_text (can_colorize,
+ "...to %qs",
+ dst_name,
+ get_setjmp_caller ());
+ else
+ return make_label_text (can_colorize,
+ "...to %qs in %qE",
+ dst_name,
+ get_setjmp_caller ());
+ }
+}
+
+/* Implementation of checker_event::prepare_for_emission vfunc for
+ rewind_to_setjmp_event.
+
+ Attempt to look up the setjmp event ID that recorded the jmp_buf
+ for this rewind. */
+
+void
+rewind_to_setjmp_event::prepare_for_emission (checker_path *path,
+ pending_diagnostic *pd,
+ diagnostic_event_id_t emission_id)
+{
+ checker_event::prepare_for_emission (path, pd, emission_id);
+ path->get_setjmp_event (m_rewind_info->get_enode_origin (),
+ &m_original_setjmp_event_id);
+}
+
+/* class warning_event : public checker_event. */
+
+/* Implementation of diagnostic_event::get_desc vfunc for
+ warning_event.
+
+ If the pending diagnostic implements describe_final_event, use it,
+ generating a precise description e.g.
+ "second 'free' here; first 'free' was at (7)"
+
+ Otherwise generate a generic description. */
+
+label_text
+warning_event::get_desc (bool can_colorize) const
+{
+ if (m_pending_diagnostic)
+ {
+ tree var = fixup_tree_for_diagnostic (m_var);
+ label_text ev_desc
+ = m_pending_diagnostic->describe_final_event
+ (evdesc::final_event (can_colorize, var, m_state));
+ if (ev_desc.get ())
+ {
+ if (m_sm && flag_analyzer_verbose_state_changes)
+ {
+ if (var)
+ return make_label_text (can_colorize,
+ "%s (%qE is in state %qs)",
+ ev_desc.get (),
+ var, m_state->get_name ());
+ else
+ return make_label_text (can_colorize,
+ "%s (in global state %qs)",
+ ev_desc.get (),
+ m_state->get_name ());
+ }
+ else
+ return ev_desc;
+ }
+ }
+
+ if (m_sm)
+ {
+ if (m_var)
+ return make_label_text (can_colorize,
+ "here (%qE is in state %qs)",
+ m_var, m_state->get_name ());
+ else
+ return make_label_text (can_colorize,
+ "here (in global state %qs)",
+ m_state->get_name ());
+ }
+ else
+ return label_text::borrow ("here");
+}
+
+/* Implementation of diagnostic_event::get_meaning vfunc for
+ warning_event. */
+
+diagnostic_event::meaning
+warning_event::get_meaning () const
+{
+ return meaning (VERB_danger, NOUN_unknown);
+}
+
+} // namespace ana
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/checker-event.h b/gcc/analyzer/checker-event.h
new file mode 100644
index 0000000..6dac647
--- /dev/null
+++ b/gcc/analyzer/checker-event.h
@@ -0,0 +1,689 @@
+/* Subclasses of diagnostic_event for analyzer diagnostics.
+ Copyright (C) 2019-2022 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_ANALYZER_CHECKER_EVENT_H
+#define GCC_ANALYZER_CHECKER_EVENT_H
+
+#include "tree-logical-location.h"
+#include "analyzer/program-state.h"
+
+namespace ana {
+
+/* A bundle of location information for a checker_event. */
+
+struct event_loc_info
+{
+ event_loc_info (location_t loc, tree fndecl, int depth)
+ : m_loc (loc), m_fndecl (fndecl), m_depth (depth)
+ {}
+
+ location_t m_loc;
+ tree m_fndecl;
+ int m_depth;
+};
+
+/* An enum for discriminating between the concrete subclasses of
+ checker_event. */
+
+enum event_kind
+{
+ EK_DEBUG,
+ EK_CUSTOM,
+ EK_STMT,
+ EK_REGION_CREATION,
+ EK_FUNCTION_ENTRY,
+ EK_STATE_CHANGE,
+ EK_START_CFG_EDGE,
+ EK_END_CFG_EDGE,
+ EK_CALL_EDGE,
+ EK_RETURN_EDGE,
+ EK_START_CONSOLIDATED_CFG_EDGES,
+ EK_END_CONSOLIDATED_CFG_EDGES,
+ EK_INLINED_CALL,
+ EK_SETJMP,
+ EK_REWIND_FROM_LONGJMP,
+ EK_REWIND_TO_SETJMP,
+ EK_WARNING
+};
+
+extern const char *event_kind_to_string (enum event_kind ek);
+
+/* Event subclasses.
+
+ The class hierarchy looks like this (using indentation to show
+ inheritance, and with event_kinds shown for the concrete subclasses):
+
+ diagnostic_event
+ checker_event
+ debug_event (EK_DEBUG)
+ custom_event (EK_CUSTOM)
+ precanned_custom_event
+ statement_event (EK_STMT)
+ region_creation_event (EK_REGION_CREATION)
+ function_entry_event (EK_FUNCTION_ENTRY)
+ state_change_event (EK_STATE_CHANGE)
+ superedge_event
+ cfg_edge_event
+ start_cfg_edge_event (EK_START_CFG_EDGE)
+ end_cfg_edge_event (EK_END_CFG_EDGE)
+ call_event (EK_CALL_EDGE)
+ return_edge (EK_RETURN_EDGE)
+ start_consolidated_cfg_edges_event (EK_START_CONSOLIDATED_CFG_EDGES)
+ end_consolidated_cfg_edges_event (EK_END_CONSOLIDATED_CFG_EDGES)
+ inlined_call_event (EK_INLINED_CALL)
+ setjmp_event (EK_SETJMP)
+ rewind_event
+ rewind_from_longjmp_event (EK_REWIND_FROM_LONGJMP)
+ rewind_to_setjmp_event (EK_REWIND_TO_SETJMP)
+ warning_event (EK_WARNING). */
+
+/* Abstract subclass of diagnostic_event; the base class for use in
+ checker_path (the analyzer's diagnostic_path subclass). */
+
+class checker_event : public diagnostic_event
+{
+public:
+ /* Implementation of diagnostic_event. */
+
+ location_t get_location () const final override { return m_loc; }
+ tree get_fndecl () const final override { return m_effective_fndecl; }
+ int get_stack_depth () const final override { return m_effective_depth; }
+ const logical_location *get_logical_location () const final override
+ {
+ if (m_effective_fndecl)
+ return &m_logical_loc;
+ else
+ return NULL;
+ }
+ meaning get_meaning () const override;
+
+ /* Additional functionality. */
+
+ int get_original_stack_depth () const { return m_original_depth; }
+
+ virtual void prepare_for_emission (checker_path *,
+ pending_diagnostic *pd,
+ diagnostic_event_id_t emission_id);
+ virtual bool is_call_p () const { return false; }
+ virtual bool is_function_entry_p () const { return false; }
+ virtual bool is_return_p () const { return false; }
+
+ /* For use with %@. */
+ const diagnostic_event_id_t *get_id_ptr () const
+ {
+ return &m_emission_id;
+ }
+
+ void dump (pretty_printer *pp) const;
+ void debug () const;
+
+ void set_location (location_t loc) { m_loc = loc; }
+
+protected:
+ checker_event (enum event_kind kind,
+ const event_loc_info &loc_info);
+
+ public:
+ const enum event_kind m_kind;
+ protected:
+ location_t m_loc;
+ tree m_original_fndecl;
+ tree m_effective_fndecl;
+ int m_original_depth;
+ int m_effective_depth;
+ pending_diagnostic *m_pending_diagnostic;
+ diagnostic_event_id_t m_emission_id; // only set once all pruning has occurred
+ tree_logical_location m_logical_loc;
+};
+
+/* A concrete event subclass for a purely textual event, for use in
+ debugging path creation and filtering. */
+
+class debug_event : public checker_event
+{
+public:
+
+ debug_event (const event_loc_info &loc_info,
+ const char *desc)
+ : checker_event (EK_DEBUG, loc_info),
+ m_desc (xstrdup (desc))
+ {
+ }
+ ~debug_event ()
+ {
+ free (m_desc);
+ }
+
+ label_text get_desc (bool) const final override;
+
+private:
+ char *m_desc;
+};
+
+/* An abstract event subclass for custom events. These are not filtered,
+ as they are likely to be pertinent to the diagnostic. */
+
+class custom_event : public checker_event
+{
+protected:
+ custom_event (const event_loc_info &loc_info)
+ : checker_event (EK_CUSTOM, loc_info)
+ {
+ }
+};
+
+/* A concrete custom_event subclass with a precanned message. */
+
+class precanned_custom_event : public custom_event
+{
+public:
+ precanned_custom_event (const event_loc_info &loc_info,
+ const char *desc)
+ : custom_event (loc_info),
+ m_desc (xstrdup (desc))
+ {
+ }
+ ~precanned_custom_event ()
+ {
+ free (m_desc);
+ }
+
+ label_text get_desc (bool) const final override;
+
+private:
+ char *m_desc;
+};
+
+/* A concrete event subclass describing the execution of a gimple statement,
+ for use at high verbosity levels when debugging paths. */
+
+class statement_event : public checker_event
+{
+public:
+ statement_event (const gimple *stmt, tree fndecl, int depth,
+ const program_state &dst_state);
+
+ label_text get_desc (bool) const final override;
+
+ const gimple * const m_stmt;
+ const program_state m_dst_state;
+};
+
+/* An abstract event subclass describing the creation of a region that
+ is significant for a diagnostic.
+
+ There are too many combinations to express region creation in one message,
+ so we emit multiple region_creation_event instances when each pertinent
+ region is created.
+
+ The events are created by pending_diagnostic's add_region_creation_events
+ vfunc, which by default creates a region_creation_event_memory_space, and
+ if a capacity is known, a region_creation_event_capacity, giving e.g.:
+ (1) region created on stack here
+ (2) capacity: 100 bytes
+ but this vfunc can be overridden to create other events if other wordings
+ are more appropriate foa a given pending_diagnostic. */
+
+class region_creation_event : public checker_event
+{
+protected:
+ region_creation_event (const event_loc_info &loc_info);
+};
+
+/* Concrete subclass of region_creation_event.
+ Generates a message based on the memory space of the region
+ e.g. "region created on stack here". */
+
+class region_creation_event_memory_space : public region_creation_event
+{
+public:
+ region_creation_event_memory_space (enum memory_space mem_space,
+ const event_loc_info &loc_info)
+ : region_creation_event (loc_info),
+ m_mem_space (mem_space)
+ {
+ }
+
+ label_text get_desc (bool can_colorize) const final override;
+
+private:
+ enum memory_space m_mem_space;
+};
+
+/* Concrete subclass of region_creation_event.
+ Generates a message based on the capacity of the region
+ e.g. "capacity: 100 bytes". */
+
+class region_creation_event_capacity : public region_creation_event
+{
+public:
+ region_creation_event_capacity (tree capacity,
+ const event_loc_info &loc_info)
+ : region_creation_event (loc_info),
+ m_capacity (capacity)
+ {
+ gcc_assert (m_capacity);
+ }
+
+ label_text get_desc (bool can_colorize) const final override;
+
+private:
+ tree m_capacity;
+};
+
+/* Concrete subclass of region_creation_event.
+ Generates a message based on the capacity of the region
+ e.g. "allocated 100 bytes here". */
+
+class region_creation_event_allocation_size : public region_creation_event
+{
+public:
+ region_creation_event_allocation_size (tree capacity,
+ const event_loc_info &loc_info)
+ : region_creation_event (loc_info),
+ m_capacity (capacity)
+ {}
+
+ label_text get_desc (bool can_colorize) const final override;
+
+private:
+ tree m_capacity;
+};
+
+/* Concrete subclass of region_creation_event.
+ Generates a debug message intended for analyzer developers. */
+
+class region_creation_event_debug : public region_creation_event
+{
+public:
+ region_creation_event_debug (const region *reg, tree capacity,
+ const event_loc_info &loc_info)
+ : region_creation_event (loc_info),
+ m_reg (reg), m_capacity (capacity)
+ {
+ }
+
+ label_text get_desc (bool can_colorize) const final override;
+
+private:
+ const region *m_reg;
+ tree m_capacity;
+};
+
+/* An event subclass describing the entry to a function. */
+
+class function_entry_event : public checker_event
+{
+public:
+ function_entry_event (const event_loc_info &loc_info)
+ : checker_event (EK_FUNCTION_ENTRY, loc_info)
+ {
+ }
+
+ function_entry_event (const program_point &dst_point);
+
+ label_text get_desc (bool can_colorize) const override;
+ meaning get_meaning () const override;
+
+ bool is_function_entry_p () const final override { return true; }
+};
+
+/* Subclass of checker_event describing a state change. */
+
+class state_change_event : public checker_event
+{
+public:
+ state_change_event (const supernode *node, const gimple *stmt,
+ int stack_depth,
+ const state_machine &sm,
+ const svalue *sval,
+ state_machine::state_t from,
+ state_machine::state_t to,
+ const svalue *origin,
+ const program_state &dst_state);
+
+ label_text get_desc (bool can_colorize) const final override;
+ meaning get_meaning () const override;
+
+ function *get_dest_function () const
+ {
+ return m_dst_state.get_current_function ();
+ }
+
+ const supernode *m_node;
+ const gimple *m_stmt;
+ const state_machine &m_sm;
+ const svalue *m_sval;
+ state_machine::state_t m_from;
+ state_machine::state_t m_to;
+ const svalue *m_origin;
+ program_state m_dst_state;
+};
+
+/* Subclass of checker_event; parent class for subclasses that relate to
+ a superedge. */
+
+class superedge_event : public checker_event
+{
+public:
+ /* Mark this edge event as being either an interprocedural call or
+ return in which VAR is in STATE, and that this is critical to the
+ diagnostic (so that get_desc can attempt to get a better description
+ from any pending_diagnostic). */
+ void record_critical_state (tree var, state_machine::state_t state)
+ {
+ m_var = var;
+ m_critical_state = state;
+ }
+
+ const callgraph_superedge& get_callgraph_superedge () const;
+
+ bool should_filter_p (int verbosity) const;
+
+ protected:
+ superedge_event (enum event_kind kind, const exploded_edge &eedge,
+ const event_loc_info &loc_info);
+
+ public:
+ const exploded_edge &m_eedge;
+ const superedge *m_sedge;
+ tree m_var;
+ state_machine::state_t m_critical_state;
+};
+
+/* An abstract event subclass for when a CFG edge is followed; it has two
+ subclasses, representing the start of the edge and the end of the
+ edge, which come in pairs. */
+
+class cfg_edge_event : public superedge_event
+{
+public:
+ meaning get_meaning () const override;
+
+ const cfg_superedge& get_cfg_superedge () const;
+
+ protected:
+ cfg_edge_event (enum event_kind kind, const exploded_edge &eedge,
+ const event_loc_info &loc_info);
+};
+
+/* A concrete event subclass for the start of a CFG edge
+ e.g. "following 'false' branch...'. */
+
+class start_cfg_edge_event : public cfg_edge_event
+{
+public:
+ start_cfg_edge_event (const exploded_edge &eedge,
+ const event_loc_info &loc_info)
+ : cfg_edge_event (EK_START_CFG_EDGE, eedge, loc_info)
+ {
+ }
+
+ label_text get_desc (bool can_colorize) const final override;
+
+ private:
+ label_text maybe_describe_condition (bool can_colorize) const;
+
+ static label_text maybe_describe_condition (bool can_colorize,
+ tree lhs,
+ enum tree_code op,
+ tree rhs);
+ static bool should_print_expr_p (tree);
+};
+
+/* A concrete event subclass for the end of a CFG edge
+ e.g. "...to here'. */
+
+class end_cfg_edge_event : public cfg_edge_event
+{
+public:
+ end_cfg_edge_event (const exploded_edge &eedge,
+ const event_loc_info &loc_info)
+ : cfg_edge_event (EK_END_CFG_EDGE, eedge, loc_info)
+ {
+ }
+
+ label_text get_desc (bool /*can_colorize*/) const final override
+ {
+ return label_text::borrow ("...to here");
+ }
+};
+
+/* A concrete event subclass for an interprocedural call. */
+
+class call_event : public superedge_event
+{
+public:
+ call_event (const exploded_edge &eedge,
+ const event_loc_info &loc_info);
+
+ label_text get_desc (bool can_colorize) const override;
+ meaning get_meaning () const override;
+
+ bool is_call_p () const final override;
+
+protected:
+ tree get_caller_fndecl () const;
+ tree get_callee_fndecl () const;
+
+ const supernode *m_src_snode;
+ const supernode *m_dest_snode;
+};
+
+/* A concrete event subclass for an interprocedural return. */
+
+class return_event : public superedge_event
+{
+public:
+ return_event (const exploded_edge &eedge,
+ const event_loc_info &loc_info);
+
+ label_text get_desc (bool can_colorize) const final override;
+ meaning get_meaning () const override;
+
+ bool is_return_p () const final override;
+
+ const supernode *m_src_snode;
+ const supernode *m_dest_snode;
+};
+
+/* A concrete event subclass for the start of a consolidated run of CFG
+ edges all either TRUE or FALSE e.g. "following 'false' branch...'. */
+
+class start_consolidated_cfg_edges_event : public checker_event
+{
+public:
+ start_consolidated_cfg_edges_event (const event_loc_info &loc_info,
+ bool edge_sense)
+ : checker_event (EK_START_CONSOLIDATED_CFG_EDGES, loc_info),
+ m_edge_sense (edge_sense)
+ {
+ }
+
+ label_text get_desc (bool can_colorize) const final override;
+ meaning get_meaning () const override;
+
+ private:
+ bool m_edge_sense;
+};
+
+/* A concrete event subclass for the end of a consolidated run of
+ CFG edges e.g. "...to here'. */
+
+class end_consolidated_cfg_edges_event : public checker_event
+{
+public:
+ end_consolidated_cfg_edges_event (const event_loc_info &loc_info)
+ : checker_event (EK_END_CONSOLIDATED_CFG_EDGES, loc_info)
+ {
+ }
+
+ label_text get_desc (bool /*can_colorize*/) const final override
+ {
+ return label_text::borrow ("...to here");
+ }
+};
+
+/* A concrete event subclass for describing an inlined call event
+ e.g. "inlined call to 'callee' from 'caller'". */
+
+class inlined_call_event : public checker_event
+{
+public:
+ inlined_call_event (location_t loc,
+ tree apparent_callee_fndecl,
+ tree apparent_caller_fndecl,
+ int actual_depth,
+ int stack_depth_adjustment)
+ : checker_event (EK_INLINED_CALL,
+ event_loc_info (loc,
+ apparent_caller_fndecl,
+ actual_depth + stack_depth_adjustment)),
+ m_apparent_callee_fndecl (apparent_callee_fndecl),
+ m_apparent_caller_fndecl (apparent_caller_fndecl)
+ {
+ gcc_assert (LOCATION_BLOCK (loc) == NULL);
+ }
+
+ label_text get_desc (bool /*can_colorize*/) const final override;
+ meaning get_meaning () const override;
+
+private:
+ tree m_apparent_callee_fndecl;
+ tree m_apparent_caller_fndecl;
+};
+
+/* A concrete event subclass for a setjmp or sigsetjmp call. */
+
+class setjmp_event : public checker_event
+{
+public:
+ setjmp_event (const event_loc_info &loc_info,
+ const exploded_node *enode,
+ const gcall *setjmp_call)
+ : checker_event (EK_SETJMP, loc_info),
+ m_enode (enode), m_setjmp_call (setjmp_call)
+ {
+ }
+
+ label_text get_desc (bool can_colorize) const final override;
+
+ void prepare_for_emission (checker_path *path,
+ pending_diagnostic *pd,
+ diagnostic_event_id_t emission_id) final override;
+
+private:
+ const exploded_node *m_enode;
+ const gcall *m_setjmp_call;
+};
+
+/* An abstract event subclass for rewinding from a longjmp to a setjmp
+ (or siglongjmp to sigsetjmp).
+
+ Base class for two from/to subclasses, showing the two halves of the
+ rewind. */
+
+class rewind_event : public checker_event
+{
+public:
+ tree get_longjmp_caller () const;
+ tree get_setjmp_caller () const;
+ const exploded_edge *get_eedge () const { return m_eedge; }
+
+ protected:
+ rewind_event (const exploded_edge *eedge,
+ enum event_kind kind,
+ const event_loc_info &loc_info,
+ const rewind_info_t *rewind_info);
+ const rewind_info_t *m_rewind_info;
+
+ private:
+ const exploded_edge *m_eedge;
+};
+
+/* A concrete event subclass for rewinding from a longjmp to a setjmp,
+ showing the longjmp (or siglongjmp). */
+
+class rewind_from_longjmp_event : public rewind_event
+{
+public:
+ rewind_from_longjmp_event (const exploded_edge *eedge,
+ const event_loc_info &loc_info,
+ const rewind_info_t *rewind_info)
+ : rewind_event (eedge, EK_REWIND_FROM_LONGJMP, loc_info,
+ rewind_info)
+ {
+ }
+
+ label_text get_desc (bool can_colorize) const final override;
+};
+
+/* A concrete event subclass for rewinding from a longjmp to a setjmp,
+ showing the setjmp (or sigsetjmp). */
+
+class rewind_to_setjmp_event : public rewind_event
+{
+public:
+ rewind_to_setjmp_event (const exploded_edge *eedge,
+ const event_loc_info &loc_info,
+ const rewind_info_t *rewind_info)
+ : rewind_event (eedge, EK_REWIND_TO_SETJMP, loc_info,
+ rewind_info)
+ {
+ }
+
+ label_text get_desc (bool can_colorize) const final override;
+
+ void prepare_for_emission (checker_path *path,
+ pending_diagnostic *pd,
+ diagnostic_event_id_t emission_id) final override;
+
+private:
+ diagnostic_event_id_t m_original_setjmp_event_id;
+};
+
+/* Concrete subclass of checker_event for use at the end of a path:
+ a repeat of the warning message at the end of the path (perhaps with
+ references to pertinent events that occurred on the way), at the point
+ where the problem occurs. */
+
+class warning_event : public checker_event
+{
+public:
+ warning_event (const event_loc_info &loc_info,
+ const state_machine *sm,
+ tree var, state_machine::state_t state)
+ : checker_event (EK_WARNING, loc_info),
+ m_sm (sm), m_var (var), m_state (state)
+ {
+ }
+
+ label_text get_desc (bool can_colorize) const final override;
+ meaning get_meaning () const override;
+
+private:
+ const state_machine *m_sm;
+ tree m_var;
+ state_machine::state_t m_state;
+};
+
+} // namespace ana
+
+#endif /* GCC_ANALYZER_CHECKER_EVENT_H */
diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc
index 371111b..c229e46 100644
--- a/gcc/analyzer/checker-path.cc
+++ b/gcc/analyzer/checker-path.cc
@@ -1,4 +1,4 @@
-/* Subclasses of diagnostic_path and diagnostic_event for analyzer diagnostics.
+/* Subclass of diagnostic_path for analyzer diagnostics.
Copyright (C) 2019-2022 Free Software Foundation, Inc.
Contributed by David Malcolm <dmalcolm@redhat.com>.
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
@@ -55,1137 +56,12 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/diagnostic-manager.h"
#include "analyzer/checker-path.h"
#include "analyzer/exploded-graph.h"
+#include "make-unique.h"
#if ENABLE_ANALYZER
namespace ana {
-/* Get a string for EK. */
-
-const char *
-event_kind_to_string (enum event_kind ek)
-{
- switch (ek)
- {
- default:
- gcc_unreachable ();
- case EK_DEBUG:
- return "EK_DEBUG";
- case EK_CUSTOM:
- return "EK_CUSTOM";
- case EK_STMT:
- return "EK_STMT";
- case EK_REGION_CREATION:
- return "EK_REGION_CREATION";
- case EK_FUNCTION_ENTRY:
- return "EK_FUNCTION_ENTRY";
- case EK_STATE_CHANGE:
- return "EK_STATE_CHANGE";
- case EK_START_CFG_EDGE:
- return "EK_START_CFG_EDGE";
- case EK_END_CFG_EDGE:
- return "EK_END_CFG_EDGE";
- case EK_CALL_EDGE:
- return "EK_CALL_EDGE";
- case EK_RETURN_EDGE:
- return "EK_RETURN_EDGE";
- case EK_START_CONSOLIDATED_CFG_EDGES:
- return "EK_START_CONSOLIDATED_CFG_EDGES";
- case EK_END_CONSOLIDATED_CFG_EDGES:
- return "EK_END_CONSOLIDATED_CFG_EDGES";
- case EK_INLINED_CALL:
- return "EK_INLINED_CALL";
- case EK_SETJMP:
- return "EK_SETJMP";
- case EK_REWIND_FROM_LONGJMP:
- return "EK_REWIND_FROM_LONGJMP";
- case EK_REWIND_TO_SETJMP:
- return "EK_REWIND_TO_SETJMP";
- case EK_WARNING:
- return "EK_WARNING";
- }
-}
-
-/* A class for fixing up fndecls and stack depths in checker_event, based
- on inlining records.
-
- The early inliner runs before the analyzer, which can lead to confusing
- output.
-
- Tne base fndecl and depth within a checker_event are from call strings
- in program_points, which reflect the call strings after inlining.
- This class lets us offset the depth and fix up the reported fndecl and
- stack depth to better reflect the user's original code. */
-
-class inlining_info
-{
-public:
- inlining_info (location_t loc)
- {
- inlining_iterator iter (loc);
- m_inner_fndecl = iter.get_fndecl ();
- int num_frames = 0;
- while (!iter.done_p ())
- {
- m_outer_fndecl = iter.get_fndecl ();
- num_frames++;
- iter.next ();
- }
- if (num_frames > 1)
- m_extra_frames = num_frames - 1;
- else
- m_extra_frames = 0;
- }
-
- tree get_inner_fndecl () const { return m_inner_fndecl; }
- int get_extra_frames () const { return m_extra_frames; }
-
-private:
- tree m_outer_fndecl;
- tree m_inner_fndecl;
- int m_extra_frames;
-};
-
-/* class checker_event : public diagnostic_event. */
-
-/* checker_event's ctor. */
-
-checker_event::checker_event (enum event_kind kind,
- location_t loc, tree fndecl, int depth)
-: m_kind (kind), m_loc (loc),
- m_original_fndecl (fndecl), m_effective_fndecl (fndecl),
- m_original_depth (depth), m_effective_depth (depth),
- m_pending_diagnostic (NULL), m_emission_id (),
- m_logical_loc (fndecl)
-{
- /* Update effective fndecl and depth if inlining has been recorded. */
- if (flag_analyzer_undo_inlining)
- {
- inlining_info info (loc);
- if (info.get_inner_fndecl ())
- {
- m_effective_fndecl = info.get_inner_fndecl ();
- m_effective_depth += info.get_extra_frames ();
- m_logical_loc = tree_logical_location (m_effective_fndecl);
- }
- }
-}
-
-/* No-op implementation of diagnostic_event::get_meaning vfunc for
- checker_event: checker events have no meaning by default. */
-
-diagnostic_event::meaning
-checker_event::get_meaning () const
-{
- return meaning ();
-}
-
-/* Dump this event to PP (for debugging/logging purposes). */
-
-void
-checker_event::dump (pretty_printer *pp) const
-{
- label_text event_desc (get_desc (false));
- pp_printf (pp, "\"%s\" (depth %i",
- event_desc.get (), m_effective_depth);
-
- if (m_effective_depth != m_original_depth)
- pp_printf (pp, " corrected from %i",
- m_original_depth);
- if (m_effective_fndecl)
- {
- pp_printf (pp, ", fndecl %qE", m_effective_fndecl);
- if (m_effective_fndecl != m_original_fndecl)
- pp_printf (pp, " corrected from %qE", m_original_fndecl);
- }
- pp_printf (pp, ", m_loc=%x)",
- get_location ());
-}
-
-/* Hook for being notified when this event has its final id EMISSION_ID
- and is about to emitted for PD.
-
- Base implementation of checker_event::prepare_for_emission vfunc;
- subclasses that override this should chain up to it.
-
- Record PD and EMISSION_ID, and call the get_desc vfunc, so that any
- side-effects of the call to get_desc take place before
- pending_diagnostic::emit is called.
-
- For example, state_change_event::get_desc can call
- pending_diagnostic::describe_state_change; free_of_non_heap can use this
- to tweak the message (TODO: would be neater to simply capture the
- pertinent data within the sm-state). */
-
-void
-checker_event::prepare_for_emission (checker_path *,
- pending_diagnostic *pd,
- diagnostic_event_id_t emission_id)
-{
- m_pending_diagnostic = pd;
- m_emission_id = emission_id;
-
- label_text desc = get_desc (false);
-}
-
-/* class debug_event : public checker_event. */
-
-/* Implementation of diagnostic_event::get_desc vfunc for
- debug_event.
- Use the saved string as the event's description. */
-
-label_text
-debug_event::get_desc (bool) const
-{
- return label_text::borrow (m_desc);
-}
-
-/* class precanned_custom_event : public custom_event. */
-
-/* Implementation of diagnostic_event::get_desc vfunc for
- precanned_custom_event.
- Use the saved string as the event's description. */
-
-label_text
-precanned_custom_event::get_desc (bool) const
-{
- return label_text::borrow (m_desc);
-}
-
-/* class statement_event : public checker_event. */
-
-/* statement_event's ctor. */
-
-statement_event::statement_event (const gimple *stmt, tree fndecl, int depth,
- const program_state &dst_state)
-: checker_event (EK_STMT, gimple_location (stmt), fndecl, depth),
- m_stmt (stmt),
- m_dst_state (dst_state)
-{
-}
-
-/* Implementation of diagnostic_event::get_desc vfunc for
- statement_event.
- Use the statement's dump form as the event's description. */
-
-label_text
-statement_event::get_desc (bool) const
-{
- pretty_printer pp;
- pp_string (&pp, "stmt: ");
- pp_gimple_stmt_1 (&pp, m_stmt, 0, (dump_flags_t)0);
- return label_text::take (xstrdup (pp_formatted_text (&pp)));
-}
-
-/* class region_creation_event : public checker_event. */
-
-region_creation_event::region_creation_event (const region *reg,
- tree capacity,
- enum rce_kind kind,
- location_t loc,
- tree fndecl,
- int depth)
-: checker_event (EK_REGION_CREATION, loc, fndecl, depth),
- m_reg (reg),
- m_capacity (capacity),
- m_rce_kind (kind)
-{
- if (m_rce_kind == RCE_CAPACITY)
- gcc_assert (capacity);
-}
-
-/* Implementation of diagnostic_event::get_desc vfunc for
- region_creation_event.
- There are effectively 3 kinds of region_region_event, to
- avoid combinatorial explosion by trying to convy the
- information in a single message. */
-
-label_text
-region_creation_event::get_desc (bool can_colorize) const
-{
- if (m_pending_diagnostic)
- {
- label_text custom_desc
- = m_pending_diagnostic->describe_region_creation_event
- (evdesc::region_creation (can_colorize, m_reg));
- if (custom_desc.get ())
- return custom_desc;
- }
-
- switch (m_rce_kind)
- {
- default:
- gcc_unreachable ();
-
- case RCE_MEM_SPACE:
- switch (m_reg->get_memory_space ())
- {
- default:
- return label_text::borrow ("region created here");
- case MEMSPACE_STACK:
- return label_text::borrow ("region created on stack here");
- case MEMSPACE_HEAP:
- return label_text::borrow ("region created on heap here");
- }
- break;
-
- case RCE_CAPACITY:
- gcc_assert (m_capacity);
- if (TREE_CODE (m_capacity) == INTEGER_CST)
- {
- unsigned HOST_WIDE_INT hwi = tree_to_uhwi (m_capacity);
- if (hwi == 1)
- return make_label_text (can_colorize,
- "capacity: %wu byte", hwi);
- else
- return make_label_text (can_colorize,
- "capacity: %wu bytes", hwi);
- }
- else
- return make_label_text (can_colorize,
- "capacity: %qE bytes", m_capacity);
-
- case RCE_DEBUG:
- {
- pretty_printer pp;
- pp_format_decoder (&pp) = default_tree_printer;
- pp_string (&pp, "region creation: ");
- m_reg->dump_to_pp (&pp, true);
- if (m_capacity)
- pp_printf (&pp, " capacity: %qE", m_capacity);
- return label_text::take (xstrdup (pp_formatted_text (&pp)));
- }
- break;
- }
-}
-
-/* class function_entry_event : public checker_event. */
-
-/* Implementation of diagnostic_event::get_desc vfunc for
- function_entry_event.
-
- Use a string such as "entry to 'foo'" as the event's description. */
-
-label_text
-function_entry_event::get_desc (bool can_colorize) const
-{
- return make_label_text (can_colorize, "entry to %qE", m_effective_fndecl);
-}
-
-/* Implementation of diagnostic_event::get_meaning vfunc for
- function entry. */
-
-diagnostic_event::meaning
-function_entry_event::get_meaning () const
-{
- return meaning (VERB_enter, NOUN_function);
-}
-
-/* class state_change_event : public checker_event. */
-
-/* state_change_event's ctor. */
-
-state_change_event::state_change_event (const supernode *node,
- const gimple *stmt,
- int stack_depth,
- const state_machine &sm,
- const svalue *sval,
- state_machine::state_t from,
- state_machine::state_t to,
- const svalue *origin,
- const program_state &dst_state)
-: checker_event (EK_STATE_CHANGE,
- stmt->location, node->m_fun->decl,
- stack_depth),
- m_node (node), m_stmt (stmt), m_sm (sm),
- m_sval (sval), m_from (from), m_to (to),
- m_origin (origin),
- m_dst_state (dst_state)
-{
-}
-
-/* Implementation of diagnostic_event::get_desc vfunc for
- state_change_event.
-
- Attempt to generate a nicer human-readable description.
- For greatest precision-of-wording, give the pending diagnostic
- a chance to describe this state change (in terms of the
- diagnostic).
- Note that we only have a pending_diagnostic set on the event once
- the diagnostic is about to being emitted, so the description for
- an event can change. */
-
-label_text
-state_change_event::get_desc (bool can_colorize) const
-{
- if (m_pending_diagnostic)
- {
- region_model *model = m_dst_state.m_region_model;
- tree var = model->get_representative_tree (m_sval);
- tree origin = model->get_representative_tree (m_origin);
- label_text custom_desc
- = m_pending_diagnostic->describe_state_change
- (evdesc::state_change (can_colorize, var, origin,
- m_from, m_to, m_emission_id, *this));
- if (custom_desc.get ())
- {
- if (flag_analyzer_verbose_state_changes)
- {
- /* Get any "meaning" of event. */
- diagnostic_event::meaning meaning = get_meaning ();
- pretty_printer meaning_pp;
- meaning.dump_to_pp (&meaning_pp);
-
- /* Append debug version. */
- if (m_origin)
- return make_label_text
- (can_colorize,
- "%s (state of %qE: %qs -> %qs, origin: %qE, meaning: %s)",
- custom_desc.get (),
- var,
- m_from->get_name (),
- m_to->get_name (),
- origin,
- pp_formatted_text (&meaning_pp));
- else
- return make_label_text
- (can_colorize,
- "%s (state of %qE: %qs -> %qs, NULL origin, meaning: %s)",
- custom_desc.get (),
- var,
- m_from->get_name (),
- m_to->get_name (),
- pp_formatted_text (&meaning_pp));
- }
- else
- return custom_desc;
- }
- }
-
- /* Fallback description. */
- if (m_sval)
- {
- label_text sval_desc = m_sval->get_desc ();
- if (m_origin)
- {
- label_text origin_desc = m_origin->get_desc ();
- return make_label_text
- (can_colorize,
- "state of %qs: %qs -> %qs (origin: %qs)",
- sval_desc.get (),
- m_from->get_name (),
- m_to->get_name (),
- origin_desc.get ());
- }
- else
- return make_label_text
- (can_colorize,
- "state of %qs: %qs -> %qs (NULL origin)",
- sval_desc.get (),
- m_from->get_name (),
- m_to->get_name ());
- }
- else
- {
- gcc_assert (m_origin == NULL);
- return make_label_text
- (can_colorize,
- "global state: %qs -> %qs",
- m_from->get_name (),
- m_to->get_name ());
- }
-}
-
-/* Implementation of diagnostic_event::get_meaning vfunc for
- state change events: delegate to the pending_diagnostic to
- get any meaning. */
-
-diagnostic_event::meaning
-state_change_event::get_meaning () const
-{
- if (m_pending_diagnostic)
- {
- region_model *model = m_dst_state.m_region_model;
- tree var = model->get_representative_tree (m_sval);
- tree origin = model->get_representative_tree (m_origin);
- return m_pending_diagnostic->get_meaning_for_state_change
- (evdesc::state_change (false, var, origin,
- m_from, m_to, m_emission_id, *this));
- }
- else
- return meaning ();
-}
-
-/* class superedge_event : public checker_event. */
-
-/* Get the callgraph_superedge for this superedge_event, which must be
- for an interprocedural edge, rather than a CFG edge. */
-
-const callgraph_superedge&
-superedge_event::get_callgraph_superedge () const
-{
- gcc_assert (m_sedge->m_kind != SUPEREDGE_CFG_EDGE);
- return *m_sedge->dyn_cast_callgraph_superedge ();
-}
-
-/* Determine if this event should be filtered at the given verbosity
- level. */
-
-bool
-superedge_event::should_filter_p (int verbosity) const
-{
- switch (m_sedge->m_kind)
- {
- case SUPEREDGE_CFG_EDGE:
- {
- if (verbosity < 2)
- return true;
-
- if (verbosity < 4)
- {
- /* Filter events with empty descriptions. This ought to filter
- FALLTHRU, but retain true/false/switch edges. */
- label_text desc = get_desc (false);
- gcc_assert (desc.get ());
- if (desc.get ()[0] == '\0')
- return true;
- }
- }
- break;
-
- default:
- break;
- }
- return false;
-}
-
-/* superedge_event's ctor. */
-
-superedge_event::superedge_event (enum event_kind kind,
- const exploded_edge &eedge,
- location_t loc, tree fndecl, int depth)
-: checker_event (kind, loc, fndecl, depth),
- m_eedge (eedge), m_sedge (eedge.m_sedge),
- m_var (NULL_TREE), m_critical_state (0)
-{
-}
-
-/* class cfg_edge_event : public superedge_event. */
-
-/* Get the cfg_superedge for this cfg_edge_event. */
-
-const cfg_superedge &
-cfg_edge_event::get_cfg_superedge () const
-{
- return *m_sedge->dyn_cast_cfg_superedge ();
-}
-
-/* cfg_edge_event's ctor. */
-
-cfg_edge_event::cfg_edge_event (enum event_kind kind,
- const exploded_edge &eedge,
- location_t loc, tree fndecl, int depth)
-: superedge_event (kind, eedge, loc, fndecl, depth)
-{
- gcc_assert (eedge.m_sedge->m_kind == SUPEREDGE_CFG_EDGE);
-}
-
-/* Implementation of diagnostic_event::get_meaning vfunc for
- CFG edge events. */
-
-diagnostic_event::meaning
-cfg_edge_event::get_meaning () const
-{
- const cfg_superedge& cfg_sedge = get_cfg_superedge ();
- if (cfg_sedge.true_value_p ())
- return meaning (VERB_branch, PROPERTY_true);
- else if (cfg_sedge.false_value_p ())
- return meaning (VERB_branch, PROPERTY_false);
- else
- return meaning ();
-}
-
-/* class start_cfg_edge_event : public cfg_edge_event. */
-
-/* Implementation of diagnostic_event::get_desc vfunc for
- start_cfg_edge_event.
-
- If -fanalyzer-verbose-edges, then generate low-level descriptions, such
- as
- "taking 'true' edge SN:7 -> SN:8".
-
- Otherwise, generate strings using the label of the underlying CFG if
- any, such as:
- "following 'true' branch..." or
- "following 'case 3' branch..."
- "following 'default' branch..."
-
- For conditionals, attempt to supply a description of the condition that
- holds, such as:
- "following 'false' branch (when 'ptr' is non-NULL)..."
-
- Failing that, return an empty description (which will lead to this event
- being filtered). */
-
-label_text
-start_cfg_edge_event::get_desc (bool can_colorize) const
-{
- bool user_facing = !flag_analyzer_verbose_edges;
- label_text edge_desc (m_sedge->get_description (user_facing));
- if (user_facing)
- {
- if (edge_desc.get () && strlen (edge_desc.get ()) > 0)
- {
- label_text cond_desc = maybe_describe_condition (can_colorize);
- label_text result;
- if (cond_desc.get ())
- return make_label_text (can_colorize,
- "following %qs branch (%s)...",
- edge_desc.get (), cond_desc.get ());
- else
- return make_label_text (can_colorize,
- "following %qs branch...",
- edge_desc.get ());
- }
- else
- return label_text::borrow ("");
- }
- else
- {
- if (strlen (edge_desc.get ()) > 0)
- return make_label_text (can_colorize,
- "taking %qs edge SN:%i -> SN:%i",
- edge_desc.get (),
- m_sedge->m_src->m_index,
- m_sedge->m_dest->m_index);
- else
- return make_label_text (can_colorize,
- "taking edge SN:%i -> SN:%i",
- m_sedge->m_src->m_index,
- m_sedge->m_dest->m_index);
- }
-}
-
-/* Attempt to generate a description of any condition that holds at this edge.
-
- The intent is to make the user-facing messages more clear, especially for
- cases where there's a single or double-negative, such as
- when describing the false branch of an inverted condition.
-
- For example, rather than printing just:
-
- | if (!ptr)
- | ~
- | |
- | (1) following 'false' branch...
-
- it's clearer to spell out the condition that holds:
-
- | if (!ptr)
- | ~
- | |
- | (1) following 'false' branch (when 'ptr' is non-NULL)...
- ^^^^^^^^^^^^^^^^^^^^^^
-
- In the above example, this function would generate the highlighted
- string: "when 'ptr' is non-NULL".
-
- If the edge is not a condition, or it's not clear that a description of
- the condition would be helpful to the user, return NULL. */
-
-label_text
-start_cfg_edge_event::maybe_describe_condition (bool can_colorize) const
-{
- const cfg_superedge& cfg_sedge = get_cfg_superedge ();
-
- if (cfg_sedge.true_value_p () || cfg_sedge.false_value_p ())
- {
- const gimple *last_stmt = m_sedge->m_src->get_last_stmt ();
- if (const gcond *cond_stmt = dyn_cast <const gcond *> (last_stmt))
- {
- enum tree_code op = gimple_cond_code (cond_stmt);
- tree lhs = gimple_cond_lhs (cond_stmt);
- tree rhs = gimple_cond_rhs (cond_stmt);
- if (cfg_sedge.false_value_p ())
- op = invert_tree_comparison (op, false /* honor_nans */);
- return maybe_describe_condition (can_colorize,
- lhs, op, rhs);
- }
- }
- return label_text::borrow (NULL);
-}
-
-/* Subroutine of maybe_describe_condition above.
-
- Attempt to generate a user-facing description of the condition
- LHS OP RHS, but only if it is likely to make it easier for the
- user to understand a condition. */
-
-label_text
-start_cfg_edge_event::maybe_describe_condition (bool can_colorize,
- tree lhs,
- enum tree_code op,
- tree rhs)
-{
- /* In theory we could just build a tree via
- fold_build2 (op, boolean_type_node, lhs, rhs)
- and print it with %qE on it, but this leads to warts such as
- parenthesizing vars, such as '(i) <= 9', and uses of '<unknown>'. */
-
- /* Special-case: describe testing the result of strcmp, as figuring
- out what the "true" or "false" path is can be confusing to the user. */
- if (TREE_CODE (lhs) == SSA_NAME
- && zerop (rhs))
- {
- if (gcall *call = dyn_cast <gcall *> (SSA_NAME_DEF_STMT (lhs)))
- if (is_special_named_call_p (call, "strcmp", 2))
- {
- if (op == EQ_EXPR)
- return label_text::borrow ("when the strings are equal");
- if (op == NE_EXPR)
- return label_text::borrow ("when the strings are non-equal");
- }
- }
-
- /* Only attempt to generate text for sufficiently simple expressions. */
- if (!should_print_expr_p (lhs))
- return label_text::borrow (NULL);
- if (!should_print_expr_p (rhs))
- return label_text::borrow (NULL);
-
- /* Special cases for pointer comparisons against NULL. */
- if (POINTER_TYPE_P (TREE_TYPE (lhs))
- && POINTER_TYPE_P (TREE_TYPE (rhs))
- && zerop (rhs))
- {
- if (op == EQ_EXPR)
- return make_label_text (can_colorize, "when %qE is NULL",
- lhs);
- if (op == NE_EXPR)
- return make_label_text (can_colorize, "when %qE is non-NULL",
- lhs);
- }
-
- return make_label_text (can_colorize, "when %<%E %s %E%>",
- lhs, op_symbol_code (op), rhs);
-}
-
-/* Subroutine of maybe_describe_condition.
-
- Return true if EXPR is we will get suitable user-facing output
- from %E on it. */
-
-bool
-start_cfg_edge_event::should_print_expr_p (tree expr)
-{
- if (TREE_CODE (expr) == SSA_NAME)
- {
- if (SSA_NAME_VAR (expr))
- return should_print_expr_p (SSA_NAME_VAR (expr));
- else
- return false;
- }
-
- if (DECL_P (expr))
- return true;
-
- if (CONSTANT_CLASS_P (expr))
- return true;
-
- return false;
-}
-
-/* class call_event : public superedge_event. */
-
-/* call_event's ctor. */
-
-call_event::call_event (const exploded_edge &eedge,
- location_t loc, tree fndecl, int depth)
-: superedge_event (EK_CALL_EDGE, eedge, loc, fndecl, depth)
-{
- if (eedge.m_sedge)
- gcc_assert (eedge.m_sedge->m_kind == SUPEREDGE_CALL);
-
- m_src_snode = eedge.m_src->get_supernode ();
- m_dest_snode = eedge.m_dest->get_supernode ();
-}
-
-/* Implementation of diagnostic_event::get_desc vfunc for
- call_event.
-
- If this call event passes critical state for an sm-based warning,
- allow the diagnostic to generate a precise description, such as:
-
- "passing freed pointer 'ptr' in call to 'foo' from 'bar'"
-
- Otherwise, generate a description of the form
- "calling 'foo' from 'bar'". */
-
-label_text
-call_event::get_desc (bool can_colorize) const
-{
- if (m_critical_state && m_pending_diagnostic)
- {
- gcc_assert (m_var);
- tree var = fixup_tree_for_diagnostic (m_var);
- label_text custom_desc
- = m_pending_diagnostic->describe_call_with_state
- (evdesc::call_with_state (can_colorize,
- m_src_snode->m_fun->decl,
- m_dest_snode->m_fun->decl,
- var,
- m_critical_state));
- if (custom_desc.get ())
- return custom_desc;
- }
-
- return make_label_text (can_colorize,
- "calling %qE from %qE",
- get_callee_fndecl (),
- get_caller_fndecl ());
-}
-
-/* Implementation of diagnostic_event::get_meaning vfunc for
- function call events. */
-
-diagnostic_event::meaning
-call_event::get_meaning () const
-{
- return meaning (VERB_call, NOUN_function);
-}
-
-/* Override of checker_event::is_call_p for calls. */
-
-bool
-call_event::is_call_p () const
-{
- return true;
-}
-
-tree
-call_event::get_caller_fndecl () const
-{
- return m_src_snode->m_fun->decl;
-}
-
-tree
-call_event::get_callee_fndecl () const
-{
- return m_dest_snode->m_fun->decl;
-}
-
-/* class return_event : public superedge_event. */
-
-/* return_event's ctor. */
-
-return_event::return_event (const exploded_edge &eedge,
- location_t loc, tree fndecl, int depth)
-: superedge_event (EK_RETURN_EDGE, eedge, loc, fndecl, depth)
-{
- if (eedge.m_sedge)
- gcc_assert (eedge.m_sedge->m_kind == SUPEREDGE_RETURN);
-
- m_src_snode = eedge.m_src->get_supernode ();
- m_dest_snode = eedge.m_dest->get_supernode ();
-}
-
-/* Implementation of diagnostic_event::get_desc vfunc for
- return_event.
-
- If this return event returns critical state for an sm-based warning,
- allow the diagnostic to generate a precise description, such as:
-
- "possible of NULL to 'foo' from 'bar'"
-
- Otherwise, generate a description of the form
- "returning to 'foo' from 'bar'. */
-
-label_text
-return_event::get_desc (bool can_colorize) const
-{
- /* For greatest precision-of-wording, if this is returning the
- state involved in the pending diagnostic, give the pending
- diagnostic a chance to describe this return (in terms of
- itself). */
- if (m_critical_state && m_pending_diagnostic)
- {
- label_text custom_desc
- = m_pending_diagnostic->describe_return_of_state
- (evdesc::return_of_state (can_colorize,
- m_dest_snode->m_fun->decl,
- m_src_snode->m_fun->decl,
- m_critical_state));
- if (custom_desc.get ())
- return custom_desc;
- }
- return make_label_text (can_colorize,
- "returning to %qE from %qE",
- m_dest_snode->m_fun->decl,
- m_src_snode->m_fun->decl);
-}
-
-/* Implementation of diagnostic_event::get_meaning vfunc for
- function return events. */
-
-diagnostic_event::meaning
-return_event::get_meaning () const
-{
- return meaning (VERB_return, NOUN_function);
-}
-
-/* Override of checker_event::is_return_p for returns. */
-
-bool
-return_event::is_return_p () const
-{
- return true;
-}
-
-/* class start_consolidated_cfg_edges_event : public checker_event. */
-
-label_text
-start_consolidated_cfg_edges_event::get_desc (bool can_colorize) const
-{
- return make_label_text (can_colorize,
- "following %qs branch...",
- m_edge_sense ? "true" : "false");
-}
-
-/* Implementation of diagnostic_event::get_meaning vfunc for
- start_consolidated_cfg_edges_event. */
-
-diagnostic_event::meaning
-start_consolidated_cfg_edges_event::get_meaning () const
-{
- return meaning (VERB_branch,
- (m_edge_sense ? PROPERTY_true : PROPERTY_false));
-}
-
-/* class inlined_call_event : public checker_event. */
-
-label_text
-inlined_call_event::get_desc (bool can_colorize) const
-{
- return make_label_text (can_colorize,
- "inlined call to %qE from %qE",
- m_apparent_callee_fndecl,
- m_apparent_caller_fndecl);
-}
-
-/* Implementation of diagnostic_event::get_meaning vfunc for
- reconstructed inlined function calls. */
-
-diagnostic_event::meaning
-inlined_call_event::get_meaning () const
-{
- return meaning (VERB_call, NOUN_function);
-}
-
-/* class setjmp_event : public checker_event. */
-
-/* Implementation of diagnostic_event::get_desc vfunc for
- setjmp_event. */
-
-label_text
-setjmp_event::get_desc (bool can_colorize) const
-{
- return make_label_text (can_colorize,
- "%qs called here",
- get_user_facing_name (m_setjmp_call));
-}
-
-/* Implementation of checker_event::prepare_for_emission vfunc for setjmp_event.
-
- Record this setjmp's event ID into the path, so that rewind events can
- use it. */
-
-void
-setjmp_event::prepare_for_emission (checker_path *path,
- pending_diagnostic *pd,
- diagnostic_event_id_t emission_id)
-{
- checker_event::prepare_for_emission (path, pd, emission_id);
- path->record_setjmp_event (m_enode, emission_id);
-}
-
-/* class rewind_event : public checker_event. */
-
-/* Get the fndecl containing the site of the longjmp call. */
-
-tree
-rewind_event::get_longjmp_caller () const
-{
- return m_eedge->m_src->get_function ()->decl;
-}
-
-/* Get the fndecl containing the site of the setjmp call. */
-
-tree
-rewind_event::get_setjmp_caller () const
-{
- return m_eedge->m_dest->get_function ()->decl;
-}
-
-/* rewind_event's ctor. */
-
-rewind_event::rewind_event (const exploded_edge *eedge,
- enum event_kind kind,
- location_t loc, tree fndecl, int depth,
- const rewind_info_t *rewind_info)
-: checker_event (kind, loc, fndecl, depth),
- m_rewind_info (rewind_info),
- m_eedge (eedge)
-{
- gcc_assert (m_eedge->m_custom_info == m_rewind_info);
-}
-
-/* class rewind_from_longjmp_event : public rewind_event. */
-
-/* Implementation of diagnostic_event::get_desc vfunc for
- rewind_from_longjmp_event. */
-
-label_text
-rewind_from_longjmp_event::get_desc (bool can_colorize) const
-{
- const char *src_name
- = get_user_facing_name (m_rewind_info->get_longjmp_call ());
-
- if (get_longjmp_caller () == get_setjmp_caller ())
- /* Special-case: purely intraprocedural rewind. */
- return make_label_text (can_colorize,
- "rewinding within %qE from %qs...",
- get_longjmp_caller (),
- src_name);
- else
- return make_label_text (can_colorize,
- "rewinding from %qs in %qE...",
- src_name,
- get_longjmp_caller ());
-}
-
-/* class rewind_to_setjmp_event : public rewind_event. */
-
-/* Implementation of diagnostic_event::get_desc vfunc for
- rewind_to_setjmp_event. */
-
-label_text
-rewind_to_setjmp_event::get_desc (bool can_colorize) const
-{
- const char *dst_name
- = get_user_facing_name (m_rewind_info->get_setjmp_call ());
-
- /* If we can, identify the ID of the setjmp_event. */
- if (m_original_setjmp_event_id.known_p ())
- {
- if (get_longjmp_caller () == get_setjmp_caller ())
- /* Special-case: purely intraprocedural rewind. */
- return make_label_text (can_colorize,
- "...to %qs (saved at %@)",
- dst_name,
- &m_original_setjmp_event_id);
- else
- return make_label_text (can_colorize,
- "...to %qs in %qE (saved at %@)",
- dst_name,
- get_setjmp_caller (),
- &m_original_setjmp_event_id);
- }
- else
- {
- if (get_longjmp_caller () == get_setjmp_caller ())
- /* Special-case: purely intraprocedural rewind. */
- return make_label_text (can_colorize,
- "...to %qs",
- dst_name,
- get_setjmp_caller ());
- else
- return make_label_text (can_colorize,
- "...to %qs in %qE",
- dst_name,
- get_setjmp_caller ());
- }
-}
-
-/* Implementation of checker_event::prepare_for_emission vfunc for
- rewind_to_setjmp_event.
-
- Attempt to look up the setjmp event ID that recorded the jmp_buf
- for this rewind. */
-
-void
-rewind_to_setjmp_event::prepare_for_emission (checker_path *path,
- pending_diagnostic *pd,
- diagnostic_event_id_t emission_id)
-{
- checker_event::prepare_for_emission (path, pd, emission_id);
- path->get_setjmp_event (m_rewind_info->get_enode_origin (),
- &m_original_setjmp_event_id);
-}
-
-/* class warning_event : public checker_event. */
-
-/* Implementation of diagnostic_event::get_desc vfunc for
- warning_event.
-
- If the pending diagnostic implements describe_final_event, use it,
- generating a precise description e.g.
- "second 'free' here; first 'free' was at (7)"
-
- Otherwise generate a generic description. */
-
-label_text
-warning_event::get_desc (bool can_colorize) const
-{
- if (m_pending_diagnostic)
- {
- tree var = fixup_tree_for_diagnostic (m_var);
- label_text ev_desc
- = m_pending_diagnostic->describe_final_event
- (evdesc::final_event (can_colorize, var, m_state));
- if (ev_desc.get ())
- {
- if (m_sm && flag_analyzer_verbose_state_changes)
- {
- if (var)
- return make_label_text (can_colorize,
- "%s (%qE is in state %qs)",
- ev_desc.get (),
- var, m_state->get_name ());
- else
- return make_label_text (can_colorize,
- "%s (in global state %qs)",
- ev_desc.get (),
- m_state->get_name ());
- }
- else
- return ev_desc;
- }
- }
-
- if (m_sm)
- {
- if (m_var)
- return make_label_text (can_colorize,
- "here (%qE is in state %qs)",
- m_var, m_state->get_name ());
- else
- return make_label_text (can_colorize,
- "here (in global state %qs)",
- m_state->get_name ());
- }
- else
- return label_text::borrow ("here");
-}
-
-/* Implementation of diagnostic_event::get_meaning vfunc for
- warning_event. */
-
-diagnostic_event::meaning
-warning_event::get_meaning () const
-{
- return meaning (VERB_danger, NOUN_unknown);
-}
-
/* Print a single-line representation of this path to PP. */
void
@@ -1226,6 +102,21 @@ checker_path::maybe_log (logger *logger, const char *desc) const
}
}
+void
+checker_path::add_event (std::unique_ptr<checker_event> event)
+{
+ if (m_logger)
+ {
+ m_logger->start_log_line ();
+ m_logger->log_partial ("added event[%i]: %s ",
+ m_events.length (),
+ event_kind_to_string (event.get ()->m_kind));
+ event.get ()->dump (m_logger->get_printer ());
+ m_logger->end_log_line ();
+ }
+ m_events.safe_push (event.release ());
+}
+
/* Print a multiline form of this path to STDERR. */
DEBUG_FUNCTION void
@@ -1250,10 +141,10 @@ checker_path::debug () const
If DEBUG is true, also create an RCE_DEBUG event. */
void
-checker_path::add_region_creation_events (const region *reg,
+checker_path::add_region_creation_events (pending_diagnostic *pd,
+ const region *reg,
const region_model *model,
- location_t loc,
- tree fndecl, int depth,
+ const event_loc_info &loc_info,
bool debug)
{
tree capacity = NULL_TREE;
@@ -1261,38 +152,18 @@ checker_path::add_region_creation_events (const region *reg,
if (const svalue *capacity_sval = model->get_capacity (reg))
capacity = model->get_representative_tree (capacity_sval);
- add_event (new region_creation_event (reg, capacity, RCE_MEM_SPACE,
- loc, fndecl, depth));
-
- if (capacity)
- add_event (new region_creation_event (reg, capacity, RCE_CAPACITY,
- loc, fndecl, depth));
+ pd->add_region_creation_events (reg, capacity, loc_info, *this);
if (debug)
- add_event (new region_creation_event (reg, capacity, RCE_DEBUG,
- loc, fndecl, depth));
-}
-
-/* Add a warning_event to the end of this path. */
-
-void
-checker_path::add_final_event (const state_machine *sm,
- const exploded_node *enode, const gimple *stmt,
- tree var, state_machine::state_t state)
-{
- checker_event *end_of_path
- = new warning_event (get_stmt_location (stmt, enode->get_function ()),
- enode->get_function ()->decl,
- enode->get_stack_depth (),
- sm, var, state);
- add_event (end_of_path);
+ add_event (make_unique<region_creation_event_debug> (reg, capacity,
+ loc_info));
}
void
checker_path::fixup_locations (pending_diagnostic *pd)
{
for (checker_event *e : m_events)
- e->set_location (pd->fixup_location (e->get_location ()));
+ e->set_location (pd->fixup_location (e->get_location (), false));
}
/* Return true if there is a (start_cfg_edge_event, end_cfg_edge_event) pair
@@ -1397,8 +268,10 @@ checker_path::inject_any_inlined_call_events (logger *logger)
!iter.done_p (); iter.next ())
{
logger->start_log_line ();
- logger->log_partial (" %qE (%p), fndecl: %qE, callsite: 0x%x",
- iter.get_block (), iter.get_block (),
+ logger->log_partial (" %qE", iter.get_block ());
+ if (!flag_dump_noaddr)
+ logger->log_partial (" (%p)", iter.get_block ());
+ logger->log_partial (", fndecl: %qE, callsite: 0x%x",
iter.get_fndecl (), iter.get_callsite ());
if (iter.get_callsite ())
dump_location (logger->get_printer (), iter.get_callsite ());
diff --git a/gcc/analyzer/checker-path.h b/gcc/analyzer/checker-path.h
index 5d00934..de1f620 100644
--- a/gcc/analyzer/checker-path.h
+++ b/gcc/analyzer/checker-path.h
@@ -1,4 +1,4 @@
-/* Subclasses of diagnostic_path and diagnostic_event for analyzer diagnostics.
+/* Subclass of diagnostic_path for analyzer diagnostics.
Copyright (C) 2019-2022 Free Software Foundation, Inc.
Contributed by David Malcolm <dmalcolm@redhat.com>.
@@ -21,593 +21,16 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_ANALYZER_CHECKER_PATH_H
#define GCC_ANALYZER_CHECKER_PATH_H
-#include "tree-logical-location.h"
+#include "analyzer/checker-event.h"
namespace ana {
-/* An enum for discriminating between the concrete subclasses of
- checker_event. */
-
-enum event_kind
-{
- EK_DEBUG,
- EK_CUSTOM,
- EK_STMT,
- EK_REGION_CREATION,
- EK_FUNCTION_ENTRY,
- EK_STATE_CHANGE,
- EK_START_CFG_EDGE,
- EK_END_CFG_EDGE,
- EK_CALL_EDGE,
- EK_RETURN_EDGE,
- EK_START_CONSOLIDATED_CFG_EDGES,
- EK_END_CONSOLIDATED_CFG_EDGES,
- EK_INLINED_CALL,
- EK_SETJMP,
- EK_REWIND_FROM_LONGJMP,
- EK_REWIND_TO_SETJMP,
- EK_WARNING
-};
-
-extern const char *event_kind_to_string (enum event_kind ek);
-
-/* Event subclasses.
-
- The class hierarchy looks like this (using indentation to show
- inheritance, and with event_kinds shown for the concrete subclasses):
-
- diagnostic_event
- checker_event
- debug_event (EK_DEBUG)
- custom_event (EK_CUSTOM)
- precanned_custom_event
- statement_event (EK_STMT)
- region_creation_event (EK_REGION_CREATION)
- function_entry_event (EK_FUNCTION_ENTRY)
- state_change_event (EK_STATE_CHANGE)
- superedge_event
- cfg_edge_event
- start_cfg_edge_event (EK_START_CFG_EDGE)
- end_cfg_edge_event (EK_END_CFG_EDGE)
- call_event (EK_CALL_EDGE)
- return_edge (EK_RETURN_EDGE)
- start_consolidated_cfg_edges_event (EK_START_CONSOLIDATED_CFG_EDGES)
- end_consolidated_cfg_edges_event (EK_END_CONSOLIDATED_CFG_EDGES)
- inlined_call_event (EK_INLINED_CALL)
- setjmp_event (EK_SETJMP)
- rewind_event
- rewind_from_longjmp_event (EK_REWIND_FROM_LONGJMP)
- rewind_to_setjmp_event (EK_REWIND_TO_SETJMP)
- warning_event (EK_WARNING). */
-
-/* Abstract subclass of diagnostic_event; the base class for use in
- checker_path (the analyzer's diagnostic_path subclass). */
-
-class checker_event : public diagnostic_event
-{
-public:
- /* Implementation of diagnostic_event. */
-
- location_t get_location () const final override { return m_loc; }
- tree get_fndecl () const final override { return m_effective_fndecl; }
- int get_stack_depth () const final override { return m_effective_depth; }
- const logical_location *get_logical_location () const final override
- {
- if (m_effective_fndecl)
- return &m_logical_loc;
- else
- return NULL;
- }
- meaning get_meaning () const override;
-
- /* Additional functionality. */
-
- int get_original_stack_depth () const { return m_original_depth; }
-
- virtual void prepare_for_emission (checker_path *,
- pending_diagnostic *pd,
- diagnostic_event_id_t emission_id);
- virtual bool is_call_p () const { return false; }
- virtual bool is_function_entry_p () const { return false; }
- virtual bool is_return_p () const { return false; }
-
- /* For use with %@. */
- const diagnostic_event_id_t *get_id_ptr () const
- {
- return &m_emission_id;
- }
-
- void dump (pretty_printer *pp) const;
-
- void set_location (location_t loc) { m_loc = loc; }
-
-protected:
- checker_event (enum event_kind kind,
- location_t loc, tree fndecl, int depth);
-
- public:
- const enum event_kind m_kind;
- protected:
- location_t m_loc;
- tree m_original_fndecl;
- tree m_effective_fndecl;
- int m_original_depth;
- int m_effective_depth;
- pending_diagnostic *m_pending_diagnostic;
- diagnostic_event_id_t m_emission_id; // only set once all pruning has occurred
- tree_logical_location m_logical_loc;
-};
-
-/* A concrete event subclass for a purely textual event, for use in
- debugging path creation and filtering. */
-
-class debug_event : public checker_event
-{
-public:
- debug_event (location_t loc, tree fndecl, int depth,
- const char *desc)
- : checker_event (EK_DEBUG, loc, fndecl, depth),
- m_desc (xstrdup (desc))
- {
- }
- ~debug_event ()
- {
- free (m_desc);
- }
-
- label_text get_desc (bool) const final override;
-
-private:
- char *m_desc;
-};
-
-/* An abstract event subclass for custom events. These are not filtered,
- as they are likely to be pertinent to the diagnostic. */
-
-class custom_event : public checker_event
-{
-protected:
- custom_event (location_t loc, tree fndecl, int depth)
- : checker_event (EK_CUSTOM, loc, fndecl, depth)
- {
- }
-};
-
-/* A concrete custom_event subclass with a precanned message. */
-
-class precanned_custom_event : public custom_event
-{
-public:
- precanned_custom_event (location_t loc, tree fndecl, int depth,
- const char *desc)
- : custom_event (loc, fndecl, depth),
- m_desc (xstrdup (desc))
- {
- }
- ~precanned_custom_event ()
- {
- free (m_desc);
- }
-
- label_text get_desc (bool) const final override;
-
-private:
- char *m_desc;
-};
-
-/* A concrete event subclass describing the execution of a gimple statement,
- for use at high verbosity levels when debugging paths. */
-
-class statement_event : public checker_event
-{
-public:
- statement_event (const gimple *stmt, tree fndecl, int depth,
- const program_state &dst_state);
-
- label_text get_desc (bool) const final override;
-
- const gimple * const m_stmt;
- const program_state m_dst_state;
-};
-
-/* There are too many combinations to express region creation in one message,
- so we emit multiple region_creation_event instances when each pertinent
- region is created.
-
- This enum distinguishes between the different messages. */
-
-enum rce_kind
-{
- /* Generate a message based on the memory space of the region
- e.g. "region created on stack here". */
- RCE_MEM_SPACE,
-
- /* Generate a message based on the capacity of the region
- e.g. "capacity: 100 bytes". */
- RCE_CAPACITY,
-
- /* Generate a debug message. */
- RCE_DEBUG
-};
-
-/* A concrete event subclass describing the creation of a region that
- is significant for a diagnostic. */
-
-class region_creation_event : public checker_event
-{
-public:
- region_creation_event (const region *reg,
- tree capacity,
- enum rce_kind kind,
- location_t loc, tree fndecl, int depth);
-
- label_text get_desc (bool can_colorize) const final override;
-
-private:
- const region *m_reg;
- tree m_capacity;
- enum rce_kind m_rce_kind;
-};
-
-/* An event subclass describing the entry to a function. */
-
-class function_entry_event : public checker_event
-{
-public:
- function_entry_event (location_t loc, tree fndecl, int depth)
- : checker_event (EK_FUNCTION_ENTRY, loc, fndecl, depth)
- {
- }
-
- label_text get_desc (bool can_colorize) const final override;
- meaning get_meaning () const override;
-
- bool is_function_entry_p () const final override { return true; }
-};
-
-/* Subclass of checker_event describing a state change. */
-
-class state_change_event : public checker_event
-{
-public:
- state_change_event (const supernode *node, const gimple *stmt,
- int stack_depth,
- const state_machine &sm,
- const svalue *sval,
- state_machine::state_t from,
- state_machine::state_t to,
- const svalue *origin,
- const program_state &dst_state);
-
- label_text get_desc (bool can_colorize) const final override;
- meaning get_meaning () const override;
-
- function *get_dest_function () const
- {
- return m_dst_state.get_current_function ();
- }
-
- const supernode *m_node;
- const gimple *m_stmt;
- const state_machine &m_sm;
- const svalue *m_sval;
- state_machine::state_t m_from;
- state_machine::state_t m_to;
- const svalue *m_origin;
- program_state m_dst_state;
-};
-
-/* Subclass of checker_event; parent class for subclasses that relate to
- a superedge. */
-
-class superedge_event : public checker_event
-{
-public:
- /* Mark this edge event as being either an interprocedural call or
- return in which VAR is in STATE, and that this is critical to the
- diagnostic (so that get_desc can attempt to get a better description
- from any pending_diagnostic). */
- void record_critical_state (tree var, state_machine::state_t state)
- {
- m_var = var;
- m_critical_state = state;
- }
-
- const callgraph_superedge& get_callgraph_superedge () const;
-
- bool should_filter_p (int verbosity) const;
-
- protected:
- superedge_event (enum event_kind kind, const exploded_edge &eedge,
- location_t loc, tree fndecl, int depth);
-
- public:
- const exploded_edge &m_eedge;
- const superedge *m_sedge;
- tree m_var;
- state_machine::state_t m_critical_state;
-};
-
-/* An abstract event subclass for when a CFG edge is followed; it has two
- subclasses, representing the start of the edge and the end of the
- edge, which come in pairs. */
-
-class cfg_edge_event : public superedge_event
-{
-public:
- meaning get_meaning () const override;
-
- const cfg_superedge& get_cfg_superedge () const;
-
- protected:
- cfg_edge_event (enum event_kind kind, const exploded_edge &eedge,
- location_t loc, tree fndecl, int depth);
-};
-
-/* A concrete event subclass for the start of a CFG edge
- e.g. "following 'false' branch...'. */
-
-class start_cfg_edge_event : public cfg_edge_event
-{
-public:
- start_cfg_edge_event (const exploded_edge &eedge,
- location_t loc, tree fndecl, int depth)
- : cfg_edge_event (EK_START_CFG_EDGE, eedge, loc, fndecl, depth)
- {
- }
-
- label_text get_desc (bool can_colorize) const final override;
-
- private:
- label_text maybe_describe_condition (bool can_colorize) const;
-
- static label_text maybe_describe_condition (bool can_colorize,
- tree lhs,
- enum tree_code op,
- tree rhs);
- static bool should_print_expr_p (tree);
-};
-
-/* A concrete event subclass for the end of a CFG edge
- e.g. "...to here'. */
-
-class end_cfg_edge_event : public cfg_edge_event
-{
-public:
- end_cfg_edge_event (const exploded_edge &eedge,
- location_t loc, tree fndecl, int depth)
- : cfg_edge_event (EK_END_CFG_EDGE, eedge, loc, fndecl, depth)
- {
- }
-
- label_text get_desc (bool /*can_colorize*/) const final override
- {
- return label_text::borrow ("...to here");
- }
-};
-
-/* A concrete event subclass for an interprocedural call. */
-
-class call_event : public superedge_event
-{
-public:
- call_event (const exploded_edge &eedge,
- location_t loc, tree fndecl, int depth);
-
- label_text get_desc (bool can_colorize) const override;
- meaning get_meaning () const override;
-
- bool is_call_p () const final override;
-
-protected:
- tree get_caller_fndecl () const;
- tree get_callee_fndecl () const;
-
- const supernode *m_src_snode;
- const supernode *m_dest_snode;
-};
-
-/* A concrete event subclass for an interprocedural return. */
-
-class return_event : public superedge_event
-{
-public:
- return_event (const exploded_edge &eedge,
- location_t loc, tree fndecl, int depth);
-
- label_text get_desc (bool can_colorize) const final override;
- meaning get_meaning () const override;
-
- bool is_return_p () const final override;
-
- const supernode *m_src_snode;
- const supernode *m_dest_snode;
-};
-
-/* A concrete event subclass for the start of a consolidated run of CFG
- edges all either TRUE or FALSE e.g. "following 'false' branch...'. */
-
-class start_consolidated_cfg_edges_event : public checker_event
-{
-public:
- start_consolidated_cfg_edges_event (location_t loc, tree fndecl, int depth,
- bool edge_sense)
- : checker_event (EK_START_CONSOLIDATED_CFG_EDGES, loc, fndecl, depth),
- m_edge_sense (edge_sense)
- {
- }
-
- label_text get_desc (bool can_colorize) const final override;
- meaning get_meaning () const override;
-
- private:
- bool m_edge_sense;
-};
-
-/* A concrete event subclass for the end of a consolidated run of
- CFG edges e.g. "...to here'. */
-
-class end_consolidated_cfg_edges_event : public checker_event
-{
-public:
- end_consolidated_cfg_edges_event (location_t loc, tree fndecl, int depth)
- : checker_event (EK_END_CONSOLIDATED_CFG_EDGES, loc, fndecl, depth)
- {
- }
-
- label_text get_desc (bool /*can_colorize*/) const final override
- {
- return label_text::borrow ("...to here");
- }
-};
-
-/* A concrete event subclass for describing an inlined call event
- e.g. "inlined call to 'callee' from 'caller'". */
-
-class inlined_call_event : public checker_event
-{
-public:
- inlined_call_event (location_t loc,
- tree apparent_callee_fndecl,
- tree apparent_caller_fndecl,
- int actual_depth,
- int stack_depth_adjustment)
- : checker_event (EK_INLINED_CALL, loc,
- apparent_caller_fndecl,
- actual_depth + stack_depth_adjustment),
- m_apparent_callee_fndecl (apparent_callee_fndecl),
- m_apparent_caller_fndecl (apparent_caller_fndecl)
- {
- gcc_assert (LOCATION_BLOCK (loc) == NULL);
- }
-
- label_text get_desc (bool /*can_colorize*/) const final override;
- meaning get_meaning () const override;
-
-private:
- tree m_apparent_callee_fndecl;
- tree m_apparent_caller_fndecl;
-};
-
-/* A concrete event subclass for a setjmp or sigsetjmp call. */
-
-class setjmp_event : public checker_event
-{
-public:
- setjmp_event (location_t loc, const exploded_node *enode,
- tree fndecl, int depth, const gcall *setjmp_call)
- : checker_event (EK_SETJMP, loc, fndecl, depth),
- m_enode (enode), m_setjmp_call (setjmp_call)
- {
- }
-
- label_text get_desc (bool can_colorize) const final override;
-
- void prepare_for_emission (checker_path *path,
- pending_diagnostic *pd,
- diagnostic_event_id_t emission_id) final override;
-
-private:
- const exploded_node *m_enode;
- const gcall *m_setjmp_call;
-};
-
-/* An abstract event subclass for rewinding from a longjmp to a setjmp
- (or siglongjmp to sigsetjmp).
-
- Base class for two from/to subclasses, showing the two halves of the
- rewind. */
-
-class rewind_event : public checker_event
-{
-public:
- tree get_longjmp_caller () const;
- tree get_setjmp_caller () const;
- const exploded_edge *get_eedge () const { return m_eedge; }
-
- protected:
- rewind_event (const exploded_edge *eedge,
- enum event_kind kind,
- location_t loc, tree fndecl, int depth,
- const rewind_info_t *rewind_info);
- const rewind_info_t *m_rewind_info;
-
- private:
- const exploded_edge *m_eedge;
-};
-
-/* A concrete event subclass for rewinding from a longjmp to a setjmp,
- showing the longjmp (or siglongjmp). */
-
-class rewind_from_longjmp_event : public rewind_event
-{
-public:
- rewind_from_longjmp_event (const exploded_edge *eedge,
- location_t loc, tree fndecl, int depth,
- const rewind_info_t *rewind_info)
- : rewind_event (eedge, EK_REWIND_FROM_LONGJMP, loc, fndecl, depth,
- rewind_info)
- {
- }
-
- label_text get_desc (bool can_colorize) const final override;
-};
-
-/* A concrete event subclass for rewinding from a longjmp to a setjmp,
- showing the setjmp (or sigsetjmp). */
-
-class rewind_to_setjmp_event : public rewind_event
-{
-public:
- rewind_to_setjmp_event (const exploded_edge *eedge,
- location_t loc, tree fndecl, int depth,
- const rewind_info_t *rewind_info)
- : rewind_event (eedge, EK_REWIND_TO_SETJMP, loc, fndecl, depth,
- rewind_info)
- {
- }
-
- label_text get_desc (bool can_colorize) const final override;
-
- void prepare_for_emission (checker_path *path,
- pending_diagnostic *pd,
- diagnostic_event_id_t emission_id) final override;
-
-private:
- diagnostic_event_id_t m_original_setjmp_event_id;
-};
-
-/* Concrete subclass of checker_event for use at the end of a path:
- a repeat of the warning message at the end of the path (perhaps with
- references to pertinent events that occurred on the way), at the point
- where the problem occurs. */
-
-class warning_event : public checker_event
-{
-public:
- warning_event (location_t loc, tree fndecl, int depth,
- const state_machine *sm,
- tree var, state_machine::state_t state)
- : checker_event (EK_WARNING, loc, fndecl, depth),
- m_sm (sm), m_var (var), m_state (state)
- {
- }
-
- label_text get_desc (bool can_colorize) const final override;
- meaning get_meaning () const override;
-
-private:
- const state_machine *m_sm;
- tree m_var;
- state_machine::state_t m_state;
-};
-
/* Subclass of diagnostic_path for analyzer diagnostics. */
class checker_path : public diagnostic_path
{
public:
- checker_path () : diagnostic_path () {}
+ checker_path (logger *logger) : diagnostic_path (), m_logger (logger) {}
/* Implementation of diagnostic_path vfuncs. */
@@ -631,10 +54,7 @@ public:
void maybe_log (logger *logger, const char *desc) const;
- void add_event (checker_event *event)
- {
- m_events.safe_push (event);
- }
+ void add_event (std::unique_ptr<checker_event> event);
void delete_event (int idx)
{
@@ -656,16 +76,12 @@ public:
m_events[idx] = new_event;
}
- void add_region_creation_events (const region *reg,
+ void add_region_creation_events (pending_diagnostic *pd,
+ const region *reg,
const region_model *model,
- location_t loc,
- tree fndecl, int depth,
+ const event_loc_info &loc_info,
bool debug);
- void add_final_event (const state_machine *sm,
- const exploded_node *enode, const gimple *stmt,
- tree var, state_machine::state_t state);
-
/* After all event-pruning, a hook for notifying each event what
its ID will be. The events are notified in order, allowing
for later events to refer to the IDs of earlier events in
@@ -711,6 +127,8 @@ private:
exploded_node *, so that rewind events can refer to them in their
descriptions. */
hash_map <const exploded_node *, diagnostic_event_id_t> m_setjmp_event_ids;
+
+ logger *m_logger;
};
} // namespace ana
diff --git a/gcc/analyzer/complexity.cc b/gcc/analyzer/complexity.cc
index 39fbbc1..2756f96 100644
--- a/gcc/analyzer/complexity.cc
+++ b/gcc/analyzer/complexity.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc
index 96ae073..b4e51b0 100644
--- a/gcc/analyzer/constraint-manager.cc
+++ b/gcc/analyzer/constraint-manager.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index 695bde5..9cc02da 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
@@ -55,6 +56,7 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/feasible-graph.h"
#include "analyzer/checker-path.h"
#include "analyzer/reachability.h"
+#include "make-unique.h"
#if ENABLE_ANALYZER
@@ -84,21 +86,24 @@ public:
logger *get_logger () const { return m_eg.get_logger (); }
- exploded_path *get_best_epath (const exploded_node *target_enode,
- const char *desc, unsigned diag_idx,
- feasibility_problem **out_problem);
+ std::unique_ptr<exploded_path>
+ get_best_epath (const exploded_node *target_enode,
+ const char *desc, unsigned diag_idx,
+ std::unique_ptr<feasibility_problem> *out_problem);
private:
DISABLE_COPY_AND_ASSIGN(epath_finder);
- exploded_path *explore_feasible_paths (const exploded_node *target_enode,
- const char *desc, unsigned diag_idx);
- bool process_worklist_item (feasible_worklist *worklist,
- const trimmed_graph &tg,
- feasible_graph *fg,
- const exploded_node *target_enode,
- unsigned diag_idx,
- exploded_path **out_best_path) const;
+ std::unique_ptr<exploded_path>
+ explore_feasible_paths (const exploded_node *target_enode,
+ const char *desc, unsigned diag_idx);
+ bool
+ process_worklist_item (feasible_worklist *worklist,
+ const trimmed_graph &tg,
+ feasible_graph *fg,
+ const exploded_node *target_enode,
+ unsigned diag_idx,
+ std::unique_ptr<exploded_path> *out_best_path) const;
void dump_trimmed_graph (const exploded_node *target_enode,
const char *desc, unsigned diag_idx,
const trimmed_graph &tg,
@@ -131,10 +136,10 @@ private:
Write any feasibility_problem to *OUT_PROBLEM. */
-exploded_path *
+std::unique_ptr<exploded_path>
epath_finder::get_best_epath (const exploded_node *enode,
const char *desc, unsigned diag_idx,
- feasibility_problem **out_problem)
+ std::unique_ptr<feasibility_problem> *out_problem)
{
logger *logger = get_logger ();
LOG_SCOPE (logger);
@@ -155,7 +160,8 @@ epath_finder::get_best_epath (const exploded_node *enode,
/* Attempt to find the shortest feasible path using feasible_graph. */
if (logger)
logger->log ("trying to find shortest feasible path");
- if (exploded_path *epath = explore_feasible_paths (enode, desc, diag_idx))
+ if (std::unique_ptr<exploded_path> epath
+ = explore_feasible_paths (enode, desc, diag_idx))
{
if (logger)
logger->log ("accepting %qs at EN: %i, SN: %i (sd: %i)"
@@ -183,8 +189,8 @@ epath_finder::get_best_epath (const exploded_node *enode,
if (logger)
logger->log ("trying to find shortest path ignoring feasibility");
gcc_assert (m_sep);
- exploded_path *epath
- = new exploded_path (m_sep->get_shortest_path (enode));
+ std::unique_ptr<exploded_path> epath
+ = make_unique<exploded_path> (m_sep->get_shortest_path (enode));
if (epath->feasible_p (logger, out_problem, m_eg.get_engine (), &m_eg))
{
if (logger)
@@ -366,7 +372,7 @@ private:
continue forever without reaching the target), or
- getting monotonically closer to the termination threshold. */
-exploded_path *
+std::unique_ptr<exploded_path>
epath_finder::explore_feasible_paths (const exploded_node *target_enode,
const char *desc, unsigned diag_idx)
{
@@ -404,7 +410,7 @@ epath_finder::explore_feasible_paths (const exploded_node *target_enode,
a limit. */
/* Set this if we find a feasible path to TARGET_ENODE. */
- exploded_path *best_path = NULL;
+ std::unique_ptr<exploded_path> best_path = NULL;
{
auto_checking_feasibility sentinel (mgr);
@@ -446,12 +452,13 @@ epath_finder::explore_feasible_paths (const exploded_node *target_enode,
to TARGET_ENODE. */
bool
-epath_finder::process_worklist_item (feasible_worklist *worklist,
- const trimmed_graph &tg,
- feasible_graph *fg,
- const exploded_node *target_enode,
- unsigned diag_idx,
- exploded_path **out_best_path) const
+epath_finder::
+process_worklist_item (feasible_worklist *worklist,
+ const trimmed_graph &tg,
+ feasible_graph *fg,
+ const exploded_node *target_enode,
+ unsigned diag_idx,
+ std::unique_ptr<exploded_path> *out_best_path) const
{
logger *logger = get_logger ();
@@ -634,18 +641,18 @@ epath_finder::dump_feasible_path (const exploded_node *target_enode,
saved_diagnostic::saved_diagnostic (const state_machine *sm,
const exploded_node *enode,
const supernode *snode, const gimple *stmt,
- stmt_finder *stmt_finder,
+ const stmt_finder *stmt_finder,
tree var,
const svalue *sval,
state_machine::state_t state,
- pending_diagnostic *d,
+ std::unique_ptr<pending_diagnostic> d,
unsigned idx)
: m_sm (sm), m_enode (enode), m_snode (snode), m_stmt (stmt),
/* stmt_finder could be on-stack; we want our own copy that can
outlive that. */
m_stmt_finder (stmt_finder ? stmt_finder->clone () : NULL),
m_var (var), m_sval (sval), m_state (state),
- m_d (d), m_trailing_eedge (NULL),
+ m_d (std::move (d)), m_trailing_eedge (NULL),
m_idx (idx),
m_best_epath (NULL), m_problem (NULL),
m_notes ()
@@ -657,16 +664,6 @@ saved_diagnostic::saved_diagnostic (const state_machine *sm,
gcc_assert (m_enode);
}
-/* saved_diagnostic's dtor. */
-
-saved_diagnostic::~saved_diagnostic ()
-{
- delete m_stmt_finder;
- delete m_d;
- delete m_best_epath;
- delete m_problem;
-}
-
bool
saved_diagnostic::operator== (const saved_diagnostic &other) const
{
@@ -689,10 +686,10 @@ saved_diagnostic::operator== (const saved_diagnostic &other) const
/* Add PN to this diagnostic, taking ownership of it. */
void
-saved_diagnostic::add_note (pending_note *pn)
+saved_diagnostic::add_note (std::unique_ptr<pending_note> pn)
{
gcc_assert (pn);
- m_notes.safe_push (pn);
+ m_notes.safe_push (pn.release ());
}
/* Return a new json::object of the form
@@ -809,8 +806,6 @@ saved_diagnostic::calc_best_epath (epath_finder *pf)
{
logger *logger = pf->get_logger ();
LOG_SCOPE (logger);
- delete m_best_epath;
- delete m_problem;
m_problem = NULL;
m_best_epath = pf->get_best_epath (m_enode, m_d->get_kind (), m_idx,
@@ -896,7 +891,7 @@ public:
pending_diagnostic *get_pending_diagnostic () const
{
- return m_sd.m_d;
+ return m_sd.m_d.get ();
}
bool reachable_from_p (const exploded_node *src_enode) const
@@ -938,7 +933,7 @@ get_emission_location (const gimple *stmt, function *fun,
location_t loc = get_stmt_location (stmt, fun);
/* Allow the pending_diagnostic to fix up the location. */
- loc = pd.fixup_location (loc);
+ loc = pd.fixup_location (loc, true);
return loc;
}
@@ -955,18 +950,17 @@ diagnostic_manager::diagnostic_manager (logger *logger, engine *eng,
}
/* Queue pending_diagnostic D at ENODE for later emission.
- Return true/false signifying if the diagnostic was actually added.
- Take ownership of D (or delete it). */
+ Return true/false signifying if the diagnostic was actually added. */
bool
diagnostic_manager::add_diagnostic (const state_machine *sm,
exploded_node *enode,
const supernode *snode, const gimple *stmt,
- stmt_finder *finder,
+ const stmt_finder *finder,
tree var,
const svalue *sval,
state_machine::state_t state,
- pending_diagnostic *d)
+ std::unique_ptr<pending_diagnostic> d)
{
LOG_FUNC (get_logger ());
@@ -987,7 +981,6 @@ diagnostic_manager::add_diagnostic (const state_machine *sm,
if (get_logger ())
get_logger ()->log ("rejecting disabled warning %qs",
d->get_kind ());
- delete d;
m_num_disabled_diagnostics++;
return false;
}
@@ -995,13 +988,13 @@ diagnostic_manager::add_diagnostic (const state_machine *sm,
saved_diagnostic *sd
= new saved_diagnostic (sm, enode, snode, stmt, finder, var, sval,
- state, d, m_saved_diagnostics.length ());
+ state, std::move (d), m_saved_diagnostics.length ());
m_saved_diagnostics.safe_push (sd);
enode->add_diagnostic (sd);
if (get_logger ())
log ("adding saved diagnostic %i at SN %i to EN %i: %qs",
sd->get_index (),
- snode->m_index, enode->m_index, d->get_kind ());
+ snode->m_index, enode->m_index, sd->m_d->get_kind ());
return true;
}
@@ -1012,18 +1005,18 @@ diagnostic_manager::add_diagnostic (const state_machine *sm,
bool
diagnostic_manager::add_diagnostic (exploded_node *enode,
const supernode *snode, const gimple *stmt,
- stmt_finder *finder,
- pending_diagnostic *d)
+ const stmt_finder *finder,
+ std::unique_ptr<pending_diagnostic> d)
{
gcc_assert (enode);
return add_diagnostic (NULL, enode, snode, stmt, finder, NULL_TREE,
- NULL, 0, d);
+ NULL, 0, std::move (d));
}
/* Add PN to the most recent saved_diagnostic. */
void
-diagnostic_manager::add_note (pending_note *pn)
+diagnostic_manager::add_note (std::unique_ptr<pending_note> pn)
{
LOG_FUNC (get_logger ());
gcc_assert (pn);
@@ -1031,7 +1024,7 @@ diagnostic_manager::add_note (pending_note *pn)
/* Get most recent saved_diagnostic. */
gcc_assert (m_saved_diagnostics.length () > 0);
saved_diagnostic *sd = m_saved_diagnostics[m_saved_diagnostics.length () - 1];
- sd->add_note (pn);
+ sd->add_note (std::move (pn));
}
/* Return a new json::object of the form
@@ -1363,7 +1356,7 @@ diagnostic_manager::emit_saved_diagnostic (const exploded_graph &eg,
/* This is the diagnostic_path subclass that will be built for
the diagnostic. */
- checker_path emission_path;
+ checker_path emission_path (get_logger ());
/* Populate emission_path with a full description of EPATH. */
build_emission_path (pb, *epath, &emission_path);
@@ -1375,8 +1368,8 @@ diagnostic_manager::emit_saved_diagnostic (const exploded_graph &eg,
We use the final enode from the epath, which might be different from
the sd.m_enode, as the dedupe code doesn't care about enodes, just
snodes. */
- emission_path.add_final_event (sd.m_sm, epath->get_final_enode (), sd.m_stmt,
- sd.m_var, sd.m_state);
+ sd.m_d->add_final_event (sd.m_sm, epath->get_final_enode (), sd.m_stmt,
+ sd.m_var, sd.m_state, &emission_path);
/* The "final" event might not be final; if the saved_diagnostic has a
trailing eedge stashed, add any events for it. This is for use
@@ -1386,13 +1379,13 @@ diagnostic_manager::emit_saved_diagnostic (const exploded_graph &eg,
emission_path.inject_any_inlined_call_events (get_logger ());
- emission_path.prepare_for_emission (sd.m_d);
+ emission_path.prepare_for_emission (sd.m_d.get ());
location_t loc
= get_emission_location (sd.m_stmt, sd.m_snode->m_fun, *sd.m_d);
/* Allow the pending_diagnostic to fix up the locations of events. */
- emission_path.fixup_locations (sd.m_d);
+ emission_path.fixup_locations (sd.m_d.get ());
gcc_rich_location rich_loc (loc);
rich_loc.set_path (&emission_path);
@@ -1454,10 +1447,11 @@ diagnostic_manager::build_emission_path (const path_builder &pb,
&& DECL_SOURCE_LOCATION (decl) != UNKNOWN_LOCATION)
{
emission_path->add_region_creation_events
- (reg, NULL,
- DECL_SOURCE_LOCATION (decl),
- NULL_TREE,
- 0,
+ (pb.get_pending_diagnostic (),
+ reg, NULL,
+ event_loc_info (DECL_SOURCE_LOCATION (decl),
+ NULL_TREE,
+ 0),
m_verbosity > 3);
}
}
@@ -1470,7 +1464,8 @@ diagnostic_manager::build_emission_path (const path_builder &pb,
const exploded_edge *eedge = epath.m_edges[i];
add_events_for_eedge (pb, *eedge, emission_path, &interest);
}
- add_event_on_final_node (epath.get_final_enode (), emission_path, &interest);
+ add_event_on_final_node (pb, epath.get_final_enode (),
+ emission_path, &interest);
}
/* Emit a region_creation_event when requested on the last statement in
@@ -1482,7 +1477,8 @@ diagnostic_manager::build_emission_path (const path_builder &pb,
*/
void
-diagnostic_manager::add_event_on_final_node (const exploded_node *final_enode,
+diagnostic_manager::add_event_on_final_node (const path_builder &pb,
+ const exploded_node *final_enode,
checker_path *emission_path,
interesting_t *interest) const
{
@@ -1519,11 +1515,12 @@ diagnostic_manager::add_event_on_final_node (const exploded_node *final_enode,
case RK_HEAP_ALLOCATED:
case RK_ALLOCA:
emission_path->add_region_creation_events
- (reg,
+ (pb.get_pending_diagnostic (),
+ reg,
dst_model,
- src_point.get_location (),
- src_point.get_fndecl (),
- src_stack_depth,
+ event_loc_info (src_point.get_location (),
+ src_point.get_fndecl (),
+ src_stack_depth),
false);
emitted = true;
break;
@@ -1566,15 +1563,16 @@ public:
int stack_depth = src_stack_depth;
- m_emission_path->add_event (new state_change_event (supernode,
- stmt,
- stack_depth,
- sm,
- NULL,
- src_sm_val,
- dst_sm_val,
- NULL,
- dst_state));
+ m_emission_path->add_event
+ (make_unique<state_change_event> (supernode,
+ stmt,
+ stack_depth,
+ sm,
+ NULL,
+ src_sm_val,
+ dst_sm_val,
+ NULL,
+ dst_state));
return false;
}
@@ -1609,15 +1607,16 @@ public:
if (!stmt)
return false;
- m_emission_path->add_event (new state_change_event (supernode,
- stmt,
- stack_depth,
- sm,
- sval,
- src_sm_val,
- dst_sm_val,
- dst_origin_sval,
- dst_state));
+ m_emission_path->add_event
+ (make_unique<state_change_event> (supernode,
+ stmt,
+ stack_depth,
+ sm,
+ sval,
+ src_sm_val,
+ dst_sm_val,
+ dst_origin_sval,
+ dst_state));
return false;
}
@@ -1744,20 +1743,24 @@ struct null_assignment_sm_context : public sm_context
state_machine::state_t from = get_state (stmt, var);
if (from != m_sm.get_start_state ())
return;
+ if (!is_transition_to_null (to))
+ return;
const svalue *var_new_sval
= m_new_state->m_region_model->get_rvalue (var, NULL);
+
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,
- var_new_sval,
- from, to,
- NULL,
- *m_new_state));
+ m_emission_path->add_event
+ (make_unique<state_change_event> (supernode,
+ m_stmt,
+ stack_depth,
+ m_sm,
+ var_new_sval,
+ from, to,
+ NULL,
+ *m_new_state));
}
void set_next_state (const gimple *stmt,
@@ -1768,29 +1771,30 @@ struct null_assignment_sm_context : public sm_context
state_machine::state_t from = get_state (stmt, sval);
if (from != m_sm.get_start_state ())
return;
+ if (!is_transition_to_null (to))
+ 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));
+ m_emission_path->add_event
+ (make_unique<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
+ tree, std::unique_ptr<pending_diagnostic>) final override
{
- delete d;
}
void warn (const supernode *, const gimple *,
- const svalue *, pending_diagnostic *d) final override
+ const svalue *, std::unique_ptr<pending_diagnostic>) final override
{
- delete d;
}
tree get_diagnostic_tree (tree expr) final override
@@ -1839,6 +1843,13 @@ struct null_assignment_sm_context : public sm_context
return m_new_state;
}
+ /* We only care about transitions to the "null" state
+ within sm-malloc. Special-case this. */
+ static bool is_transition_to_null (state_machine::state_t s)
+ {
+ return !strcmp (s->get_name (), "null");
+ }
+
const program_state *m_old_state;
const program_state *m_new_state;
const gimple *m_stmt;
@@ -1915,11 +1926,8 @@ diagnostic_manager::add_events_for_eedge (const path_builder &pb,
/* Add function entry events. */
if (dst_point.get_supernode ()->entry_p ())
{
- emission_path->add_event
- (new function_entry_event
- (dst_point.get_supernode ()->get_start_location (),
- dst_point.get_fndecl (),
- dst_stack_depth));
+ pb.get_pending_diagnostic ()->add_function_entry_event
+ (eedge, emission_path);
/* Create region_creation_events for on-stack regions within
this frame. */
if (interest)
@@ -1936,10 +1944,11 @@ diagnostic_manager::add_events_for_eedge (const path_builder &pb,
&& DECL_SOURCE_LOCATION (decl) != UNKNOWN_LOCATION)
{
emission_path->add_region_creation_events
- (reg, dst_state.m_region_model,
- DECL_SOURCE_LOCATION (decl),
- dst_point.get_fndecl (),
- dst_stack_depth,
+ (pb.get_pending_diagnostic (),
+ reg, dst_state.m_region_model,
+ event_loc_info (DECL_SOURCE_LOCATION (decl),
+ dst_point.get_fndecl (),
+ dst_stack_depth),
m_verbosity > 3);
}
}
@@ -1952,22 +1961,23 @@ diagnostic_manager::add_events_for_eedge (const path_builder &pb,
const gcall *call = dyn_cast <const gcall *> (stmt);
if (call && is_setjmp_call_p (call))
emission_path->add_event
- (new setjmp_event (stmt->location,
- dst_node,
- dst_point.get_fndecl (),
- dst_stack_depth,
- call));
+ (make_unique<setjmp_event> (event_loc_info (stmt->location,
+ dst_point.get_fndecl (),
+ dst_stack_depth),
+ dst_node,
+ call));
else
emission_path->add_event
- (new statement_event (stmt,
- dst_point.get_fndecl (),
- dst_stack_depth, dst_state));
+ (make_unique<statement_event> (stmt,
+ dst_point.get_fndecl (),
+ dst_stack_depth, dst_state));
/* Create state change events for assignment to NULL.
Iterate through the stmts in dst_enode, adding state change
events for them. */
if (dst_state.m_region_model)
{
+ log_scope s (get_logger (), "processing run of stmts");
program_state iter_state (dst_state);
program_point iter_point (dst_point);
while (1)
@@ -2031,10 +2041,11 @@ diagnostic_manager::add_events_for_eedge (const path_builder &pb,
case RK_HEAP_ALLOCATED:
case RK_ALLOCA:
emission_path->add_region_creation_events
- (reg, dst_model,
- src_point.get_location (),
- src_point.get_fndecl (),
- src_stack_depth,
+ (pb.get_pending_diagnostic (),
+ reg, dst_model,
+ event_loc_info (src_point.get_location (),
+ src_point.get_fndecl (),
+ src_stack_depth),
m_verbosity > 3);
break;
}
@@ -2051,11 +2062,12 @@ diagnostic_manager::add_events_for_eedge (const path_builder &pb,
"this path would have been rejected as infeasible"
" at this edge: ");
pb.get_feasibility_problem ()->dump_to_pp (&pp);
- emission_path->add_event (new precanned_custom_event
- (dst_point.get_location (),
- dst_point.get_fndecl (),
- dst_stack_depth,
- pp_formatted_text (&pp)));
+ emission_path->add_event
+ (make_unique<precanned_custom_event>
+ (event_loc_info (dst_point.get_location (),
+ dst_point.get_fndecl (),
+ dst_stack_depth),
+ pp_formatted_text (&pp)));
}
}
@@ -2166,17 +2178,17 @@ diagnostic_manager::add_events_for_superedge (const path_builder &pb,
case SUPEREDGE_CFG_EDGE:
{
emission_path->add_event
- (new start_cfg_edge_event (eedge,
- (last_stmt
- ? last_stmt->location
- : UNKNOWN_LOCATION),
- src_point.get_fndecl (),
- src_stack_depth));
+ (make_unique<start_cfg_edge_event>
+ (eedge,
+ event_loc_info (last_stmt ? last_stmt->location : UNKNOWN_LOCATION,
+ src_point.get_fndecl (),
+ src_stack_depth)));
emission_path->add_event
- (new end_cfg_edge_event (eedge,
- dst_point.get_supernode ()->get_start_location (),
- dst_point.get_fndecl (),
- dst_stack_depth));
+ (make_unique<end_cfg_edge_event>
+ (eedge,
+ event_loc_info (dst_point.get_supernode ()->get_start_location (),
+ dst_point.get_fndecl (),
+ dst_stack_depth)));
}
break;
@@ -2189,12 +2201,12 @@ diagnostic_manager::add_events_for_superedge (const path_builder &pb,
/* TODO: add a subclass for this, or generate events for the
summary. */
emission_path->add_event
- (new debug_event ((last_stmt
- ? last_stmt->location
- : UNKNOWN_LOCATION),
- src_point.get_fndecl (),
- src_stack_depth,
- "call summary"));
+ (make_unique<debug_event> (event_loc_info (last_stmt
+ ? last_stmt->location
+ : UNKNOWN_LOCATION,
+ src_point.get_fndecl (),
+ src_stack_depth),
+ "call summary"));
}
break;
@@ -2205,12 +2217,12 @@ diagnostic_manager::add_events_for_superedge (const path_builder &pb,
const gcall *call_stmt = return_edge->get_call_stmt ();
emission_path->add_event
- (new return_event (eedge,
- (call_stmt
- ? call_stmt->location
- : UNKNOWN_LOCATION),
- dst_point.get_fndecl (),
- dst_stack_depth));
+ (make_unique<return_event> (eedge,
+ event_loc_info (call_stmt
+ ? call_stmt->location
+ : UNKNOWN_LOCATION,
+ dst_point.get_fndecl (),
+ dst_stack_depth)));
}
break;
}
@@ -2752,15 +2764,15 @@ diagnostic_manager::consolidate_conditions (checker_path *path) const
start_idx, next_idx - 1, start_idx, start_idx +1);
start_consolidated_cfg_edges_event *new_start_ev
= new start_consolidated_cfg_edges_event
- (old_start_ev->get_location (),
- old_start_ev->get_fndecl (),
- old_start_ev->get_stack_depth (),
+ (event_loc_info (old_start_ev->get_location (),
+ old_start_ev->get_fndecl (),
+ old_start_ev->get_stack_depth ()),
edge_sense);
checker_event *new_end_ev
= new end_consolidated_cfg_edges_event
- (old_end_ev->get_location (),
- old_end_ev->get_fndecl (),
- old_end_ev->get_stack_depth ());
+ (event_loc_info (old_end_ev->get_location (),
+ old_end_ev->get_fndecl (),
+ old_end_ev->get_stack_depth ()));
path->replace_event (start_idx, new_start_ev);
path->replace_event (start_idx + 1, new_end_ev);
path->delete_events (start_idx + 2, next_idx - (start_idx + 2));
diff --git a/gcc/analyzer/diagnostic-manager.h b/gcc/analyzer/diagnostic-manager.h
index 266eed8..56a233b 100644
--- a/gcc/analyzer/diagnostic-manager.h
+++ b/gcc/analyzer/diagnostic-manager.h
@@ -33,16 +33,15 @@ public:
saved_diagnostic (const state_machine *sm,
const exploded_node *enode,
const supernode *snode, const gimple *stmt,
- stmt_finder *stmt_finder,
+ const stmt_finder *stmt_finder,
tree var, const svalue *sval,
state_machine::state_t state,
- pending_diagnostic *d,
+ std::unique_ptr<pending_diagnostic> d,
unsigned idx);
- ~saved_diagnostic ();
bool operator== (const saved_diagnostic &other) const;
- void add_note (pending_note *pn);
+ void add_note (std::unique_ptr<pending_note> pn);
json::object *to_json () const;
@@ -51,11 +50,11 @@ public:
const feasibility_problem *get_feasibility_problem () const
{
- return m_problem;
+ return m_problem.get ();
}
bool calc_best_epath (epath_finder *pf);
- const exploded_path *get_best_epath () const { return m_best_epath; }
+ const exploded_path *get_best_epath () const { return m_best_epath.get (); }
unsigned get_epath_length () const;
void add_duplicate (saved_diagnostic *other);
@@ -72,19 +71,19 @@ public:
const exploded_node *m_enode;
const supernode *m_snode;
const gimple *m_stmt;
- stmt_finder *m_stmt_finder;
+ std::unique_ptr<stmt_finder> m_stmt_finder;
tree m_var;
const svalue *m_sval;
state_machine::state_t m_state;
- pending_diagnostic *m_d; // owned
+ std::unique_ptr<pending_diagnostic> m_d;
const exploded_edge *m_trailing_eedge;
private:
DISABLE_COPY_AND_ASSIGN (saved_diagnostic);
unsigned m_idx;
- exploded_path *m_best_epath; // owned
- feasibility_problem *m_problem; // owned
+ std::unique_ptr<exploded_path> m_best_epath;
+ std::unique_ptr<feasibility_problem> m_problem;
auto_vec<const saved_diagnostic *> m_duplicates;
auto_delete_vec <pending_note> m_notes;
@@ -113,18 +112,18 @@ public:
bool add_diagnostic (const state_machine *sm,
exploded_node *enode,
const supernode *snode, const gimple *stmt,
- stmt_finder *finder,
+ const stmt_finder *finder,
tree var,
const svalue *sval,
state_machine::state_t state,
- pending_diagnostic *d);
+ std::unique_ptr<pending_diagnostic> d);
bool add_diagnostic (exploded_node *enode,
const supernode *snode, const gimple *stmt,
- stmt_finder *finder,
- pending_diagnostic *d);
+ const stmt_finder *finder,
+ std::unique_ptr<pending_diagnostic> d);
- void add_note (pending_note *pn);
+ void add_note (std::unique_ptr<pending_note> pn);
void emit_saved_diagnostics (const exploded_graph &eg);
@@ -149,7 +148,8 @@ private:
const exploded_path &epath,
checker_path *emission_path) const;
- void add_event_on_final_node (const exploded_node *final_enode,
+ void add_event_on_final_node (const path_builder &pb,
+ const exploded_node *final_enode,
checker_path *emission_path,
interesting_t *interest) const;
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 52978dd..b3b81cc 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
+#include "make-unique.h"
#include "tree.h"
#include "fold-const.h"
#include "gcc-rich-location.h"
@@ -114,35 +115,29 @@ impl_region_model_context (program_state *state,
}
bool
-impl_region_model_context::warn (pending_diagnostic *d)
+impl_region_model_context::warn (std::unique_ptr<pending_diagnostic> d)
{
LOG_FUNC (get_logger ());
if (m_stmt == NULL && m_stmt_finder == NULL)
{
if (get_logger ())
get_logger ()->log ("rejecting diagnostic: no stmt");
- delete d;
return false;
}
if (m_eg)
return m_eg->get_diagnostic_manager ().add_diagnostic
(m_enode_for_diag, m_enode_for_diag->get_supernode (),
- m_stmt, m_stmt_finder, d);
+ m_stmt, m_stmt_finder, std::move (d));
else
- {
- delete d;
- return false;
- }
+ return false;
}
void
-impl_region_model_context::add_note (pending_note *pn)
+impl_region_model_context::add_note (std::unique_ptr<pending_note> pn)
{
LOG_FUNC (get_logger ());
if (m_eg)
- m_eg->get_diagnostic_manager ().add_note (pn);
- else
- delete pn;
+ m_eg->get_diagnostic_manager ().add_note (std::move (pn));
}
void
@@ -198,12 +193,10 @@ impl_region_model_context::purge_state_involving (const svalue *sval)
}
void
-impl_region_model_context::bifurcate (custom_edge_info *info)
+impl_region_model_context::bifurcate (std::unique_ptr<custom_edge_info> info)
{
if (m_path_ctxt)
- m_path_ctxt->bifurcate (info);
- else
- delete info;
+ m_path_ctxt->bifurcate (std::move (info));
}
void
@@ -213,25 +206,6 @@ impl_region_model_context::terminate_path ()
return m_path_ctxt->terminate_path ();
}
-bool
-impl_region_model_context::get_state_map_by_name (const char *name,
- sm_state_map **out_smap,
- const state_machine **out_sm,
- unsigned *out_sm_idx)
-{
- if (!m_new_state)
- return false;
-
- unsigned sm_idx;
- if (!m_ext_state.get_sm_idx_by_name (name, &sm_idx))
- return false;
-
- *out_smap = m_new_state->m_checker_states[sm_idx];
- *out_sm = &m_ext_state.get_sm (sm_idx);
- *out_sm_idx = sm_idx;
- return true;
-}
-
/* struct setjmp_record. */
int
@@ -287,7 +261,7 @@ public:
const sm_state_map *old_smap,
sm_state_map *new_smap,
path_context *path_ctxt,
- stmt_finder *stmt_finder = NULL,
+ const stmt_finder *stmt_finder = NULL,
bool unknown_side_effects = false)
: sm_context (sm_idx, sm),
m_logger (eg.get_logger ()),
@@ -336,21 +310,17 @@ public:
}
- void set_next_state (const gimple *stmt,
+ void set_next_state (const gimple *,
tree var,
state_machine::state_t to,
tree origin) final override
{
logger * const logger = get_logger ();
LOG_FUNC (logger);
- impl_region_model_context new_ctxt (m_eg, m_enode_for_diag,
- m_old_state, m_new_state,
- NULL, NULL,
- stmt);
const svalue *var_new_sval
- = m_new_state->m_region_model->get_rvalue (var, &new_ctxt);
+ = m_new_state->m_region_model->get_rvalue (var, NULL);
const svalue *origin_new_sval
- = m_new_state->m_region_model->get_rvalue (origin, &new_ctxt);
+ = m_new_state->m_region_model->get_rvalue (origin, NULL);
/* We use the new sval here to avoid issues with uninitialized values. */
state_machine::state_t current
@@ -376,12 +346,8 @@ public:
(m_eg, m_enode_for_diag, NULL, 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, NULL,
- stmt);
const svalue *origin_new_sval
- = m_new_state->m_region_model->get_rvalue (origin, &new_ctxt);
+ = m_new_state->m_region_model->get_rvalue (origin, NULL);
state_machine::state_t current
= m_old_smap->get_state (sval, m_eg.get_ext_state ());
@@ -401,39 +367,35 @@ public:
}
void warn (const supernode *snode, const gimple *stmt,
- tree var, pending_diagnostic *d) final override
+ tree var,
+ std::unique_ptr<pending_diagnostic> d) final override
{
LOG_FUNC (get_logger ());
- gcc_assert (d); // take ownership
- impl_region_model_context old_ctxt
- (m_eg, m_enode_for_diag, m_old_state, m_new_state, NULL, NULL, NULL);
-
+ gcc_assert (d);
const svalue *var_old_sval
- = m_old_state->m_region_model->get_rvalue (var, &old_ctxt);
+ = m_old_state->m_region_model->get_rvalue (var, NULL);
state_machine::state_t current
= (var
? m_old_smap->get_state (var_old_sval, m_eg.get_ext_state ())
: m_old_smap->get_global_state ());
m_eg.get_diagnostic_manager ().add_diagnostic
(&m_sm, m_enode_for_diag, snode, stmt, m_stmt_finder,
- var, var_old_sval, current, d);
+ var, var_old_sval, current, std::move (d));
}
void warn (const supernode *snode, const gimple *stmt,
- const svalue *sval, pending_diagnostic *d) final override
+ const svalue *sval,
+ std::unique_ptr<pending_diagnostic> d) final override
{
LOG_FUNC (get_logger ());
- gcc_assert (d); // take ownership
- impl_region_model_context old_ctxt
- (m_eg, m_enode_for_diag, m_old_state, m_new_state, NULL, NULL, NULL);
-
+ gcc_assert (d);
state_machine::state_t current
= (sval
? m_old_smap->get_state (sval, m_eg.get_ext_state ())
: m_old_smap->get_global_state ());
m_eg.get_diagnostic_manager ().add_diagnostic
(&m_sm, m_enode_for_diag, snode, stmt, m_stmt_finder,
- NULL_TREE, sval, current, d);
+ NULL_TREE, sval, current, std::move (d));
}
/* Hook for picking more readable trees for SSA names of temporaries,
@@ -526,12 +488,53 @@ public:
const sm_state_map *m_old_smap;
sm_state_map *m_new_smap;
path_context *m_path_ctxt;
- stmt_finder *m_stmt_finder;
+ const stmt_finder *m_stmt_finder;
/* Are we handling an external function with unknown side effects? */
bool m_unknown_side_effects;
};
+bool
+impl_region_model_context::
+get_state_map_by_name (const char *name,
+ sm_state_map **out_smap,
+ const state_machine **out_sm,
+ unsigned *out_sm_idx,
+ std::unique_ptr<sm_context> *out_sm_context)
+{
+ if (!m_new_state)
+ return false;
+
+ unsigned sm_idx;
+ if (!m_ext_state.get_sm_idx_by_name (name, &sm_idx))
+ return false;
+
+ const state_machine *sm = &m_ext_state.get_sm (sm_idx);
+ sm_state_map *new_smap = m_new_state->m_checker_states[sm_idx];
+
+ *out_smap = new_smap;
+ *out_sm = sm;
+ if (out_sm_idx)
+ *out_sm_idx = sm_idx;
+ if (out_sm_context)
+ {
+ const sm_state_map *old_smap = m_old_state->m_checker_states[sm_idx];
+ *out_sm_context
+ = make_unique<impl_sm_context> (*m_eg,
+ sm_idx,
+ *sm,
+ m_enode_for_diag,
+ m_old_state,
+ m_new_state,
+ old_smap,
+ new_smap,
+ m_path_ctxt,
+ m_stmt_finder,
+ false);
+ }
+ return true;
+}
+
/* Subclass of stmt_finder for finding the best stmt to report the leak at,
given the emission path. */
@@ -541,9 +544,9 @@ public:
leak_stmt_finder (const exploded_graph &eg, tree var)
: m_eg (eg), m_var (var) {}
- stmt_finder *clone () const final override
+ std::unique_ptr<stmt_finder> clone () const final override
{
- return new leak_stmt_finder (m_eg, m_var);
+ return make_unique<leak_stmt_finder> (m_eg, m_var);
}
const gimple *find_stmt (const exploded_path &epath)
@@ -864,12 +867,12 @@ impl_region_model_context::on_state_leak (const state_machine &sm,
}
tree leaked_tree_for_diag = fixup_tree_for_diagnostic (leaked_tree);
- pending_diagnostic *pd = sm.on_leak (leaked_tree_for_diag);
+ std::unique_ptr<pending_diagnostic> pd = sm.on_leak (leaked_tree_for_diag);
if (pd)
m_eg->get_diagnostic_manager ().add_diagnostic
(&sm, m_enode_for_diag, m_enode_for_diag->get_supernode (),
m_stmt, &stmt_finder,
- leaked_tree_for_diag, sval, state, pd);
+ leaked_tree_for_diag, sval, state, std::move (pd));
}
/* Implementation of region_model_context::on_condition vfunc.
@@ -926,6 +929,22 @@ impl_region_model_context::on_bounded_ranges (const svalue &sval,
}
}
+/* Implementation of region_model_context::on_pop_frame vfunc.
+ Notify all state machines about the frame being popped, which
+ could lead to states being discarded. */
+
+void
+impl_region_model_context::on_pop_frame (const frame_region *frame_reg)
+{
+ int sm_idx;
+ sm_state_map *smap;
+ FOR_EACH_VEC_ELT (m_new_state->m_checker_states, sm_idx, smap)
+ {
+ const state_machine &sm = m_ext_state.get_sm (sm_idx);
+ sm.on_pop_frame (smap, frame_reg);
+ }
+}
+
/* Implementation of region_model_context::on_phi vfunc.
Notify all state machines about the phi, which could lead to
state transitions. */
@@ -1505,7 +1524,6 @@ exploded_node::on_stmt_pre (exploded_graph &eg,
/* Otherwise, defer to m_region_model. */
state->m_region_model->on_stmt_pre (stmt,
- out_terminate_path,
out_unknown_side_effects,
ctxt);
}
@@ -1649,10 +1667,10 @@ exploded_node::replay_call_summary (exploded_graph &eg,
call_summary_replay r (cd, called_fn, summary, ext_state);
if (path_ctxt)
- path_ctxt->bifurcate (new call_summary_edge_info (cd,
- called_fn,
- summary,
- ext_state));
+ path_ctxt->bifurcate (make_unique<call_summary_edge_info> (cd,
+ called_fn,
+ summary,
+ ext_state));
}
@@ -1771,11 +1789,12 @@ public:
/* Compare with diagnostic_manager::add_events_for_superedge. */
const int src_stack_depth = src_point.get_stack_depth ();
m_stack_pop_event = new precanned_custom_event
- (src_point.get_location (),
- src_point.get_fndecl (),
- src_stack_depth,
+ (event_loc_info (src_point.get_location (),
+ src_point.get_fndecl (),
+ src_stack_depth),
"stack frame is popped here, invalidating saved environment");
- emission_path->add_event (m_stack_pop_event);
+ emission_path->add_event
+ (std::unique_ptr<custom_event> (m_stack_pop_event));
return false;
}
return false;
@@ -1845,7 +1864,9 @@ exploded_node::on_longjmp (exploded_graph &eg,
/* Verify that the setjmp's call_stack hasn't been popped. */
if (!valid_longjmp_stack_p (longjmp_point, setjmp_point))
{
- ctxt->warn (new stale_jmp_buf (setjmp_call, longjmp_call, setjmp_point));
+ ctxt->warn (make_unique<stale_jmp_buf> (setjmp_call,
+ longjmp_call,
+ setjmp_point));
return;
}
@@ -1879,7 +1900,7 @@ exploded_node::on_longjmp (exploded_graph &eg,
{
exploded_edge *eedge
= eg.add_edge (const_cast<exploded_node *> (this), next, NULL,
- new rewind_info_t (tmp_setjmp_record, longjmp_call));
+ make_unique<rewind_info_t> (tmp_setjmp_record, longjmp_call));
/* For any diagnostics that were queued here (such as leaks) we want
the checker_path to show the rewinding events after the "final event"
@@ -1988,16 +2009,22 @@ exploded_node::dump_succs_and_preds (FILE *outf) const
/* Implementation of custom_edge_info::update_model vfunc
for dynamic_call_info_t.
- Update state for the dynamically discorverd calls */
+ Update state for a dynamically discovered call (or return), by pushing
+ or popping the a frame for the appropriate function. */
bool
dynamic_call_info_t::update_model (region_model *model,
const exploded_edge *eedge,
- region_model_context *) const
+ region_model_context *ctxt) const
{
gcc_assert (eedge);
- const program_state &dest_state = eedge->m_dest->get_state ();
- *model = *dest_state.m_region_model;
+ if (m_is_returning_call)
+ model->update_for_return_gcall (m_dynamic_call, ctxt);
+ else
+ {
+ function *callee = eedge->m_dest->get_function ();
+ model->update_for_gcall (m_dynamic_call, ctxt, callee);
+ }
return true;
}
@@ -2016,19 +2043,21 @@ dynamic_call_info_t::add_events_to_path (checker_path *emission_path,
const int dest_stack_depth = dest_point.get_stack_depth ();
if (m_is_returning_call)
- emission_path->add_event (new return_event (eedge,
- (m_dynamic_call
- ? m_dynamic_call->location
- : UNKNOWN_LOCATION),
- dest_point.get_fndecl (),
- dest_stack_depth));
+ emission_path->add_event
+ (make_unique<return_event> (eedge,
+ event_loc_info (m_dynamic_call
+ ? m_dynamic_call->location
+ : UNKNOWN_LOCATION,
+ dest_point.get_fndecl (),
+ dest_stack_depth)));
else
- emission_path->add_event (new call_event (eedge,
- (m_dynamic_call
- ? m_dynamic_call->location
- : UNKNOWN_LOCATION),
- src_point.get_fndecl (),
- src_stack_depth));
+ emission_path->add_event
+ (make_unique<call_event> (eedge,
+ event_loc_info (m_dynamic_call
+ ? m_dynamic_call->location
+ : UNKNOWN_LOCATION,
+ src_point.get_fndecl (),
+ src_stack_depth)));
}
/* class rewind_info_t : public custom_edge_info. */
@@ -2073,15 +2102,19 @@ rewind_info_t::add_events_to_path (checker_path *emission_path,
const int dst_stack_depth = dst_point.get_stack_depth ();
emission_path->add_event
- (new rewind_from_longjmp_event
- (&eedge, get_longjmp_call ()->location,
- src_point.get_fndecl (),
- src_stack_depth, this));
+ (make_unique<rewind_from_longjmp_event>
+ (&eedge,
+ event_loc_info (get_longjmp_call ()->location,
+ src_point.get_fndecl (),
+ src_stack_depth),
+ this));
emission_path->add_event
- (new rewind_to_setjmp_event
- (&eedge, get_setjmp_call ()->location,
- dst_point.get_fndecl (),
- dst_stack_depth, this));
+ (make_unique<rewind_to_setjmp_event>
+ (&eedge,
+ event_loc_info (get_setjmp_call ()->location,
+ dst_point.get_fndecl (),
+ dst_stack_depth),
+ this));
}
/* class exploded_edge : public dedge<eg_traits>. */
@@ -2090,19 +2123,12 @@ rewind_info_t::add_events_to_path (checker_path *emission_path,
exploded_edge::exploded_edge (exploded_node *src, exploded_node *dest,
const superedge *sedge,
- custom_edge_info *custom_info)
+ std::unique_ptr<custom_edge_info> custom_info)
: dedge<eg_traits> (src, dest), m_sedge (sedge),
- m_custom_info (custom_info)
+ m_custom_info (std::move (custom_info))
{
}
-/* exploded_edge's dtor. */
-
-exploded_edge::~exploded_edge ()
-{
- delete m_custom_info;
-}
-
/* Implementation of dedge::dump_dot vfunc for exploded_edge.
Use the label of the underlying superedge, if any. */
@@ -2629,9 +2655,9 @@ mark_params_as_tainted (program_state *state, tree fndecl,
class tainted_args_function_custom_event : public custom_event
{
public:
- tainted_args_function_custom_event (location_t loc, tree fndecl, int depth)
- : custom_event (loc, fndecl, depth),
- m_fndecl (fndecl)
+ tainted_args_function_custom_event (const event_loc_info &loc_info)
+ : custom_event (loc_info),
+ m_fndecl (loc_info.m_fndecl)
{
}
@@ -2674,8 +2700,8 @@ public:
const exploded_edge &) const final override
{
emission_path->add_event
- (new tainted_args_function_custom_event
- (DECL_SOURCE_LOCATION (m_fndecl), m_fndecl, 0));
+ (make_unique<tainted_args_function_custom_event>
+ (event_loc_info (DECL_SOURCE_LOCATION (m_fndecl), m_fndecl, 0)));
}
private:
@@ -2710,12 +2736,12 @@ exploded_graph::add_function_entry (function *fun)
program_state state (m_ext_state);
state.push_frame (m_ext_state, fun);
- custom_edge_info *edge_info = NULL;
+ std::unique_ptr<custom_edge_info> edge_info = NULL;
if (lookup_attribute ("tainted_args", DECL_ATTRIBUTES (fun->decl)))
{
if (mark_params_as_tainted (&state, fun->decl, m_ext_state))
- edge_info = new tainted_args_function_info (fun->decl);
+ edge_info = make_unique<tainted_args_function_info> (fun->decl);
}
if (!state.m_valid)
@@ -2723,12 +2749,9 @@ exploded_graph::add_function_entry (function *fun)
exploded_node *enode = get_or_create_node (point, state, NULL);
if (!enode)
- {
- delete edge_info;
- return NULL;
- }
+ return NULL;
- add_edge (m_origin, enode, NULL, edge_info);
+ add_edge (m_origin, enode, NULL, std::move (edge_info));
m_functions_with_enodes.add (fun);
@@ -2926,18 +2949,19 @@ exploded_graph::get_or_create_node (const program_point &point,
/* Add an exploded_edge from SRC to DEST, recording its association
with SEDGE (which may be NULL), and, if non-NULL, taking ownership
- of REWIND_INFO.
+ of CUSTOM_INFO.
Return the newly-created eedge. */
exploded_edge *
exploded_graph::add_edge (exploded_node *src, exploded_node *dest,
const superedge *sedge,
- custom_edge_info *custom_info)
+ std::unique_ptr<custom_edge_info> custom_info)
{
if (get_logger ())
get_logger ()->log ("creating edge EN: %i -> EN: %i",
src->m_index, dest->m_index);
- exploded_edge *e = new exploded_edge (src, dest, sedge, custom_info);
+ exploded_edge *e = new exploded_edge (src, dest, sedge,
+ std::move (custom_info));
digraph<eg_traits>::add_edge (e);
return e;
}
@@ -3049,7 +3073,7 @@ class tainted_args_field_custom_event : public custom_event
{
public:
tainted_args_field_custom_event (tree field)
- : custom_event (DECL_SOURCE_LOCATION (field), NULL_TREE, 0),
+ : custom_event (event_loc_info (DECL_SOURCE_LOCATION (field), NULL_TREE, 0)),
m_field (field)
{
}
@@ -3073,9 +3097,9 @@ private:
class tainted_args_callback_custom_event : public custom_event
{
public:
- tainted_args_callback_custom_event (location_t loc, tree fndecl, int depth,
- tree field)
- : custom_event (loc, fndecl, depth),
+ tainted_args_callback_custom_event (const event_loc_info &loc_info,
+ tree field)
+ : custom_event (loc_info),
m_field (field)
{
}
@@ -3121,14 +3145,16 @@ public:
/* Show the field in the struct declaration, e.g.
"(1) field 'store' is marked with '__attribute__((tainted_args))'" */
emission_path->add_event
- (new tainted_args_field_custom_event (m_field));
+ (make_unique<tainted_args_field_custom_event> (m_field));
/* Show the callback in the initializer
e.g.
"(2) function 'gadget_dev_desc_UDC_store' used as initializer
for field 'store' marked with '__attribute__((tainted_args))'". */
emission_path->add_event
- (new tainted_args_callback_custom_event (m_loc, m_fndecl, 0, m_field));
+ (make_unique<tainted_args_callback_custom_event>
+ (event_loc_info (m_loc, m_fndecl, 0),
+ m_field));
}
private:
@@ -3184,9 +3210,8 @@ add_tainted_args_callback (exploded_graph *eg, tree field, tree fndecl,
}
}
- tainted_args_call_info *info
- = new tainted_args_call_info (field, fndecl, loc);
- eg->add_edge (eg->get_origin (), enode, NULL, info);
+ eg->add_edge (eg->get_origin (), enode, NULL,
+ make_unique<tainted_args_call_info> (field, fndecl, loc));
}
/* Callback for walk_tree for finding callbacks within initializers;
@@ -3783,7 +3808,7 @@ exploded_graph::maybe_create_dynamic_call (const gcall *call,
node);
if (enode)
add_edge (node,enode, NULL,
- new dynamic_call_info_t (call));
+ make_unique<dynamic_call_info_t> (call));
return true;
}
}
@@ -3814,7 +3839,7 @@ public:
}
void
- bifurcate (custom_edge_info *info) final override
+ bifurcate (std::unique_ptr<custom_edge_info> info) final override
{
if (m_state_at_bifurcation)
/* Verify that the state at bifurcation is consistent when we
@@ -3827,7 +3852,7 @@ public:
= std::unique_ptr<program_state> (new program_state (*m_cur_state));
/* Take ownership of INFO. */
- m_custom_eedge_infos.safe_push (info);
+ m_custom_eedge_infos.safe_push (info.release ());
}
void terminate_path () final override
@@ -4109,8 +4134,10 @@ exploded_graph::process_node (exploded_node *node)
instances. For example, to handle a "realloc" call, we
might split into 3 states, for the "failure",
"resizing in place", and "moving to a new buffer" cases. */
- for (auto edge_info : path_ctxt.get_custom_eedge_infos ())
+ for (auto edge_info_iter : path_ctxt.get_custom_eedge_infos ())
{
+ /* Take ownership of the edge infos from the path_ctxt. */
+ std::unique_ptr<custom_edge_info> edge_info (edge_info_iter);
if (logger)
{
logger->start_log_line ();
@@ -4137,18 +4164,12 @@ exploded_graph::process_node (exploded_node *node)
exploded_node *next2
= get_or_create_node (next_point, bifurcated_new_state, node);
if (next2)
- {
- /* Take ownership of edge_info. */
- add_edge (node, next2, NULL, edge_info);
- }
- else
- delete edge_info;
+ add_edge (node, next2, NULL, std::move (edge_info));
}
else
{
if (logger)
logger->log ("infeasible state, not adding node");
- delete edge_info;
}
}
}
@@ -4243,7 +4264,7 @@ exploded_graph::process_node (exploded_node *node)
const svalue *fn_ptr_sval
= model->get_rvalue (fn_ptr, &ctxt);
if (fn_ptr_sval->all_zeroes_p ())
- ctxt.warn (new jump_through_null (call));
+ ctxt.warn (make_unique<jump_through_null> (call));
}
/* An unknown function or a special function was called
@@ -4273,7 +4294,12 @@ exploded_graph::process_node (exploded_node *node)
exploded_node *next = get_or_create_node (next_point, next_state,
node);
if (next)
- add_edge (node, next, succ);
+ {
+ add_edge (node, next, succ);
+
+ /* We might have a function entrypoint. */
+ detect_infinite_recursion (next);
+ }
}
/* Return from the calls which doesn't have a return superedge.
@@ -4304,7 +4330,7 @@ exploded_graph::process_node (exploded_node *node)
node);
if (enode)
add_edge (node, enode, NULL,
- new dynamic_call_info_t (call, true));
+ make_unique<dynamic_call_info_t> (call, true));
}
}
}
@@ -4614,8 +4640,9 @@ exploded_path::get_final_enode () const
feasibility_problem to *OUT. */
bool
-exploded_path::feasible_p (logger *logger, feasibility_problem **out,
- engine *eng, const exploded_graph *eg) const
+exploded_path::feasible_p (logger *logger,
+ std::unique_ptr<feasibility_problem> *out,
+ engine *eng, const exploded_graph *eg) const
{
LOG_SCOPE (logger);
@@ -4642,8 +4669,8 @@ exploded_path::feasible_p (logger *logger, feasibility_problem **out,
const program_point &src_point = src_enode.get_point ();
const gimple *last_stmt
= src_point.get_supernode ()->get_last_stmt ();
- *out = new feasibility_problem (edge_idx, *eedge,
- last_stmt, rc);
+ *out = make_unique<feasibility_problem> (edge_idx, *eedge,
+ last_stmt, rc);
}
else
delete rc;
@@ -4802,9 +4829,7 @@ feasibility_state::maybe_update_for_edge (logger *logger,
m_model.on_asm_stmt (asm_stmt, NULL);
else if (const gcall *call = dyn_cast <const gcall *> (stmt))
{
- bool terminate_path;
- bool unknown_side_effects
- = m_model.on_call_pre (call, NULL, &terminate_path);
+ bool unknown_side_effects = m_model.on_call_pre (call, NULL);
m_model.on_call_post (call, unknown_side_effects, NULL);
}
else if (const greturn *return_ = dyn_cast <const greturn *> (stmt))
@@ -5965,17 +5990,17 @@ public:
m_logger (logger)
{}
- void register_state_machine (state_machine *sm) final override
+ void register_state_machine (std::unique_ptr<state_machine> sm) final override
{
LOG_SCOPE (m_logger);
- m_checkers->safe_push (sm);
+ m_checkers->safe_push (sm.release ());
}
void register_known_function (const char *name,
- known_function *kf) final override
+ std::unique_ptr<known_function> kf) final override
{
LOG_SCOPE (m_logger);
- m_known_fn_mgr->add (name, kf);
+ m_known_fn_mgr->add (name, std::move (kf));
}
logger *get_logger () const final override
@@ -6001,6 +6026,7 @@ impl_run_checkers (logger *logger)
logger->log ("BITS_BIG_ENDIAN: %i", BITS_BIG_ENDIAN ? 1 : 0);
logger->log ("BYTES_BIG_ENDIAN: %i", BYTES_BIG_ENDIAN ? 1 : 0);
logger->log ("WORDS_BIG_ENDIAN: %i", WORDS_BIG_ENDIAN ? 1 : 0);
+ log_stashed_constants (logger);
}
/* If using LTO, ensure that the cgraph nodes have function bodies. */
@@ -6041,6 +6067,8 @@ impl_run_checkers (logger *logger)
auto_delete_vec <state_machine> checkers;
make_checkers (checkers, logger);
+ register_known_functions (*eng.get_known_function_manager ());
+
plugin_analyzer_init_impl data (&checkers,
eng.get_known_function_manager (),
logger);
@@ -6110,6 +6138,34 @@ impl_run_checkers (logger *logger)
delete purge_map;
}
+/* Handle -fdump-analyzer and -fdump-analyzer-stderr. */
+static FILE *dump_fout = NULL;
+
+/* Track if we're responsible for closing dump_fout. */
+static bool owns_dump_fout = false;
+
+/* If dumping is enabled, attempt to create dump_fout if it hasn't already
+ been opened. Return it. */
+
+FILE *
+get_or_create_any_logfile ()
+{
+ if (!dump_fout)
+ {
+ if (flag_dump_analyzer_stderr)
+ dump_fout = stderr;
+ else if (flag_dump_analyzer)
+ {
+ char *dump_filename = concat (dump_base_name, ".analyzer.txt", NULL);
+ dump_fout = fopen (dump_filename, "w");
+ free (dump_filename);
+ if (dump_fout)
+ owns_dump_fout = true;
+ }
+ }
+ return dump_fout;
+}
+
/* External entrypoint to the analysis "engine".
Set up any dumps, then call impl_run_checkers. */
@@ -6119,23 +6175,9 @@ run_checkers ()
/* Save input_location. */
location_t saved_input_location = input_location;
- /* Handle -fdump-analyzer and -fdump-analyzer-stderr. */
- FILE *dump_fout = NULL;
- /* Track if we're responsible for closing dump_fout. */
- bool owns_dump_fout = false;
- if (flag_dump_analyzer_stderr)
- dump_fout = stderr;
- else if (flag_dump_analyzer)
- {
- char *dump_filename = concat (dump_base_name, ".analyzer.txt", NULL);
- dump_fout = fopen (dump_filename, "w");
- free (dump_filename);
- if (dump_fout)
- owns_dump_fout = true;
- }
-
{
log_user the_logger (NULL);
+ get_or_create_any_logfile ();
if (dump_fout)
the_logger.set_logger (new logger (dump_fout, 0, 0,
*global_dc->printer));
@@ -6148,7 +6190,11 @@ run_checkers ()
}
if (owns_dump_fout)
- fclose (dump_fout);
+ {
+ fclose (dump_fout);
+ owns_dump_fout = false;
+ dump_fout = NULL;
+ }
/* Restore input_location. Subsequent passes may assume that input_location
is some arbitrary value *not* in the block tree, which might be violated
diff --git a/gcc/analyzer/exploded-graph.h b/gcc/analyzer/exploded-graph.h
index 5996252..86644c1 100644
--- a/gcc/analyzer/exploded-graph.h
+++ b/gcc/analyzer/exploded-graph.h
@@ -56,8 +56,8 @@ class impl_region_model_context : public region_model_context
uncertainty_t *uncertainty,
logger *logger = NULL);
- bool warn (pending_diagnostic *d) final override;
- void add_note (pending_note *pn) final override;
+ bool warn (std::unique_ptr<pending_diagnostic> d) final override;
+ void add_note (std::unique_ptr<pending_note> pn) final override;
void on_svalue_leak (const svalue *) override;
void on_liveness_change (const svalue_set &live_svalues,
const region_model *model) final override;
@@ -77,6 +77,8 @@ class impl_region_model_context : public region_model_context
void on_bounded_ranges (const svalue &sval,
const bounded_ranges &ranges) final override;
+ void on_pop_frame (const frame_region *frame_reg) final override;
+
void on_unknown_change (const svalue *sval, bool is_mutable) final override;
void on_phi (const gphi *phi, tree rhs) final override;
@@ -90,16 +92,18 @@ class impl_region_model_context : public region_model_context
void purge_state_involving (const svalue *sval) final override;
- void bifurcate (custom_edge_info *info) final override;
+ void bifurcate (std::unique_ptr<custom_edge_info> info) final override;
void terminate_path () final override;
const extrinsic_state *get_ext_state () const final override
{
return &m_ext_state;
}
- bool get_state_map_by_name (const char *name,
- sm_state_map **out_smap,
- const state_machine **out_sm,
- unsigned *out_sm_idx) override;
+ bool
+ get_state_map_by_name (const char *name,
+ sm_state_map **out_smap,
+ const state_machine **out_sm,
+ unsigned *out_sm_idx,
+ std::unique_ptr<sm_context> *out_sm_context) override;
const gimple *get_stmt () const override { return m_stmt; }
@@ -367,8 +371,7 @@ class exploded_edge : public dedge<eg_traits>
public:
exploded_edge (exploded_node *src, exploded_node *dest,
const superedge *sedge,
- custom_edge_info *custom_info);
- ~exploded_edge ();
+ std::unique_ptr<custom_edge_info> custom_info);
void dump_dot (graphviz_out *gv, const dump_args_t &args)
const final override;
void dump_dot_label (pretty_printer *pp) const;
@@ -380,10 +383,8 @@ class exploded_edge : public dedge<eg_traits>
/* NULL for most edges; will be non-NULL for special cases
such as an unwind from a longjmp to a setjmp, or when
- a signal is delivered to a signal-handler.
-
- Owned by this class. */
- custom_edge_info *m_custom_info;
+ a signal is delivered to a signal-handler. */
+ std::unique_ptr<custom_edge_info> m_custom_info;
private:
DISABLE_COPY_AND_ASSIGN (exploded_edge);
@@ -801,7 +802,7 @@ public:
exploded_node *enode_for_diag);
exploded_edge *add_edge (exploded_node *src, exploded_node *dest,
const superedge *sedge,
- custom_edge_info *custom = NULL);
+ std::unique_ptr<custom_edge_info> custom = NULL);
per_program_point_data *
get_or_create_per_program_point_data (const program_point &);
@@ -852,6 +853,11 @@ public:
void on_escaped_function (tree fndecl);
+ /* In infinite-recursion.cc */
+ void detect_infinite_recursion (exploded_node *enode);
+ exploded_node *find_previous_entry_to (function *top_of_stack_fun,
+ exploded_node *enode) const;
+
private:
void print_bar_charts (pretty_printer *pp) const;
@@ -926,7 +932,7 @@ public:
void dump_to_file (const char *filename,
const extrinsic_state &ext_state) const;
- bool feasible_p (logger *logger, feasibility_problem **out,
+ bool feasible_p (logger *logger, std::unique_ptr<feasibility_problem> *out,
engine *eng, const exploded_graph *eg) const;
auto_vec<const exploded_edge *> m_edges;
@@ -991,7 +997,7 @@ class stmt_finder
{
public:
virtual ~stmt_finder () {}
- virtual stmt_finder *clone () const = 0;
+ virtual std::unique_ptr<stmt_finder> clone () const = 0;
virtual const gimple *find_stmt (const exploded_path &epath) = 0;
};
diff --git a/gcc/analyzer/feasible-graph.cc b/gcc/analyzer/feasible-graph.cc
index a946e4c..7c3dcf8 100644
--- a/gcc/analyzer/feasible-graph.cc
+++ b/gcc/analyzer/feasible-graph.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
@@ -189,10 +190,10 @@ feasible_graph::add_feasibility_problem (feasible_node *src_fnode,
/* Make an exploded_path from the origin to FNODE's exploded_node,
following the edges in the feasible_graph. */
-exploded_path *
+std::unique_ptr<exploded_path>
feasible_graph::make_epath (feasible_node *fnode) const
{
- exploded_path *epath = new exploded_path ();
+ std::unique_ptr<exploded_path> epath (new exploded_path ());
/* FG is actually a tree. Built the path backwards, by walking
backwards from FNODE until we reach the origin. */
diff --git a/gcc/analyzer/feasible-graph.h b/gcc/analyzer/feasible-graph.h
index 2530119..9f37b08 100644
--- a/gcc/analyzer/feasible-graph.h
+++ b/gcc/analyzer/feasible-graph.h
@@ -195,7 +195,7 @@ class feasible_graph : public digraph <fg_traits>
const exploded_edge *eedge,
rejected_constraint *rc);
- exploded_path *make_epath (feasible_node *fnode) const;
+ std::unique_ptr<exploded_path> make_epath (feasible_node *fnode) const;
void dump_feasible_path (const feasible_node &dst_fnode,
const char *filename) const;
diff --git a/gcc/analyzer/infinite-recursion.cc b/gcc/analyzer/infinite-recursion.cc
new file mode 100644
index 0000000..1a17d31f
--- /dev/null
+++ b/gcc/analyzer/infinite-recursion.cc
@@ -0,0 +1,482 @@
+/* Detection of infinite recursion.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#define INCLUDE_MEMORY
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "fold-const.h"
+#include "gcc-rich-location.h"
+#include "alloc-pool.h"
+#include "fibonacci_heap.h"
+#include "shortest-paths.h"
+#include "diagnostic-core.h"
+#include "diagnostic-event-id.h"
+#include "diagnostic-path.h"
+#include "diagnostic-metadata.h"
+#include "function.h"
+#include "pretty-print.h"
+#include "sbitmap.h"
+#include "bitmap.h"
+#include "tristate.h"
+#include "ordered-hash-map.h"
+#include "selftest.h"
+#include "json.h"
+#include "analyzer/analyzer.h"
+#include "analyzer/analyzer-logging.h"
+#include "analyzer/call-string.h"
+#include "analyzer/program-point.h"
+#include "analyzer/store.h"
+#include "analyzer/region-model.h"
+#include "analyzer/constraint-manager.h"
+#include "analyzer/sm.h"
+#include "analyzer/pending-diagnostic.h"
+#include "analyzer/diagnostic-manager.h"
+#include "cfg.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-pretty-print.h"
+#include "cgraph.h"
+#include "digraph.h"
+#include "analyzer/supergraph.h"
+#include "analyzer/program-state.h"
+#include "analyzer/exploded-graph.h"
+#include "make-unique.h"
+#include "analyzer/checker-path.h"
+
+/* A subclass of pending_diagnostic for complaining about suspected
+ infinite recursion. */
+
+class infinite_recursion_diagnostic
+: public pending_diagnostic_subclass<infinite_recursion_diagnostic>
+{
+public:
+ infinite_recursion_diagnostic (const exploded_node *prev_entry_enode,
+ const exploded_node *new_entry_enode,
+ tree callee_fndecl)
+ : m_prev_entry_enode (prev_entry_enode),
+ m_new_entry_enode (new_entry_enode),
+ m_callee_fndecl (callee_fndecl),
+ m_prev_entry_event (NULL)
+ {}
+
+ const char *get_kind () const final override
+ {
+ return "infinite_recursion_diagnostic";
+ }
+
+ bool operator== (const infinite_recursion_diagnostic &other) const
+ {
+ return m_callee_fndecl == other.m_callee_fndecl;
+ }
+
+ int get_controlling_option () const final override
+ {
+ return OPT_Wanalyzer_infinite_recursion;
+ }
+
+ bool emit (rich_location *rich_loc) final override
+ {
+ /* "CWE-674: Uncontrolled Recursion". */
+ diagnostic_metadata m;
+ m.add_cwe (674);
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "infinite recursion");
+ }
+
+ label_text describe_final_event (const evdesc::final_event &ev) final override
+ {
+ const int frames_consumed = (m_new_entry_enode->get_stack_depth ()
+ - m_prev_entry_enode->get_stack_depth ());
+ if (frames_consumed > 1)
+ return ev.formatted_print
+ ("apparently infinite chain of mutually-recursive function calls,"
+ " consuming %i stack frames per recursion",
+ frames_consumed);
+ else
+ return ev.formatted_print ("apparently infinite recursion");
+ }
+
+ void
+ add_function_entry_event (const exploded_edge &eedge,
+ checker_path *emission_path) final override
+ {
+ /* Subclass of function_entry_event for use when reporting both
+ the initial and subsequent entries to the function of interest,
+ allowing for cross-referencing the first event in the description
+ of the second. */
+ class recursive_function_entry_event : public function_entry_event
+ {
+ public:
+ recursive_function_entry_event (const program_point &dst_point,
+ const infinite_recursion_diagnostic &pd,
+ bool topmost)
+ : function_entry_event (dst_point),
+ m_pd (pd),
+ m_topmost (topmost)
+ {
+ }
+
+ label_text
+ get_desc (bool can_colorize) const final override
+ {
+ if (m_topmost)
+ {
+ if (m_pd.m_prev_entry_event
+ && m_pd.m_prev_entry_event->get_id_ptr ()->known_p ())
+ return make_label_text
+ (can_colorize,
+ "recursive entry to %qE; previously entered at %@",
+ m_effective_fndecl,
+ m_pd.m_prev_entry_event->get_id_ptr ());
+ else
+ return make_label_text (can_colorize, "recursive entry to %qE",
+ m_effective_fndecl);
+ }
+ else
+ return make_label_text (can_colorize, "initial entry to %qE",
+ m_effective_fndecl);
+ }
+
+ private:
+ const infinite_recursion_diagnostic &m_pd;
+ bool m_topmost;
+ };
+ const exploded_node *dst_node = eedge.m_dest;
+ const program_point &dst_point = dst_node->get_point ();
+ if (eedge.m_dest == m_prev_entry_enode)
+ {
+ gcc_assert (m_prev_entry_event == NULL);
+ std::unique_ptr<checker_event> prev_entry_event
+ = make_unique <recursive_function_entry_event> (dst_point,
+ *this, false);
+ m_prev_entry_event = prev_entry_event.get ();
+ emission_path->add_event (std::move (prev_entry_event));
+ }
+ else if (eedge.m_dest == m_new_entry_enode)
+ emission_path->add_event
+ (make_unique<recursive_function_entry_event> (dst_point, *this, true));
+ else
+ pending_diagnostic::add_function_entry_event (eedge, emission_path);
+ }
+
+ /* Customize the location where the warning_event appears, putting
+ it at the topmost entrypoint to the function. */
+ void add_final_event (const state_machine *,
+ const exploded_node *,
+ const gimple *,
+ tree,
+ state_machine::state_t,
+ checker_path *emission_path) final override
+ {
+ gcc_assert (m_new_entry_enode);
+ emission_path->add_event
+ (make_unique<warning_event>
+ (event_loc_info (m_new_entry_enode->get_supernode
+ ()->get_start_location (),
+ m_callee_fndecl,
+ m_new_entry_enode->get_stack_depth ()),
+ NULL, NULL, NULL));
+ }
+
+private:
+ const exploded_node *m_prev_entry_enode;
+ const exploded_node *m_new_entry_enode;
+ tree m_callee_fndecl;
+ const checker_event *m_prev_entry_event;
+};
+
+/* Return true iff ENODE is the PK_BEFORE_SUPERNODE at a function
+ entrypoint. */
+
+static bool
+is_entrypoint_p (exploded_node *enode)
+{
+ /* Look for an entrypoint to a function... */
+ const supernode *snode = enode->get_supernode ();
+ if (!snode)
+ return false;
+ if (!snode->entry_p ())
+ return false;;
+ const program_point &point = enode->get_point ();
+ if (point.get_kind () != PK_BEFORE_SUPERNODE)
+ return false;
+ return true;
+}
+
+/* Walk backwards through the eg, looking for the first
+ enode we find that's also the entrypoint of the same function. */
+
+exploded_node *
+exploded_graph::find_previous_entry_to (function *top_of_stack_fun,
+ exploded_node *enode) const
+{
+ auto_vec<exploded_node *> worklist;
+ hash_set<exploded_node *> visited;
+
+ visited.add (enode);
+ for (auto in_edge : enode->m_preds)
+ worklist.safe_push (in_edge->m_src);
+
+ while (worklist.length () > 0)
+ {
+ exploded_node *iter = worklist.pop ();
+
+ if (is_entrypoint_p (iter)
+ && iter->get_function () == top_of_stack_fun)
+ return iter;
+
+ if (visited.contains (iter))
+ continue;
+ visited.add (iter);
+ for (auto in_edge : iter->m_preds)
+ worklist.safe_push (in_edge->m_src);
+ }
+
+ /* Not found. */
+ return NULL;
+}
+
+/* Given BASE_REG within ENCLOSING_FRAME (such as a function parameter),
+ remap it to the equivalent region within EQUIV_PREV_FRAME.
+
+ For example, given param "n" within frame "foo@3", and equiv prev frame
+ "foo@1", remap it to param "n" within frame "foo@1". */
+
+static const region *
+remap_enclosing_frame (const region *base_reg,
+ const frame_region *enclosing_frame,
+ const frame_region *equiv_prev_frame,
+ region_model_manager *mgr)
+{
+ gcc_assert (base_reg->get_parent_region () == enclosing_frame);
+ switch (base_reg->get_kind ())
+ {
+ default:
+ /* We should only encounter params and varargs at the topmost
+ entrypoint. */
+ gcc_unreachable ();
+
+ case RK_VAR_ARG:
+ {
+ const var_arg_region *var_arg_reg = (const var_arg_region *)base_reg;
+ return mgr->get_var_arg_region (equiv_prev_frame,
+ var_arg_reg->get_index ());
+ }
+ case RK_DECL:
+ {
+ const decl_region *decl_reg = (const decl_region *)base_reg;
+ return equiv_prev_frame->get_region_for_local (mgr,
+ decl_reg->get_decl (),
+ NULL);
+ }
+ }
+}
+
+/* Compare the state of memory at NEW_ENTRY_ENODE and PREV_ENTRY_ENODE,
+ both of which are entrypoints to the same function, where recursion has
+ occurred.
+
+ Return true if the state of NEW_ENTRY_ENODE is sufficiently different
+ from PREV_ENTRY_ENODE to suggests that some variant is being modified,
+ and thus the recursion isn't infinite.
+
+ Return false if the states are effectively the same, suggesting that
+ the recursion is infinite.
+
+ For example, consider mutually recursive functions "foo" and "bar".
+ At the entrypoint to a "foo" frame where we've detected recursion,
+ we might have three frames on the stack: the new 'foo'@3, an inner
+ 'bar'@2, and the innermost 'foo'@1.
+
+ (gdb) call enode->dump(m_ext_state)
+ EN: 16
+ callstring: [(SN: 9 -> SN: 3 in foo), (SN: 5 -> SN: 8 in bar)]
+ before SN: 0 (NULL from-edge)
+
+ rmodel:
+ stack depth: 3
+ frame (index 2): frame: ‘foo’@3
+ frame (index 1): frame: ‘bar’@2
+ frame (index 0): frame: ‘foo’@1
+ clusters within root region
+ cluster for: (*INIT_VAL(f_4(D)))
+ clusters within frame: ‘bar’@2
+ cluster for: b_2(D): INIT_VAL(f_4(D))
+ clusters within frame: ‘foo’@3
+ cluster for: f_4(D): INIT_VAL(f_4(D))
+ m_called_unknown_fn: FALSE
+
+ whereas for the previous entry node we'd have just the innermost
+ 'foo'@1
+
+ (gdb) call prev_entry_enode->dump(m_ext_state)
+ EN: 1
+ callstring: []
+ before SN: 0 (NULL from-edge)
+
+ rmodel:
+ stack depth: 1
+ frame (index 0): frame: ‘foo’@1
+ clusters within root region
+ cluster for: (*INIT_VAL(f_4(D)))
+ m_called_unknown_fn: FALSE
+
+ We want to abstract away frames 1 and 2 in the new entry enode,
+ and compare its frame 3 with the frame 1 in the previous entry
+ enode, and determine if enough state changes between them to
+ rule out infinite recursion. */
+
+static bool
+sufficiently_different_p (exploded_node *new_entry_enode,
+ exploded_node *prev_entry_enode,
+ logger *logger)
+{
+ LOG_SCOPE (logger);
+ gcc_assert (new_entry_enode);
+ gcc_assert (prev_entry_enode);
+ gcc_assert (is_entrypoint_p (new_entry_enode));
+ gcc_assert (is_entrypoint_p (prev_entry_enode));
+
+ const int new_stack_depth = new_entry_enode->get_stack_depth ();
+
+ /* Compare the stores of the two enodes. */
+ const region_model &new_model
+ = *new_entry_enode->get_state ().m_region_model;
+ const region_model &prev_model
+ = *prev_entry_enode->get_state ().m_region_model;
+ const store &new_store = *new_model.get_store ();
+
+ for (auto kv : new_store)
+ {
+ const region *base_reg = kv.first;
+
+ /* Get the value within the new frame. */
+ const svalue *new_sval
+ = new_model.get_store_value (base_reg, NULL);
+
+ /* If the value is UNKNOWN (e.g. due to hitting complexity limits)
+ assume that it differs from the previous value. */
+ if (new_sval->get_kind () == SK_UNKNOWN)
+ return true;
+
+ /* Get the equivalent value within the old enode. */
+ const svalue *prev_sval;
+
+ if (const frame_region *enclosing_frame
+ = base_reg->maybe_get_frame_region ())
+ {
+ /* We have a binding within a frame in the new entry enode. */
+
+ /* Ignore bindings within frames below the new entry node. */
+ if (enclosing_frame->get_stack_depth () < new_stack_depth)
+ continue;
+
+ /* We have a binding within the frame of the new entry node,
+ presumably a parameter. */
+
+ /* Get the value within the equivalent frame of
+ the old entrypoint; typically will be the initial_svalue
+ of the parameter. */
+ const frame_region *equiv_prev_frame
+ = prev_model.get_current_frame ();
+ const region *equiv_prev_base_reg
+ = remap_enclosing_frame (base_reg,
+ enclosing_frame,
+ equiv_prev_frame,
+ new_model.get_manager ());
+ prev_sval = prev_model.get_store_value (equiv_prev_base_reg, NULL);
+ }
+ else
+ prev_sval = prev_model.get_store_value (base_reg, NULL);
+
+ /* If the prev_sval is UNKNOWN (e.g. due to hitting complexity limits)
+ assume that it will differ from any new value. */
+ if (prev_sval->get_kind () == SK_UNKNOWN)
+ return true;
+
+ if (new_sval != prev_sval)
+ return true;
+ }
+
+ /* No significant differences found. */
+ return false;
+}
+
+/* Implementation of -Wanalyzer-infinite-recursion.
+
+ Called when adding ENODE to the graph, after adding its first in-edge.
+
+ For function entrypoints, see if recursion has occurred, and, if so,
+ check if the state of memory changed between the recursion levels,
+ which would suggest some kind of decreasing variant that leads to
+ termination.
+
+ For recursive calls where the state of memory is effectively unchanged
+ between recursion levels, warn with -Wanalyzer-infinite-recursion. */
+
+void
+exploded_graph::detect_infinite_recursion (exploded_node *enode)
+{
+ if (!is_entrypoint_p (enode))
+ return;
+ function *top_of_stack_fun = enode->get_function ();
+ gcc_assert (top_of_stack_fun);
+
+ /* ....where a call to that function is already in the call string. */
+ const call_string &call_string = enode->get_point ().get_call_string ();
+
+ if (call_string.count_occurrences_of_function (top_of_stack_fun) < 2)
+ return;
+
+ tree fndecl = top_of_stack_fun->decl;
+
+ log_scope s (get_logger (),
+ "checking for infinite recursion",
+ "considering recursion at EN: %i entering %qE",
+ enode->m_index, fndecl);
+
+ /* Find enode that's the entrypoint for the previous frame for fndecl
+ in the recursion. */
+ exploded_node *prev_entry_enode
+ = find_previous_entry_to (top_of_stack_fun, enode);
+ gcc_assert (prev_entry_enode);
+ if (get_logger ())
+ get_logger ()->log ("previous entrypoint to %qE is EN: %i",
+ fndecl, prev_entry_enode->m_index);
+
+ /* Look for changes to the state of memory between the recursion levels. */
+ if (sufficiently_different_p (enode, prev_entry_enode, get_logger ()))
+ return;
+
+ /* Otherwise, the state of memory is effectively the same between the two
+ recursion levels; warn. */
+
+ const supernode *caller_snode = call_string.get_top_of_stack ().m_caller;
+ const supernode *snode = enode->get_supernode ();
+ gcc_assert (caller_snode->m_returning_call);
+ get_diagnostic_manager ().add_diagnostic
+ (enode, snode, caller_snode->m_returning_call, NULL,
+ make_unique<infinite_recursion_diagnostic> (prev_entry_enode,
+ enode,
+ fndecl));
+}
diff --git a/gcc/analyzer/kf-analyzer.cc b/gcc/analyzer/kf-analyzer.cc
new file mode 100644
index 0000000..b233418
--- /dev/null
+++ b/gcc/analyzer/kf-analyzer.cc
@@ -0,0 +1,386 @@
+/* Handling for the various __analyzer_* known functions.
+ Copyright (C) 2020-2022 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#define INCLUDE_MEMORY
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "function.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "diagnostic-core.h"
+#include "analyzer/analyzer.h"
+#include "analyzer/analyzer-logging.h"
+#include "diagnostic.h"
+#include "tree-diagnostic.h" /* for default_tree_printer. */
+#include "analyzer/region-model.h"
+#include "analyzer/pending-diagnostic.h"
+#include "analyzer/call-details.h"
+#include "make-unique.h"
+
+#if ENABLE_ANALYZER
+
+namespace ana {
+
+/* Handle calls to "__analyzer_break" by triggering a breakpoint within
+ the analyzer. */
+
+class kf_analyzer_break : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 0;
+ }
+ void impl_call_pre (const call_details &) const final override
+ {
+ /* TODO: is there a good cross-platform way to do this? */
+ raise (SIGINT);
+ }
+};
+
+/* Handler for calls to "__analyzer_describe".
+
+ Emit a warning describing the 2nd argument (which can be of any
+ type), at the given verbosity level. This is for use when
+ debugging, and may be of use in DejaGnu tests. */
+
+class kf_analyzer_describe : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 2;
+ }
+ void impl_call_pre (const call_details &cd) const final override
+ {
+ if (!cd.get_ctxt ())
+ return;
+ tree t_verbosity = cd.get_arg_tree (0);
+ const svalue *sval = cd.get_arg_svalue (1);
+ bool simple = zerop (t_verbosity);
+ label_text desc = sval->get_desc (simple);
+ warning_at (cd.get_location (), 0, "svalue: %qs", desc.get ());
+ }
+};
+
+/* Handler for calls to "__analyzer_dump_capacity".
+
+ Emit a warning describing the capacity of the base region of
+ the region pointed to by the 1st argument.
+ This is for use when debugging, and may be of use in DejaGnu tests. */
+
+class kf_analyzer_dump_capacity : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 1
+ && cd.arg_is_pointer_p (0));
+ }
+
+ void impl_call_pre (const call_details &cd) const final override
+ {
+ region_model_context *ctxt = cd.get_ctxt ();
+ if (!ctxt)
+ return;
+ region_model *model = cd.get_model ();
+ tree t_ptr = cd.get_arg_tree (0);
+ const svalue *sval_ptr = model->get_rvalue (t_ptr, ctxt);
+ const region *reg = model->deref_rvalue (sval_ptr, t_ptr, ctxt);
+ const region *base_reg = reg->get_base_region ();
+ const svalue *capacity = model->get_capacity (base_reg);
+ label_text desc = capacity->get_desc (true);
+ warning_at (cd.get_call_stmt ()->location, 0,
+ "capacity: %qs", desc.get ());
+ }
+};
+
+/* Compare D1 and D2 using their names, and then IDs to order them. */
+
+static int
+cmp_decls (tree d1, tree d2)
+{
+ gcc_assert (DECL_P (d1));
+ gcc_assert (DECL_P (d2));
+ if (DECL_NAME (d1) && DECL_NAME (d2))
+ if (int cmp = strcmp (IDENTIFIER_POINTER (DECL_NAME (d1)),
+ IDENTIFIER_POINTER (DECL_NAME (d2))))
+ return cmp;
+ return (int)DECL_UID (d1) - (int)DECL_UID (d2);
+}
+
+/* Comparator for use by vec<tree>::qsort,
+ using their names, and then IDs to order them. */
+
+static int
+cmp_decls_ptr_ptr (const void *p1, const void *p2)
+{
+ tree const *d1 = (tree const *)p1;
+ tree const *d2 = (tree const *)p2;
+
+ return cmp_decls (*d1, *d2);
+}
+
+/* Handler for calls to "__analyzer_dump_escaped".
+
+ Emit a warning giving the number of decls that have escaped, followed
+ by a comma-separated list of their names, in alphabetical order.
+
+ This is for use when debugging, and may be of use in DejaGnu tests. */
+
+class kf_analyzer_dump_escaped : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 0;
+ }
+ void impl_call_pre (const call_details &cd) const final override
+ {
+ region_model_context *ctxt = cd.get_ctxt ();
+ if (!ctxt)
+ return;
+ region_model *model = cd.get_model ();
+
+ auto_vec<tree> escaped_decls;
+ for (auto iter : *model->get_store ())
+ {
+ const binding_cluster *c = iter.second;
+ if (!c->escaped_p ())
+ continue;
+ if (tree decl = c->get_base_region ()->maybe_get_decl ())
+ escaped_decls.safe_push (decl);
+ }
+
+ /* Sort them into deterministic order; alphabetical is
+ probably most user-friendly. */
+ escaped_decls.qsort (cmp_decls_ptr_ptr);
+
+ pretty_printer pp;
+ pp_format_decoder (&pp) = default_tree_printer;
+ pp_show_color (&pp) = pp_show_color (global_dc->printer);
+ bool first = true;
+ for (auto iter : escaped_decls)
+ {
+ if (first)
+ first = false;
+ else
+ pp_string (&pp, ", ");
+ pp_printf (&pp, "%qD", iter);
+ }
+ /* Print the number to make it easier to write DejaGnu tests for
+ the "nothing has escaped" case. */
+ warning_at (cd.get_location (), 0, "escaped: %i: %s",
+ escaped_decls.length (),
+ pp_formatted_text (&pp));
+ }
+};
+
+/* Placeholder handler for calls to "__analyzer_dump_exploded_nodes".
+ This is a no-op; the real implementation happens when the
+ exploded_graph is postprocessed. */
+
+class kf_analyzer_dump_exploded_nodes : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 1;
+ }
+};
+
+/* Handler for calls to "__analyzer_dump_named_constant".
+
+ Look up the given name, and emit a warning describing the
+ state of the corresponding stashed value.
+
+ This is for use when debugging, and for DejaGnu tests. */
+
+class kf_analyzer_dump_named_constant : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 1;
+ }
+ void impl_call_pre (const call_details &cd) const final override
+ {
+ region_model_context *ctxt = cd.get_ctxt ();
+ if (!ctxt)
+ return;
+
+ const char *name = cd.get_arg_string_literal (0);
+ if (!name)
+ {
+ error_at (cd.get_location (), "cannot determine name");
+ return;
+ }
+ tree value = get_stashed_constant_by_name (name);
+ if (value)
+ warning_at (cd.get_location (), 0, "named constant %qs has value %qE",
+ name, value);
+ else
+ warning_at (cd.get_location (), 0, "named constant %qs has unknown value",
+ name);
+ }
+};
+
+/* A pending_diagnostic subclass for implementing "__analyzer_dump_path". */
+
+class dump_path_diagnostic
+ : public pending_diagnostic_subclass<dump_path_diagnostic>
+{
+public:
+ int get_controlling_option () const final override
+ {
+ return 0;
+ }
+
+ bool emit (rich_location *richloc) final override
+ {
+ inform (richloc, "path");
+ return true;
+ }
+
+ const char *get_kind () const final override
+ {
+ return "dump_path_diagnostic";
+ }
+
+ bool operator== (const dump_path_diagnostic &) const
+ {
+ return true;
+ }
+};
+
+/* Handle calls to "__analyzer_dump_path" by queuing a diagnostic at this
+ exploded_node. */
+
+class kf_analyzer_dump_path : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 0;
+ }
+ void impl_call_pre (const call_details &cd) const final override
+ {
+ region_model_context *ctxt = cd.get_ctxt ();
+ if (!ctxt)
+ return;
+ ctxt->warn (make_unique<dump_path_diagnostic> ());
+ }
+};
+
+/* Handle calls to "__analyzer_dump_region_model" by dumping
+ the region model's state to stderr. */
+
+class kf_analyzer_dump_region_model : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 0;
+ }
+ void impl_call_pre (const call_details &cd) const final override
+ {
+ region_model_context *ctxt = cd.get_ctxt ();
+ if (!ctxt)
+ return;
+ region_model *model = cd.get_model ();
+ model->dump (false);
+ }
+};
+
+/* Handle a call to "__analyzer_eval" by evaluating the input
+ and dumping as a dummy warning, so that test cases can use
+ dg-warning to validate the result (and so unexpected warnings will
+ lead to DejaGnu failures).
+ Broken out as a subroutine to make it easier to put a breakpoint on it
+ - though typically this doesn't help, as we have an SSA name as the arg,
+ and what's more interesting is usually the def stmt for that name. */
+
+class kf_analyzer_eval : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 1;
+ }
+ void impl_call_pre (const call_details &cd) const final override
+ {
+ region_model_context *ctxt = cd.get_ctxt ();
+ if (!ctxt)
+ return;
+ region_model *model = cd.get_model ();
+
+ tree t_arg = cd.get_arg_tree (0);
+ tristate t = model->eval_condition (t_arg, NE_EXPR, integer_zero_node,
+ ctxt);
+ warning_at (cd.get_location (), 0, "%s", t.as_string ());
+ }
+};
+
+/* Handler for "__analyzer_get_unknown_ptr". */
+
+class kf_analyzer_get_unknown_ptr : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 0;
+ }
+ void impl_call_pre (const call_details &cd) const final override
+ {
+ region_model_manager *mgr = cd.get_manager ();
+ const svalue *ptr_sval
+ = mgr->get_or_create_unknown_svalue (cd.get_lhs_type ());
+ cd.maybe_set_lhs (ptr_sval);
+ }
+};
+
+/* Populate KFM with instances of known functions used for debugging the
+ analyzer and for writing DejaGnu tests, all with a "__analyzer_" prefix. */
+
+void
+register_known_analyzer_functions (known_function_manager &kfm)
+{
+ kfm.add ("__analyzer_break", make_unique<kf_analyzer_break> ());
+ kfm.add ("__analyzer_describe", make_unique<kf_analyzer_describe> ());
+ kfm.add ("__analyzer_dump_capacity",
+ make_unique<kf_analyzer_dump_capacity> ());
+ kfm.add ("__analyzer_dump_escaped", make_unique<kf_analyzer_dump_escaped> ());
+ kfm.add ("__analyzer_dump_exploded_nodes",
+ make_unique<kf_analyzer_dump_exploded_nodes> ());
+ kfm.add ("__analyzer_dump_named_constant",
+ make_unique<kf_analyzer_dump_named_constant> ());
+ kfm.add ("__analyzer_dump_path", make_unique<kf_analyzer_dump_path> ());
+ kfm.add ("__analyzer_dump_region_model",
+ make_unique<kf_analyzer_dump_region_model> ());
+ kfm.add ("__analyzer_eval", make_unique<kf_analyzer_eval> ());
+ kfm.add ("__analyzer_get_unknown_ptr",
+ make_unique<kf_analyzer_get_unknown_ptr> ());
+}
+
+} // namespace ana
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/kf-lang-cp.cc b/gcc/analyzer/kf-lang-cp.cc
new file mode 100644
index 0000000..9dca366
--- /dev/null
+++ b/gcc/analyzer/kf-lang-cp.cc
@@ -0,0 +1,111 @@
+/* Handling for the known behavior of various functions specific to C++.
+ Copyright (C) 2020-2022 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#define INCLUDE_MEMORY
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "function.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "analyzer/analyzer.h"
+#include "analyzer/analyzer-logging.h"
+#include "diagnostic.h"
+#include "analyzer/region-model.h"
+#include "analyzer/call-details.h"
+#include "make-unique.h"
+
+#if ENABLE_ANALYZER
+
+namespace ana {
+
+/* Implementations of specific functions. */
+
+/* Handler for "operator new" and "operator new []". */
+
+class kf_operator_new : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 1;
+ }
+
+ void impl_call_pre (const call_details &cd) const final override
+ {
+ region_model *model = cd.get_model ();
+ region_model_manager *mgr = cd.get_manager ();
+ const svalue *size_sval = cd.get_arg_svalue (0);
+ const region *new_reg
+ = model->get_or_create_region_for_heap_alloc (size_sval, cd.get_ctxt ());
+ if (cd.get_lhs_type ())
+ {
+ const svalue *ptr_sval
+ = mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
+ cd.maybe_set_lhs (ptr_sval);
+ }
+ }
+};
+
+/* Handler for "operator delete", both the sized and unsized variants
+ (2 arguments and 1 argument respectively), and for "operator delete []" */
+
+class kf_operator_delete : public known_function
+{
+public:
+ kf_operator_delete (unsigned num_args) : m_num_args (num_args) {}
+
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == m_num_args;
+ }
+
+ void impl_call_post (const call_details &cd) const final override
+ {
+ region_model *model = cd.get_model ();
+ const svalue *ptr_sval = cd.get_arg_svalue (0);
+ if (const region *freed_reg = ptr_sval->maybe_get_region ())
+ {
+ /* If the ptr points to an underlying heap region, delete it,
+ poisoning pointers. */
+ model->unbind_region_and_descendents (freed_reg, POISON_KIND_FREED);
+ }
+ }
+
+private:
+ unsigned m_num_args;
+};
+
+/* Populate KFM with instances of known functions relating to C++. */
+
+void
+register_known_functions_lang_cp (known_function_manager &kfm)
+{
+ kfm.add ("operator new", make_unique<kf_operator_new> ());
+ kfm.add ("operator new []", make_unique<kf_operator_new> ());
+ kfm.add ("operator delete", make_unique<kf_operator_delete> (1));
+ kfm.add ("operator delete", make_unique<kf_operator_delete> (2));
+ kfm.add ("operator delete []", make_unique<kf_operator_delete> (1));
+}
+
+} // namespace ana
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc
new file mode 100644
index 0000000..ff2f1b1
--- /dev/null
+++ b/gcc/analyzer/kf.cc
@@ -0,0 +1,991 @@
+/* Handling for the known behavior of various specific functions.
+ Copyright (C) 2020-2022 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#define INCLUDE_MEMORY
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "function.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "diagnostic-core.h"
+#include "diagnostic-metadata.h"
+#include "analyzer/analyzer.h"
+#include "analyzer/analyzer-logging.h"
+#include "diagnostic.h"
+#include "analyzer/region-model.h"
+#include "analyzer/call-details.h"
+#include "analyzer/call-info.h"
+#include "make-unique.h"
+
+#if ENABLE_ANALYZER
+
+namespace ana {
+
+/* Implementations of specific functions. */
+
+/* Handler for "alloca". */
+
+class kf_alloca : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 1;
+ }
+ void impl_call_pre (const call_details &cd) const final override;
+};
+
+void
+kf_alloca::impl_call_pre (const call_details &cd) const
+{
+ const svalue *size_sval = cd.get_arg_svalue (0);
+
+ region_model *model = cd.get_model ();
+ region_model_manager *mgr = cd.get_manager ();
+
+ const region *new_reg
+ = model->create_region_for_alloca (size_sval, cd.get_ctxt ());
+ const svalue *ptr_sval
+ = mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
+ cd.maybe_set_lhs (ptr_sval);
+}
+
+/* Handler for "__builtin_expect" etc. */
+
+class kf_expect : public internal_known_function
+{
+public:
+ void impl_call_pre (const call_details &cd) const final override
+ {
+ /* __builtin_expect's return value is its initial argument. */
+ const svalue *sval = cd.get_arg_svalue (0);
+ cd.maybe_set_lhs (sval);
+ }
+};
+
+/* Handler for "calloc". */
+
+class kf_calloc : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 2
+ && cd.arg_is_size_p (0)
+ && cd.arg_is_size_p (1));
+ }
+ void impl_call_pre (const call_details &cd) const final override;
+};
+
+void
+kf_calloc::impl_call_pre (const call_details &cd) const
+{
+ region_model *model = cd.get_model ();
+ region_model_manager *mgr = cd.get_manager ();
+ const svalue *nmemb_sval = cd.get_arg_svalue (0);
+ const svalue *size_sval = cd.get_arg_svalue (1);
+ /* TODO: check for overflow here? */
+ const svalue *prod_sval
+ = mgr->get_or_create_binop (size_type_node, MULT_EXPR,
+ nmemb_sval, size_sval);
+ const region *new_reg
+ = model->get_or_create_region_for_heap_alloc (prod_sval, cd.get_ctxt ());
+ const region *sized_reg
+ = mgr->get_sized_region (new_reg, NULL_TREE, prod_sval);
+ model->zero_fill_region (sized_reg);
+ if (cd.get_lhs_type ())
+ {
+ const svalue *ptr_sval
+ = mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
+ cd.maybe_set_lhs (ptr_sval);
+ }
+}
+
+/* Handler for glibc's "__errno_location". */
+
+class kf_errno_location : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 0;
+ }
+
+ void impl_call_pre (const call_details &cd) const final override
+ {
+ if (cd.get_lhs_region ())
+ {
+ region_model_manager *mgr = cd.get_manager ();
+ const region *errno_reg = mgr->get_errno_region ();
+ const svalue *errno_ptr = mgr->get_ptr_svalue (cd.get_lhs_type (),
+ errno_reg);
+ cd.maybe_set_lhs (errno_ptr);
+ }
+ }
+};
+
+/* Handler for "error" and "error_at_line" from GNU's non-standard <error.h>.
+ MIN_ARGS identifies the minimum number of expected arguments
+ to be consistent with such a call (3 and 5 respectively). */
+
+class kf_error : public known_function
+{
+public:
+ kf_error (unsigned min_args) : m_min_args (min_args) {}
+
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () >= m_min_args
+ && cd.get_arg_type (0) == integer_type_node);
+ }
+
+ void impl_call_pre (const call_details &cd) const final override;
+
+private:
+ unsigned m_min_args;
+};
+
+void
+kf_error::impl_call_pre (const call_details &cd) const
+{
+ /* The process exits if status != 0, so it only continues
+ for the case where status == 0.
+ Add that constraint, or terminate this analysis path. */
+ tree status = cd.get_arg_tree (0);
+ region_model_context *ctxt = cd.get_ctxt ();
+ region_model *model = cd.get_model ();
+ if (!model->add_constraint (status, EQ_EXPR, integer_zero_node, ctxt))
+ if (ctxt)
+ ctxt->terminate_path ();
+}
+
+/* Handler for "free", after sm-handling.
+
+ If the ptr points to an underlying heap region, delete the region,
+ poisoning pointers to it and regions within it.
+
+ We delay this until after sm-state has been updated so that the
+ sm-handling can transition all of the various casts of the pointer
+ to a "freed" state *before* we delete the related region here.
+
+ This has to be done here so that the sm-handling can use the fact
+ that they point to the same region to establish that they are equal
+ (in region_model::eval_condition), and thus transition
+ all pointers to the region to the "freed" state together, regardless
+ of casts. */
+
+class kf_free : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 0 && cd.arg_is_pointer_p (0));
+ }
+ void impl_call_post (const call_details &cd) const final override;
+};
+
+void
+kf_free::impl_call_post (const call_details &cd) const
+{
+ const svalue *ptr_sval = cd.get_arg_svalue (0);
+ if (const region *freed_reg = ptr_sval->maybe_get_region ())
+ {
+ /* If the ptr points to an underlying heap region, delete it,
+ poisoning pointers. */
+ region_model *model = cd.get_model ();
+ model->unbind_region_and_descendents (freed_reg, POISON_KIND_FREED);
+ model->unset_dynamic_extents (freed_reg);
+ }
+}
+
+/* Handle the on_call_pre part of "malloc". */
+
+class kf_malloc : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 1
+ && cd.arg_is_size_p (0));
+ }
+ void impl_call_pre (const call_details &cd) const final override;
+};
+
+void
+kf_malloc::impl_call_pre (const call_details &cd) const
+{
+ region_model *model = cd.get_model ();
+ region_model_manager *mgr = cd.get_manager ();
+ const svalue *size_sval = cd.get_arg_svalue (0);
+ const region *new_reg
+ = model->get_or_create_region_for_heap_alloc (size_sval, cd.get_ctxt ());
+ if (cd.get_lhs_type ())
+ {
+ const svalue *ptr_sval
+ = mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
+ cd.maybe_set_lhs (ptr_sval);
+ }
+}
+
+/* Handler for "memcpy" and "__builtin_memcpy",
+ "memmove", and "__builtin_memmove". */
+/* TODO: complain about overlapping src and dest for the memcpy
+ variants. */
+
+class kf_memcpy_memmove : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 3
+ && cd.arg_is_pointer_p (0)
+ && cd.arg_is_pointer_p (1)
+ && cd.arg_is_size_p (2));
+ }
+ void impl_call_pre (const call_details &cd) const final override;
+};
+
+void
+kf_memcpy_memmove::impl_call_pre (const call_details &cd) const
+{
+ const svalue *dest_ptr_sval = cd.get_arg_svalue (0);
+ const svalue *src_ptr_sval = cd.get_arg_svalue (1);
+ const svalue *num_bytes_sval = cd.get_arg_svalue (2);
+
+ region_model *model = cd.get_model ();
+ region_model_manager *mgr = cd.get_manager ();
+
+ const region *dest_reg
+ = model->deref_rvalue (dest_ptr_sval, cd.get_arg_tree (0), cd.get_ctxt ());
+ const region *src_reg
+ = model->deref_rvalue (src_ptr_sval, cd.get_arg_tree (1), cd.get_ctxt ());
+
+ cd.maybe_set_lhs (dest_ptr_sval);
+
+ const region *sized_src_reg
+ = mgr->get_sized_region (src_reg, NULL_TREE, num_bytes_sval);
+ const region *sized_dest_reg
+ = mgr->get_sized_region (dest_reg, NULL_TREE, num_bytes_sval);
+ const svalue *src_contents_sval
+ = model->get_store_value (sized_src_reg, cd.get_ctxt ());
+ model->check_for_poison (src_contents_sval, cd.get_arg_tree (1),
+ cd.get_ctxt ());
+ model->set_value (sized_dest_reg, src_contents_sval, cd.get_ctxt ());
+}
+
+/* Handler for "memset" and "__builtin_memset". */
+
+class kf_memset : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 3 && cd.arg_is_pointer_p (0));
+ }
+
+ void impl_call_pre (const call_details &cd) const final override;
+};
+
+void
+kf_memset::impl_call_pre (const call_details &cd) const
+{
+ const svalue *dest_sval = cd.get_arg_svalue (0);
+ const svalue *fill_value_sval = cd.get_arg_svalue (1);
+ const svalue *num_bytes_sval = cd.get_arg_svalue (2);
+
+ region_model *model = cd.get_model ();
+ region_model_manager *mgr = cd.get_manager ();
+
+ const region *dest_reg
+ = model->deref_rvalue (dest_sval, cd.get_arg_tree (0), cd.get_ctxt ());
+
+ const svalue *fill_value_u8
+ = mgr->get_or_create_cast (unsigned_char_type_node, fill_value_sval);
+
+ const region *sized_dest_reg = mgr->get_sized_region (dest_reg,
+ NULL_TREE,
+ num_bytes_sval);
+ model->check_region_for_write (sized_dest_reg, cd.get_ctxt ());
+ model->fill_region (sized_dest_reg, fill_value_u8);
+}
+
+/* A subclass of pending_diagnostic for complaining about 'putenv'
+ called on an auto var. */
+
+class putenv_of_auto_var
+: public pending_diagnostic_subclass<putenv_of_auto_var>
+{
+public:
+ putenv_of_auto_var (tree fndecl, const region *reg)
+ : m_fndecl (fndecl), m_reg (reg),
+ m_var_decl (reg->get_base_region ()->maybe_get_decl ())
+ {
+ }
+
+ const char *get_kind () const final override
+ {
+ return "putenv_of_auto_var";
+ }
+
+ bool operator== (const putenv_of_auto_var &other) const
+ {
+ return (m_fndecl == other.m_fndecl
+ && m_reg == other.m_reg
+ && same_tree_p (m_var_decl, other.m_var_decl));
+ }
+
+ int get_controlling_option () const final override
+ {
+ return OPT_Wanalyzer_putenv_of_auto_var;
+ }
+
+ bool emit (rich_location *rich_loc) final override
+ {
+ auto_diagnostic_group d;
+ diagnostic_metadata m;
+
+ /* SEI CERT C Coding Standard: "POS34-C. Do not call putenv() with a
+ pointer to an automatic variable as the argument". */
+ diagnostic_metadata::precanned_rule
+ rule ("POS34-C", "https://wiki.sei.cmu.edu/confluence/x/6NYxBQ");
+ m.add_rule (rule);
+
+ bool warned;
+ if (m_var_decl)
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "%qE on a pointer to automatic variable %qE",
+ m_fndecl, m_var_decl);
+ else
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
+ "%qE on a pointer to an on-stack buffer",
+ m_fndecl);
+ if (warned)
+ {
+ if (m_var_decl)
+ inform (DECL_SOURCE_LOCATION (m_var_decl),
+ "%qE declared on stack here", m_var_decl);
+ inform (rich_loc->get_loc (), "perhaps use %qs rather than %qE",
+ "setenv", m_fndecl);
+ }
+
+ return warned;
+ }
+
+ label_text describe_final_event (const evdesc::final_event &ev) final override
+ {
+ if (m_var_decl)
+ return ev.formatted_print ("%qE on a pointer to automatic variable %qE",
+ m_fndecl, m_var_decl);
+ else
+ return ev.formatted_print ("%qE on a pointer to an on-stack buffer",
+ m_fndecl);
+ }
+
+ void mark_interesting_stuff (interesting_t *interest) final override
+ {
+ if (!m_var_decl)
+ interest->add_region_creation (m_reg->get_base_region ());
+ }
+
+private:
+ tree m_fndecl; // non-NULL
+ const region *m_reg; // non-NULL
+ tree m_var_decl; // could be NULL
+};
+
+/* Handler for calls to "putenv".
+
+ In theory we could try to model the state of the environment variables
+ for the process; for now we merely complain about putenv of regions
+ on the stack. */
+
+class kf_putenv : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 1 && cd.arg_is_pointer_p (0));
+ }
+
+ void impl_call_pre (const call_details &cd) const final override
+ {
+ tree fndecl = cd.get_fndecl_for_call ();
+ gcc_assert (fndecl);
+ region_model_context *ctxt = cd.get_ctxt ();
+ region_model *model = cd.get_model ();
+ const svalue *ptr_sval = cd.get_arg_svalue (0);
+ const region *reg
+ = model->deref_rvalue (ptr_sval, cd.get_arg_tree (0), ctxt);
+ model->get_store ()->mark_as_escaped (reg);
+ enum memory_space mem_space = reg->get_memory_space ();
+ switch (mem_space)
+ {
+ default:
+ gcc_unreachable ();
+ case MEMSPACE_UNKNOWN:
+ case MEMSPACE_CODE:
+ case MEMSPACE_GLOBALS:
+ case MEMSPACE_HEAP:
+ case MEMSPACE_READONLY_DATA:
+ break;
+ case MEMSPACE_STACK:
+ if (ctxt)
+ ctxt->warn (make_unique<putenv_of_auto_var> (fndecl, reg));
+ break;
+ }
+ }
+};
+
+/* Handler for "realloc":
+
+ void *realloc(void *ptr, size_t size);
+
+ realloc(3) is awkward, since it has various different outcomes
+ that are best modelled as separate exploded nodes/edges.
+
+ We first check for sm-state, in
+ malloc_state_machine::on_realloc_call, so that we
+ can complain about issues such as realloc of a non-heap
+ pointer, and terminate the path for such cases (and issue
+ the complaints at the call's exploded node).
+
+ Assuming that these checks pass, we split the path here into
+ three special cases (and terminate the "standard" path):
+ (A) failure, returning NULL
+ (B) success, growing the buffer in-place without moving it
+ (C) success, allocating a new buffer, copying the content
+ of the old buffer to it, and freeing the old buffer.
+
+ Each of these has a custom_edge_info subclass, which updates
+ the region_model and sm-state of the destination state. */
+
+class kf_realloc : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 2
+ && cd.arg_is_pointer_p (0)
+ && cd.arg_is_size_p (1));
+ }
+ void impl_call_post (const call_details &cd) const final override;
+};
+
+void
+kf_realloc::impl_call_post (const call_details &cd) const
+{
+ /* Three custom subclasses of custom_edge_info, for handling the various
+ outcomes of "realloc". */
+
+ /* Concrete custom_edge_info: a realloc call that fails, returning NULL. */
+ class failure : public failed_call_info
+ {
+ public:
+ failure (const call_details &cd)
+ : failed_call_info (cd)
+ {
+ }
+
+ bool update_model (region_model *model,
+ const exploded_edge *,
+ region_model_context *ctxt) const final override
+ {
+ /* Return NULL; everything else is unchanged. */
+ const call_details cd (get_call_details (model, ctxt));
+ region_model_manager *mgr = cd.get_manager ();
+ if (cd.get_lhs_type ())
+ {
+ const svalue *zero
+ = mgr->get_or_create_int_cst (cd.get_lhs_type (), 0);
+ model->set_value (cd.get_lhs_region (),
+ zero,
+ cd.get_ctxt ());
+ }
+ return true;
+ }
+ };
+
+ /* Concrete custom_edge_info: a realloc call that succeeds, growing
+ the existing buffer without moving it. */
+ class success_no_move : public call_info
+ {
+ public:
+ success_no_move (const call_details &cd)
+ : call_info (cd)
+ {
+ }
+
+ label_text get_desc (bool can_colorize) const final override
+ {
+ return make_label_text (can_colorize,
+ "when %qE succeeds, without moving buffer",
+ get_fndecl ());
+ }
+
+ bool update_model (region_model *model,
+ const exploded_edge *,
+ region_model_context *ctxt) const final override
+ {
+ /* Update size of buffer and return the ptr unchanged. */
+ const call_details cd (get_call_details (model, ctxt));
+ region_model_manager *mgr = cd.get_manager ();
+ const svalue *ptr_sval = cd.get_arg_svalue (0);
+ const svalue *size_sval = cd.get_arg_svalue (1);
+
+ /* We can only grow in place with a non-NULL pointer. */
+ {
+ const svalue *null_ptr
+ = mgr->get_or_create_int_cst (ptr_sval->get_type (), 0);
+ if (!model->add_constraint (ptr_sval, NE_EXPR, null_ptr,
+ cd.get_ctxt ()))
+ return false;
+ }
+
+ if (const region *buffer_reg = model->deref_rvalue (ptr_sval, NULL_TREE,
+ ctxt))
+ if (compat_types_p (size_sval->get_type (), size_type_node))
+ model->set_dynamic_extents (buffer_reg, size_sval, ctxt);
+ if (cd.get_lhs_region ())
+ {
+ model->set_value (cd.get_lhs_region (), ptr_sval, cd.get_ctxt ());
+ const svalue *zero
+ = mgr->get_or_create_int_cst (cd.get_lhs_type (), 0);
+ return model->add_constraint (ptr_sval, NE_EXPR, zero, ctxt);
+ }
+ else
+ return true;
+ }
+ };
+
+ /* Concrete custom_edge_info: a realloc call that succeeds, freeing
+ the existing buffer and moving the content to a freshly allocated
+ buffer. */
+ class success_with_move : public call_info
+ {
+ public:
+ success_with_move (const call_details &cd)
+ : call_info (cd)
+ {
+ }
+
+ label_text get_desc (bool can_colorize) const final override
+ {
+ return make_label_text (can_colorize,
+ "when %qE succeeds, moving buffer",
+ get_fndecl ());
+ }
+ bool update_model (region_model *model,
+ const exploded_edge *,
+ region_model_context *ctxt) const final override
+ {
+ const call_details cd (get_call_details (model, ctxt));
+ region_model_manager *mgr = cd.get_manager ();
+ const svalue *old_ptr_sval = cd.get_arg_svalue (0);
+ const svalue *new_size_sval = cd.get_arg_svalue (1);
+
+ /* Create the new region. */
+ const region *new_reg
+ = model->get_or_create_region_for_heap_alloc (new_size_sval, ctxt);
+ const svalue *new_ptr_sval
+ = mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
+ if (!model->add_constraint (new_ptr_sval, NE_EXPR, old_ptr_sval,
+ cd.get_ctxt ()))
+ return false;
+
+ if (cd.get_lhs_type ())
+ cd.maybe_set_lhs (new_ptr_sval);
+
+ if (const region *freed_reg = model->deref_rvalue (old_ptr_sval,
+ NULL_TREE, ctxt))
+ {
+ /* Copy the data. */
+ const svalue *old_size_sval = model->get_dynamic_extents (freed_reg);
+ if (old_size_sval)
+ {
+ const svalue *copied_size_sval
+ = get_copied_size (model, old_size_sval, new_size_sval);
+ const region *copied_old_reg
+ = mgr->get_sized_region (freed_reg, NULL, copied_size_sval);
+ const svalue *buffer_content_sval
+ = model->get_store_value (copied_old_reg, cd.get_ctxt ());
+ const region *copied_new_reg
+ = mgr->get_sized_region (new_reg, NULL, copied_size_sval);
+ model->set_value (copied_new_reg, buffer_content_sval,
+ cd.get_ctxt ());
+ }
+ else
+ {
+ /* We don't know how big the old region was;
+ mark the new region as having been touched to avoid uninit
+ issues. */
+ model->mark_region_as_unknown (new_reg, cd.get_uncertainty ());
+ }
+
+ /* Free the old region, so that pointers to the old buffer become
+ invalid. */
+
+ /* If the ptr points to an underlying heap region, delete it,
+ poisoning pointers. */
+ model->unbind_region_and_descendents (freed_reg, POISON_KIND_FREED);
+ model->unset_dynamic_extents (freed_reg);
+ }
+
+ /* Update the sm-state: mark the old_ptr_sval as "freed",
+ and the new_ptr_sval as "nonnull". */
+ model->on_realloc_with_move (cd, old_ptr_sval, new_ptr_sval);
+
+ if (cd.get_lhs_type ())
+ {
+ const svalue *zero
+ = mgr->get_or_create_int_cst (cd.get_lhs_type (), 0);
+ return model->add_constraint (new_ptr_sval, NE_EXPR, zero,
+ cd.get_ctxt ());
+ }
+ else
+ return true;
+ }
+
+ private:
+ /* Return the lesser of OLD_SIZE_SVAL and NEW_SIZE_SVAL.
+ If unknown, OLD_SIZE_SVAL is returned. */
+ const svalue *get_copied_size (region_model *model,
+ const svalue *old_size_sval,
+ const svalue *new_size_sval) const
+ {
+ tristate res
+ = model->eval_condition (old_size_sval, GT_EXPR, new_size_sval);
+ switch (res.get_value ())
+ {
+ case tristate::TS_TRUE:
+ return new_size_sval;
+ case tristate::TS_FALSE:
+ case tristate::TS_UNKNOWN:
+ return old_size_sval;
+ default:
+ gcc_unreachable ();
+ }
+ }
+ };
+
+ /* Body of kf_realloc::impl_call_post. */
+
+ if (cd.get_ctxt ())
+ {
+ cd.get_ctxt ()->bifurcate (make_unique<failure> (cd));
+ cd.get_ctxt ()->bifurcate (make_unique<success_no_move> (cd));
+ cd.get_ctxt ()->bifurcate (make_unique<success_with_move> (cd));
+ cd.get_ctxt ()->terminate_path ();
+ }
+}
+
+/* Handler for "strchr" and "__builtin_strchr". */
+
+class kf_strchr : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 2 && cd.arg_is_pointer_p (0));
+ }
+ void impl_call_post (const call_details &cd) const final override;
+};
+
+void
+kf_strchr::impl_call_post (const call_details &cd) const
+{
+ class strchr_call_info : public call_info
+ {
+ public:
+ strchr_call_info (const call_details &cd, bool found)
+ : call_info (cd), m_found (found)
+ {
+ }
+
+ label_text get_desc (bool can_colorize) const final override
+ {
+ if (m_found)
+ return make_label_text (can_colorize,
+ "when %qE returns non-NULL",
+ get_fndecl ());
+ else
+ return make_label_text (can_colorize,
+ "when %qE returns NULL",
+ get_fndecl ());
+ }
+
+ bool update_model (region_model *model,
+ const exploded_edge *,
+ region_model_context *ctxt) const final override
+ {
+ const call_details cd (get_call_details (model, ctxt));
+ if (tree lhs_type = cd.get_lhs_type ())
+ {
+ region_model_manager *mgr = model->get_manager ();
+ const svalue *result;
+ if (m_found)
+ {
+ const svalue *str_sval = cd.get_arg_svalue (0);
+ const region *str_reg
+ = model->deref_rvalue (str_sval, cd.get_arg_tree (0),
+ cd.get_ctxt ());
+ /* We want str_sval + OFFSET for some unknown OFFSET.
+ Use a conjured_svalue to represent the offset,
+ using the str_reg as the id of the conjured_svalue. */
+ const svalue *offset
+ = mgr->get_or_create_conjured_svalue (size_type_node,
+ cd.get_call_stmt (),
+ str_reg,
+ conjured_purge (model,
+ ctxt));
+ result = mgr->get_or_create_binop (lhs_type, POINTER_PLUS_EXPR,
+ str_sval, offset);
+ }
+ else
+ result = mgr->get_or_create_int_cst (lhs_type, 0);
+ cd.maybe_set_lhs (result);
+ }
+ return true;
+ }
+ private:
+ bool m_found;
+ };
+
+ /* Body of kf_strchr::impl_call_post. */
+ if (cd.get_ctxt ())
+ {
+ cd.get_ctxt ()->bifurcate (make_unique<strchr_call_info> (cd, false));
+ cd.get_ctxt ()->bifurcate (make_unique<strchr_call_info> (cd, true));
+ cd.get_ctxt ()->terminate_path ();
+ }
+}
+
+/* Handler for "__builtin_stack_restore". */
+
+class kf_stack_restore : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &) const final override
+ {
+ return true;
+ }
+
+ /* Currently a no-op. */
+};
+
+/* Handler for "__builtin_stack_save". */
+
+class kf_stack_save : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &) const final override
+ {
+ return true;
+ }
+
+ /* Currently a no-op. */
+};
+
+/* Handler for "strcpy" and "__builtin_strcpy_chk". */
+
+class kf_strcpy : public known_function
+{
+public:
+ kf_strcpy (unsigned int num_args) : m_num_args (num_args) {}
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == m_num_args
+ && cd.arg_is_pointer_p (0)
+ && cd.arg_is_pointer_p (1));
+ }
+
+ void impl_call_pre (const call_details &cd) const final override;
+
+private:
+ unsigned int m_num_args;
+};
+
+void
+kf_strcpy::impl_call_pre (const call_details &cd) const
+{
+ region_model *model = cd.get_model ();
+ region_model_manager *mgr = cd.get_manager ();
+
+ const svalue *dest_sval = cd.get_arg_svalue (0);
+ const region *dest_reg = model->deref_rvalue (dest_sval, cd.get_arg_tree (0),
+ cd.get_ctxt ());
+ const svalue *src_sval = cd.get_arg_svalue (1);
+ const region *src_reg = model->deref_rvalue (src_sval, cd.get_arg_tree (1),
+ cd.get_ctxt ());
+ const svalue *src_contents_sval = model->get_store_value (src_reg,
+ cd.get_ctxt ());
+
+ cd.maybe_set_lhs (dest_sval);
+
+ /* Try to get the string size if SRC_REG is a string_region. */
+ const svalue *copied_bytes_sval = model->get_string_size (src_reg);
+ /* Otherwise, check if the contents of SRC_REG is a string. */
+ if (copied_bytes_sval->get_kind () == SK_UNKNOWN)
+ copied_bytes_sval = model->get_string_size (src_contents_sval);
+
+ const region *sized_dest_reg
+ = mgr->get_sized_region (dest_reg, NULL_TREE, copied_bytes_sval);
+ model->set_value (sized_dest_reg, src_contents_sval, cd.get_ctxt ());
+}
+
+/* Handle the on_call_pre part of "strlen". */
+
+class kf_strlen : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 1 && cd.arg_is_pointer_p (0));
+ }
+ void impl_call_pre (const call_details &cd) const final override;
+};
+
+void
+kf_strlen::impl_call_pre (const call_details &cd) const
+{
+ region_model_context *ctxt = cd.get_ctxt ();
+ region_model *model = cd.get_model ();
+ region_model_manager *mgr = cd.get_manager ();
+
+ const svalue *arg_sval = cd.get_arg_svalue (0);
+ const region *buf_reg
+ = model->deref_rvalue (arg_sval, cd.get_arg_tree (0), ctxt);
+ if (const string_region *str_reg
+ = buf_reg->dyn_cast_string_region ())
+ {
+ tree str_cst = str_reg->get_string_cst ();
+ /* TREE_STRING_LENGTH is sizeof, not strlen. */
+ int sizeof_cst = TREE_STRING_LENGTH (str_cst);
+ int strlen_cst = sizeof_cst - 1;
+ if (cd.get_lhs_type ())
+ {
+ tree t_cst = build_int_cst (cd.get_lhs_type (), strlen_cst);
+ const svalue *result_sval
+ = mgr->get_or_create_constant_svalue (t_cst);
+ cd.maybe_set_lhs (result_sval);
+ return;
+ }
+ }
+ /* Otherwise a conjured value. */
+}
+
+class kf_ubsan_bounds : public internal_known_function
+{
+ /* Empty. */
+};
+
+/* Handle calls to functions referenced by
+ __attribute__((malloc(FOO))). */
+
+void
+region_model::impl_deallocation_call (const call_details &cd)
+{
+ kf_free kf;
+ kf.impl_call_post (cd);
+}
+
+/* Populate KFM with instances of known functions supported by the core of the
+ analyzer (as opposed to plugins). */
+
+void
+register_known_functions (known_function_manager &kfm)
+{
+ /* Debugging/test support functions, all with a "__analyzer_" prefix. */
+ register_known_analyzer_functions (kfm);
+
+ /* Internal fns the analyzer has known_functions for. */
+ {
+ kfm.add (IFN_BUILTIN_EXPECT, make_unique<kf_expect> ());
+ kfm.add (IFN_UBSAN_BOUNDS, make_unique<kf_ubsan_bounds> ());
+ }
+
+ /* Built-ins the analyzer has known_functions for. */
+ {
+ kfm.add (BUILT_IN_ALLOCA, make_unique<kf_alloca> ());
+ kfm.add (BUILT_IN_ALLOCA_WITH_ALIGN, make_unique<kf_alloca> ());
+ kfm.add (BUILT_IN_CALLOC, make_unique<kf_calloc> ());
+ kfm.add (BUILT_IN_EXPECT, make_unique<kf_expect> ());
+ kfm.add (BUILT_IN_EXPECT_WITH_PROBABILITY, make_unique<kf_expect> ());
+ kfm.add (BUILT_IN_FREE, make_unique<kf_free> ());
+ kfm.add (BUILT_IN_MALLOC, make_unique<kf_malloc> ());
+ kfm.add (BUILT_IN_MEMCPY, make_unique<kf_memcpy_memmove> ());
+ kfm.add (BUILT_IN_MEMCPY_CHK, make_unique<kf_memcpy_memmove> ());
+ kfm.add (BUILT_IN_MEMMOVE, make_unique<kf_memcpy_memmove> ());
+ kfm.add (BUILT_IN_MEMMOVE_CHK, make_unique<kf_memcpy_memmove> ());
+ kfm.add (BUILT_IN_MEMSET, make_unique<kf_memset> ());
+ kfm.add (BUILT_IN_MEMSET_CHK, make_unique<kf_memset> ());
+ kfm.add (BUILT_IN_REALLOC, make_unique<kf_realloc> ());
+ kfm.add (BUILT_IN_STACK_RESTORE, make_unique<kf_stack_restore> ());
+ kfm.add (BUILT_IN_STACK_SAVE, make_unique<kf_stack_save> ());
+ kfm.add (BUILT_IN_STRCHR, make_unique<kf_strchr> ());
+ kfm.add (BUILT_IN_STRCPY, make_unique<kf_strcpy> (2));
+ kfm.add (BUILT_IN_STRCPY_CHK, make_unique<kf_strcpy> (3));
+ kfm.add (BUILT_IN_STRLEN, make_unique<kf_strlen> ());
+
+ register_varargs_builtins (kfm);
+ }
+
+ /* Known builtins and C standard library functions. */
+ {
+ kfm.add ("memset", make_unique<kf_memset> ());
+ }
+
+ /* Known POSIX functions, and some non-standard extensions. */
+ {
+ kfm.add ("putenv", make_unique<kf_putenv> ());
+
+ register_known_fd_functions (kfm);
+ register_known_file_functions (kfm);
+ }
+
+ /* glibc functions. */
+ {
+ kfm.add ("__errno_location", make_unique<kf_errno_location> ());
+ kfm.add ("error", make_unique<kf_error> (3));
+ kfm.add ("error_at_line", make_unique<kf_error> (5));
+ }
+
+ /* Other implementations of C standard library. */
+ {
+ /* According to PR 107807 comment #2, Solaris implements "errno"
+ like this:
+ extern int *___errno(void) __attribute__((__const__));
+ #define errno (*(___errno()))
+ and OS X like this:
+ extern int * __error(void);
+ #define errno (*__error())
+ Add these as synonyms for "__errno_location". */
+ kfm.add ("___errno", make_unique<kf_errno_location> ());
+ kfm.add ("__error", make_unique<kf_errno_location> ());
+ }
+
+ /* Language-specific support functions. */
+ register_known_functions_lang_cp (kfm);
+}
+
+} // namespace ana
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/known-function-manager.cc b/gcc/analyzer/known-function-manager.cc
index 48fb005..dc514a7 100644
--- a/gcc/analyzer/known-function-manager.cc
+++ b/gcc/analyzer/known-function-manager.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
@@ -26,7 +27,11 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-core.h"
#include "analyzer/analyzer-logging.h"
#include "stringpool.h"
+#include "basic-block.h"
+#include "gimple.h"
#include "analyzer/known-function-manager.h"
+#include "analyzer/region-model.h"
+#include "analyzer/call-details.h"
#if ENABLE_ANALYZER
@@ -37,6 +42,7 @@ namespace ana {
known_function_manager::known_function_manager (logger *logger)
: log_user (logger)
{
+ memset (m_combined_fns_arr, 0, sizeof (m_combined_fns_arr));
}
known_function_manager::~known_function_manager ()
@@ -44,34 +50,107 @@ known_function_manager::~known_function_manager ()
/* Delete all owned kfs. */
for (auto iter : m_map_id_to_kf)
delete iter.second;
+ for (auto iter : m_combined_fns_arr)
+ delete iter;
}
void
-known_function_manager::add (const char *name, known_function *kf)
+known_function_manager::add (const char *name,
+ std::unique_ptr<known_function> kf)
{
LOG_FUNC_1 (get_logger (), "registering %s", name);
tree id = get_identifier (name);
- m_map_id_to_kf.put (id, kf);
+ m_map_id_to_kf.put (id, kf.release ());
}
-const known_function *
-known_function_manager::get_by_identifier (tree identifier)
+void
+known_function_manager::add (enum built_in_function name,
+ std::unique_ptr<known_function> kf)
{
- known_function **slot = m_map_id_to_kf.get (identifier);
- if (slot)
- return *slot;
- else
- return NULL;
+ gcc_assert (name < END_BUILTINS);
+ delete m_combined_fns_arr[name];
+ m_combined_fns_arr[name] = kf.release ();
+}
+
+void
+known_function_manager::add (enum internal_fn ifn,
+ std::unique_ptr<known_function> kf)
+{
+ gcc_assert (ifn < IFN_LAST);
+ delete m_combined_fns_arr[ifn + END_BUILTINS];
+ m_combined_fns_arr[ifn + END_BUILTINS] = kf.release ();
}
+/* Get any known_function for FNDECL for call CD.
+
+ The call must match all assumptions made by the known_function (such as
+ e.g. "argument 1's type must be a pointer type").
+
+ Return NULL if no known_function is found, or it does not match the
+ assumption(s). */
+
const known_function *
-known_function_manager::get_by_fndecl (tree fndecl)
+known_function_manager::get_match (tree fndecl, const call_details &cd) const
{
+ /* Look for a matching built-in. */
+ if (fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
+ {
+ if (const known_function *candidate
+ = get_normal_builtin (DECL_FUNCTION_CODE (fndecl)))
+ if (gimple_builtin_call_types_compatible_p (cd.get_call_stmt (),
+ fndecl))
+ return candidate;
+ }
+
+ /* Look for a match by name. */
+
+ /* Reject fndecls that aren't in the root namespace. */
+ if (DECL_CONTEXT (fndecl)
+ && TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL)
+ return NULL;
if (tree identifier = DECL_NAME (fndecl))
- return get_by_identifier (identifier);
+ if (const known_function *candidate = get_by_identifier (identifier))
+ if (candidate->matches_call_types_p (cd))
+ return candidate;
+
return NULL;
}
+/* Get any known_function for IFN, or NULL. */
+
+const known_function *
+known_function_manager::get_internal_fn (enum internal_fn ifn) const
+{
+ gcc_assert (ifn < IFN_LAST);
+ return m_combined_fns_arr[ifn + END_BUILTINS];
+}
+
+/* Get any known_function for NAME, without type-checking.
+ Return NULL if there isn't one. */
+
+const known_function *
+known_function_manager::get_normal_builtin (enum built_in_function name) const
+{
+ /* The numbers for built-in functions in enum combined_fn are the same as
+ for the built_in_function enum. */
+ gcc_assert (name < END_BUILTINS);
+ return m_combined_fns_arr[name];
+}
+
+/* Get any known_function matching IDENTIFIER, without type-checking.
+ Return NULL if there isn't one. */
+
+const known_function *
+known_function_manager::get_by_identifier (tree identifier) const
+{
+ known_function_manager *mut_this = const_cast<known_function_manager *>(this);
+ known_function **slot = mut_this->m_map_id_to_kf.get (identifier);
+ if (slot)
+ return *slot;
+ else
+ return NULL;
+}
+
} // namespace ana
#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/known-function-manager.h b/gcc/analyzer/known-function-manager.h
index 2b95b7e..7bacafe 100644
--- a/gcc/analyzer/known-function-manager.h
+++ b/gcc/analyzer/known-function-manager.h
@@ -25,21 +25,43 @@ along with GCC; see the file COPYING3. If not see
namespace ana {
+/* Instances of known_function are registered with the known_function_manager
+ when the analyzer starts.
+
+ The known_function_manager has responsibility for determining which
+ known_function instance (if any) is relevant at a call site, by checking
+ name or id, and by calling known_function::matches_call_types_p to ensure
+ that the known_function's preconditions hold (typically assumptions about
+ types e.g. that "has 3 args, and that arg 0 is of pointer type").
+
+ The known_function subclasses themselves have responsibility for
+ determining the outcome(s) of the call. */
+
class known_function_manager : public log_user
{
public:
known_function_manager (logger *logger);
~known_function_manager ();
- void add (const char *name, known_function *kf);
- const known_function *get_by_identifier (tree identifier);
- const known_function *get_by_fndecl (tree fndecl);
+
+ void add (const char *name, std::unique_ptr<known_function> kf);
+ void add (enum built_in_function name, std::unique_ptr<known_function> kf);
+ void add (enum internal_fn ifn, std::unique_ptr<known_function> kf);
+
+ const known_function *get_match (tree fndecl, const call_details &cd) const;
+ const known_function *get_internal_fn (enum internal_fn) const;
private:
DISABLE_COPY_AND_ASSIGN (known_function_manager);
+ const known_function *get_normal_builtin (enum built_in_function name) const;
+ const known_function *get_by_identifier (tree identifier) const;
+
/* Map from identifier to known_function instance.
Has ownership of the latter. */
hash_map<tree, known_function *> m_map_id_to_kf;
+
+ /* Array of known builtins. */
+ known_function *m_combined_fns_arr[CFN_LAST];
};
} // namespace ana
diff --git a/gcc/analyzer/pending-diagnostic.cc b/gcc/analyzer/pending-diagnostic.cc
index 50a8afc..5ff32c0 100644
--- a/gcc/analyzer/pending-diagnostic.cc
+++ b/gcc/analyzer/pending-diagnostic.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
@@ -49,6 +50,7 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/exploded-graph.h"
#include "diagnostic-path.h"
#include "analyzer/checker-path.h"
+#include "make-unique.h"
#if ENABLE_ANALYZER
@@ -151,7 +153,7 @@ fixup_location_in_macro_p (cpp_hashnode *macro)
Don't unwind inside macros for which fixup_location_in_macro_p is true. */
location_t
-pending_diagnostic::fixup_location (location_t loc) const
+pending_diagnostic::fixup_location (location_t loc, bool) const
{
if (linemap_location_from_macro_expansion_p (line_table, loc))
{
@@ -165,6 +167,18 @@ pending_diagnostic::fixup_location (location_t loc) const
return loc;
}
+/* Base implementation of pending_diagnostic::add_function_entry_event.
+ Add a function_entry_event to EMISSION_PATH. */
+
+void
+pending_diagnostic::add_function_entry_event (const exploded_edge &eedge,
+ checker_path *emission_path)
+{
+ const exploded_node *dst_node = eedge.m_dest;
+ const program_point &dst_point = dst_node->get_point ();
+ emission_path->add_event (make_unique<function_entry_event> (dst_point));
+}
+
/* Base implementation of pending_diagnostic::add_call_event.
Add a call_event to EMISSION_PATH. */
@@ -177,12 +191,48 @@ pending_diagnostic::add_call_event (const exploded_edge &eedge,
const int src_stack_depth = src_point.get_stack_depth ();
const gimple *last_stmt = src_point.get_supernode ()->get_last_stmt ();
emission_path->add_event
- (new call_event (eedge,
- (last_stmt
- ? last_stmt->location
- : UNKNOWN_LOCATION),
- src_point.get_fndecl (),
- src_stack_depth));
+ (make_unique<call_event> (eedge,
+ event_loc_info (last_stmt
+ ? last_stmt->location
+ : UNKNOWN_LOCATION,
+ src_point.get_fndecl (),
+ src_stack_depth)));
+}
+
+/* Base implementation of pending_diagnostic::add_region_creation_events.
+ See the comment for class region_creation_event. */
+
+void
+pending_diagnostic::add_region_creation_events (const region *reg,
+ tree capacity,
+ const event_loc_info &loc_info,
+ checker_path &emission_path)
+{
+ emission_path.add_event
+ (make_unique<region_creation_event_memory_space> (reg->get_memory_space (),
+ loc_info));
+
+ if (capacity)
+ emission_path.add_event
+ (make_unique<region_creation_event_capacity> (capacity, loc_info));
+}
+
+/* Base implementation of pending_diagnostic::add_final_event.
+ Add a warning_event to the end of EMISSION_PATH. */
+
+void
+pending_diagnostic::add_final_event (const state_machine *sm,
+ const exploded_node *enode,
+ const gimple *stmt,
+ tree var, state_machine::state_t state,
+ checker_path *emission_path)
+{
+ emission_path->add_event
+ (make_unique<warning_event>
+ (event_loc_info (get_stmt_location (stmt, enode->get_function ()),
+ enode->get_function ()->decl,
+ enode->get_stack_depth ()),
+ sm, var, state));
}
} // namespace ana
diff --git a/gcc/analyzer/pending-diagnostic.h b/gcc/analyzer/pending-diagnostic.h
index 4ea469e..be446a4 100644
--- a/gcc/analyzer/pending-diagnostic.h
+++ b/gcc/analyzer/pending-diagnostic.h
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#define GCC_ANALYZER_PENDING_DIAGNOSTIC_H
#include "diagnostic-path.h"
+#include "analyzer/sm.h"
namespace ana {
@@ -58,17 +59,6 @@ struct event_desc
bool m_colorize;
};
-/* For use by pending_diagnostic::describe_region_creation. */
-
-struct region_creation : public event_desc
-{
- region_creation (bool colorize, const region *reg)
- : event_desc (colorize), m_reg (reg)
- {}
-
- const region *m_reg;
-};
-
/* For use by pending_diagnostic::describe_state_change. */
struct state_change : public event_desc
@@ -213,27 +203,10 @@ class pending_diagnostic
diagnostic deduplication. */
static bool same_tree_p (tree t1, tree t2);
- /* A vfunc for fixing up locations (both the primary location for the
- diagnostic, and for events in their paths), e.g. to avoid unwinding
- inside specific macros. */
- virtual location_t fixup_location (location_t loc) const;
-
- /* For greatest precision-of-wording, the various following "describe_*"
- virtual functions give the pending diagnostic a way to describe events
- in a diagnostic_path in terms that make sense for that diagnostic.
-
- In each case, return a non-NULL label_text to give the event a custom
- description; NULL otherwise (falling back on a more generic
- description). */
-
- /* Precision-of-wording vfunc for describing a region creation event
- triggered by the mark_interesting_stuff vfunc. */
- virtual label_text
- describe_region_creation_event (const evdesc::region_creation &)
- {
- /* Default no-op implementation. */
- return label_text ();
- }
+ /* Vfunc for fixing up locations, e.g. to avoid unwinding
+ inside specific macros. PRIMARY is true for the primary location
+ for the diagnostic, and FALSE for events in their paths. */
+ virtual location_t fixup_location (location_t loc, bool primary) const;
/* Precision-of-wording vfunc for describing a critical state change
within the diagnostic_path.
@@ -308,6 +281,14 @@ class pending_diagnostic
/* End of precision-of-wording vfuncs. */
+ /* Vfunc for adding a function_entry_event to a checker_path, so that e.g.
+ the infinite recursion diagnostic can add a custom event subclass
+ that annotates recursively entering a function. */
+
+ virtual void
+ add_function_entry_event (const exploded_edge &eedge,
+ checker_path *emission_path);
+
/* Vfunc for extending/overriding creation of the events for an
exploded_edge that corresponds to a superedge, allowing for custom
events to be created that are pertinent to a particular
@@ -329,6 +310,24 @@ class pending_diagnostic
virtual void add_call_event (const exploded_edge &,
checker_path *);
+ /* Vfunc for adding any events for the creation of regions identified
+ by the mark_interesting_stuff vfunc.
+ See the comment for class region_creation_event. */
+ virtual void add_region_creation_events (const region *reg,
+ tree capacity,
+ const event_loc_info &loc_info,
+ checker_path &emission_path);
+
+ /* Vfunc for adding the final warning_event to a checker_path, so that e.g.
+ the infinite recursion diagnostic can have its diagnostic appear at
+ the callsite, but the final event in the path be at the entrypoint
+ of the called function. */
+ virtual void add_final_event (const state_machine *sm,
+ const exploded_node *enode,
+ const gimple *stmt,
+ tree var, state_machine::state_t state,
+ checker_path *emission_path);
+
/* Vfunc for determining that this pending_diagnostic supercedes OTHER,
and that OTHER should therefore not be emitted.
They have already been tested for being at the same stmt. */
diff --git a/gcc/analyzer/program-point.cc b/gcc/analyzer/program-point.cc
index cfa4dda..23635a1 100644
--- a/gcc/analyzer/program-point.cc
+++ b/gcc/analyzer/program-point.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index 7537dc0..3942b5f 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
@@ -517,6 +518,14 @@ sm_state_map::impl_set_state (const svalue *sval,
return true;
}
+/* Clear any state for SVAL from this state map. */
+
+void
+sm_state_map::clear_any_state (const svalue *sval)
+{
+ m_map.remove (sval);
+}
+
/* Set the "global" state within this state map to STATE. */
void
@@ -718,6 +727,67 @@ sm_state_map::canonicalize_svalue (const svalue *sval,
return sval;
}
+/* Attempt to merge this state map with OTHER, writing the result
+ into *OUT.
+ Return true if the merger was possible, false otherwise.
+
+ Normally, only identical state maps can be merged, so that
+ differences between state maps lead to different enodes
+
+ However some state machines may support merging states to
+ allow for discarding of less important states, and thus avoid
+ blow-up of the exploded graph. */
+
+bool
+sm_state_map::can_merge_with_p (const sm_state_map &other,
+ const state_machine &sm,
+ const extrinsic_state &ext_state,
+ sm_state_map **out) const
+{
+ /* If identical, then they merge trivially, with a copy. */
+ if (*this == other)
+ {
+ delete *out;
+ *out = clone ();
+ return true;
+ }
+
+ delete *out;
+ *out = new sm_state_map (sm);
+
+ /* Otherwise, attempt to merge element by element. */
+
+ /* Try to merge global state. */
+ if (state_machine::state_t merged_global_state
+ = sm.maybe_get_merged_state (get_global_state (),
+ other.get_global_state ()))
+ (*out)->set_global_state (merged_global_state);
+ else
+ return false;
+
+ /* Try to merge state each svalue's state (for the union
+ of svalues represented by each smap).
+ Ignore the origin information. */
+ hash_set<const svalue *> svals;
+ for (auto kv : *this)
+ svals.add (kv.first);
+ for (auto kv : other)
+ svals.add (kv.first);
+ for (auto sval : svals)
+ {
+ state_machine::state_t this_state = get_state (sval, ext_state);
+ state_machine::state_t other_state = other.get_state (sval, ext_state);
+ if (state_machine::state_t merged_state
+ = sm.maybe_get_merged_state (this_state, other_state))
+ (*out)->impl_set_state (sval, merged_state, NULL, ext_state);
+ else
+ return false;
+ }
+
+ /* Successfully merged all elements. */
+ return true;
+}
+
/* class program_state. */
/* program_state's ctor. */
@@ -751,6 +821,8 @@ sm_state_map::replay_call_summary (call_summary_replay &r,
const svalue *caller_sval = r.convert_svalue_from_summary (summary_sval);
if (!caller_sval)
continue;
+ if (!caller_sval->can_have_associated_state_p ())
+ continue;
const svalue *summary_origin = kv.second.m_origin;
const svalue *caller_origin
= (summary_origin
@@ -1282,11 +1354,14 @@ program_state::can_merge_with_p (const program_state &other,
gcc_assert (out);
gcc_assert (m_region_model);
- /* Early reject if there are sm-differences between the states. */
+ /* Attempt to merge the sm-states. */
int i;
sm_state_map *smap;
FOR_EACH_VEC_ELT (out->m_checker_states, i, smap)
- if (*m_checker_states[i] != *other.m_checker_states[i])
+ if (!m_checker_states[i]->can_merge_with_p (*other.m_checker_states[i],
+ ext_state.get_sm (i),
+ ext_state,
+ &out->m_checker_states[i]))
return false;
/* Attempt to merge the region_models. */
@@ -1297,13 +1372,6 @@ program_state::can_merge_with_p (const program_state &other,
this, &other))
return false;
- /* Copy m_checker_states to OUT. */
- FOR_EACH_VEC_ELT (out->m_checker_states, i, smap)
- {
- delete smap;
- out->m_checker_states[i] = m_checker_states[i]->clone ();
- }
-
out->m_region_model->canonicalize ();
return true;
@@ -1667,7 +1735,7 @@ test_program_state_1 ()
const svalue *size_in_bytes
= mgr->get_or_create_unknown_svalue (size_type_node);
const region *new_reg
- = model->create_region_for_heap_alloc (size_in_bytes, NULL);
+ = model->get_or_create_region_for_heap_alloc (size_in_bytes, NULL);
const svalue *ptr_sval = mgr->get_ptr_svalue (ptr_type_node, new_reg);
model->set_value (model->get_lvalue (p, NULL),
ptr_sval, NULL);
@@ -1724,7 +1792,7 @@ test_program_state_merging ()
const svalue *size_in_bytes
= mgr->get_or_create_unknown_svalue (size_type_node);
const region *new_reg
- = model0->create_region_for_heap_alloc (size_in_bytes, NULL);
+ = model0->get_or_create_region_for_heap_alloc (size_in_bytes, NULL);
const svalue *ptr_sval = mgr->get_ptr_svalue (ptr_type_node, new_reg);
model0->set_value (model0->get_lvalue (p, &ctxt),
ptr_sval, &ctxt);
diff --git a/gcc/analyzer/program-state.h b/gcc/analyzer/program-state.h
index ad40578..7964327 100644
--- a/gcc/analyzer/program-state.h
+++ b/gcc/analyzer/program-state.h
@@ -145,6 +145,7 @@ public:
state_machine::state_t state,
const svalue *origin,
const extrinsic_state &ext_state);
+ void clear_any_state (const svalue *sval);
void set_global_state (state_machine::state_t state);
state_machine::state_t get_global_state () const;
@@ -174,6 +175,11 @@ public:
bool replay_call_summary (call_summary_replay &r,
const sm_state_map &summary);
+ bool can_merge_with_p (const sm_state_map &other,
+ const state_machine &sm,
+ const extrinsic_state &ext_state,
+ sm_state_map **out) const;
+
private:
const state_machine &m_sm;
map_t m_map;
diff --git a/gcc/analyzer/region-model-asm.cc b/gcc/analyzer/region-model-asm.cc
index b4c1f91..171b249 100644
--- a/gcc/analyzer/region-model-asm.cc
+++ b/gcc/analyzer/region-model-asm.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
diff --git a/gcc/analyzer/region-model-impl-calls.cc b/gcc/analyzer/region-model-impl-calls.cc
deleted file mode 100644
index 52c4205..0000000
--- a/gcc/analyzer/region-model-impl-calls.cc
+++ /dev/null
@@ -1,1150 +0,0 @@
-/* Handling for the known behavior of various specific functions.
- Copyright (C) 2020-2022 Free Software Foundation, Inc.
- Contributed by David Malcolm <dmalcolm@redhat.com>.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tree.h"
-#include "function.h"
-#include "basic-block.h"
-#include "gimple.h"
-#include "gimple-iterator.h"
-#include "diagnostic-core.h"
-#include "graphviz.h"
-#include "options.h"
-#include "cgraph.h"
-#include "tree-dfa.h"
-#include "stringpool.h"
-#include "convert.h"
-#include "target.h"
-#include "fold-const.h"
-#include "tree-pretty-print.h"
-#include "diagnostic-color.h"
-#include "diagnostic-metadata.h"
-#include "bitmap.h"
-#include "analyzer/analyzer.h"
-#include "analyzer/analyzer-logging.h"
-#include "ordered-hash-map.h"
-#include "options.h"
-#include "analyzer/supergraph.h"
-#include "sbitmap.h"
-#include "analyzer/call-string.h"
-#include "analyzer/program-point.h"
-#include "analyzer/store.h"
-#include "analyzer/region-model.h"
-#include "analyzer/call-info.h"
-#include "analyzer/sm.h"
-#include "diagnostic-path.h"
-#include "analyzer/pending-diagnostic.h"
-#include "gimple-pretty-print.h"
-
-#if ENABLE_ANALYZER
-
-namespace ana {
-
-/* class call_details. */
-
-/* call_details's ctor. */
-
-call_details::call_details (const gcall *call, region_model *model,
- region_model_context *ctxt)
-: m_call (call), m_model (model), m_ctxt (ctxt),
- m_lhs_type (NULL_TREE), m_lhs_region (NULL)
-{
- m_lhs_type = NULL_TREE;
- if (tree lhs = gimple_call_lhs (call))
- {
- m_lhs_region = model->get_lvalue (lhs, ctxt);
- m_lhs_type = TREE_TYPE (lhs);
- }
-}
-
-/* Get the manager from m_model. */
-
-region_model_manager *
-call_details::get_manager () const
-{
- return m_model->get_manager ();
-}
-
-/* Get any logger associated with this object. */
-
-logger *
-call_details::get_logger () const
-{
- if (m_ctxt)
- return m_ctxt->get_logger ();
- else
- return NULL;
-}
-
-/* Get any uncertainty_t associated with the region_model_context. */
-
-uncertainty_t *
-call_details::get_uncertainty () const
-{
- if (m_ctxt)
- return m_ctxt->get_uncertainty ();
- else
- return NULL;
-}
-
-/* If the callsite has a left-hand-side region, set it to RESULT
- and return true.
- Otherwise do nothing and return false. */
-
-bool
-call_details::maybe_set_lhs (const svalue *result) const
-{
- gcc_assert (result);
- if (m_lhs_region)
- {
- m_model->set_value (m_lhs_region, result, m_ctxt);
- return true;
- }
- else
- return false;
-}
-
-/* Return the number of arguments used by the call statement. */
-
-unsigned
-call_details::num_args () const
-{
- return gimple_call_num_args (m_call);
-}
-
-/* Get argument IDX at the callsite as a tree. */
-
-tree
-call_details::get_arg_tree (unsigned idx) const
-{
- return gimple_call_arg (m_call, idx);
-}
-
-/* Get the type of argument IDX. */
-
-tree
-call_details::get_arg_type (unsigned idx) const
-{
- return TREE_TYPE (gimple_call_arg (m_call, idx));
-}
-
-/* Get argument IDX at the callsite as an svalue. */
-
-const svalue *
-call_details::get_arg_svalue (unsigned idx) const
-{
- tree arg = get_arg_tree (idx);
- return m_model->get_rvalue (arg, m_ctxt);
-}
-
-/* Attempt to get the string literal for argument IDX, or return NULL
- otherwise.
- For use when implementing "__analyzer_*" functions that take
- string literals. */
-
-const char *
-call_details::get_arg_string_literal (unsigned idx) const
-{
- const svalue *str_arg = get_arg_svalue (idx);
- if (const region *pointee = str_arg->maybe_get_region ())
- if (const string_region *string_reg = pointee->dyn_cast_string_region ())
- {
- tree string_cst = string_reg->get_string_cst ();
- return TREE_STRING_POINTER (string_cst);
- }
- return NULL;
-}
-
-/* Attempt to get the fndecl used at this call, if known, or NULL_TREE
- otherwise. */
-
-tree
-call_details::get_fndecl_for_call () const
-{
- return m_model->get_fndecl_for_call (m_call, m_ctxt);
-}
-
-/* Dump a multiline representation of this call to PP. */
-
-void
-call_details::dump_to_pp (pretty_printer *pp, bool simple) const
-{
- pp_string (pp, "gcall: ");
- pp_gimple_stmt_1 (pp, m_call, 0 /* spc */, TDF_NONE /* flags */);
- pp_newline (pp);
- pp_string (pp, "return region: ");
- if (m_lhs_region)
- m_lhs_region->dump_to_pp (pp, simple);
- else
- pp_string (pp, "NULL");
- pp_newline (pp);
- for (unsigned i = 0; i < gimple_call_num_args (m_call); i++)
- {
- const svalue *arg_sval = get_arg_svalue (i);
- pp_printf (pp, "arg %i: ", i);
- arg_sval->dump_to_pp (pp, simple);
- pp_newline (pp);
- }
-}
-
-/* Dump a multiline representation of this call to stderr. */
-
-DEBUG_FUNCTION void
-call_details::dump (bool simple) const
-{
- pretty_printer pp;
- pp_format_decoder (&pp) = default_tree_printer;
- pp_show_color (&pp) = pp_show_color (global_dc->printer);
- pp.buffer->stream = stderr;
- dump_to_pp (&pp, simple);
- pp_flush (&pp);
-}
-
-/* Get a conjured_svalue for this call for REG,
- and purge any state already relating to that conjured_svalue. */
-
-const svalue *
-call_details::get_or_create_conjured_svalue (const region *reg) const
-{
- region_model_manager *mgr = m_model->get_manager ();
- return mgr->get_or_create_conjured_svalue (reg->get_type (), m_call, reg,
- conjured_purge (m_model, m_ctxt));
-}
-
-/* Implementations of specific functions. */
-
-/* Handle the on_call_pre part of "alloca". */
-
-void
-region_model::impl_call_alloca (const call_details &cd)
-{
- const svalue *size_sval = cd.get_arg_svalue (0);
- const region *new_reg = create_region_for_alloca (size_sval, cd.get_ctxt ());
- const svalue *ptr_sval
- = m_mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
- cd.maybe_set_lhs (ptr_sval);
-}
-
-/* Handle a call to "__analyzer_describe".
-
- Emit a warning describing the 2nd argument (which can be of any
- type), at the given verbosity level. This is for use when
- debugging, and may be of use in DejaGnu tests. */
-
-void
-region_model::impl_call_analyzer_describe (const gcall *call,
- region_model_context *ctxt)
-{
- tree t_verbosity = gimple_call_arg (call, 0);
- tree t_val = gimple_call_arg (call, 1);
- const svalue *sval = get_rvalue (t_val, ctxt);
- bool simple = zerop (t_verbosity);
- label_text desc = sval->get_desc (simple);
- warning_at (call->location, 0, "svalue: %qs", desc.get ());
-}
-
-/* Handle a call to "__analyzer_dump_capacity".
-
- Emit a warning describing the capacity of the base region of
- the region pointed to by the 1st argument.
- This is for use when debugging, and may be of use in DejaGnu tests. */
-
-void
-region_model::impl_call_analyzer_dump_capacity (const gcall *call,
- region_model_context *ctxt)
-{
- tree t_ptr = gimple_call_arg (call, 0);
- const svalue *sval_ptr = get_rvalue (t_ptr, ctxt);
- const region *reg = deref_rvalue (sval_ptr, t_ptr, ctxt);
- const region *base_reg = reg->get_base_region ();
- const svalue *capacity = get_capacity (base_reg);
- label_text desc = capacity->get_desc (true);
- warning_at (call->location, 0, "capacity: %qs", desc.get ());
-}
-
-/* Compare D1 and D2 using their names, and then IDs to order them. */
-
-static int
-cmp_decls (tree d1, tree d2)
-{
- gcc_assert (DECL_P (d1));
- gcc_assert (DECL_P (d2));
- if (DECL_NAME (d1) && DECL_NAME (d2))
- if (int cmp = strcmp (IDENTIFIER_POINTER (DECL_NAME (d1)),
- IDENTIFIER_POINTER (DECL_NAME (d2))))
- return cmp;
- return (int)DECL_UID (d1) - (int)DECL_UID (d2);
-}
-
-/* Comparator for use by vec<tree>::qsort,
- using their names, and then IDs to order them. */
-
-static int
-cmp_decls_ptr_ptr (const void *p1, const void *p2)
-{
- tree const *d1 = (tree const *)p1;
- tree const *d2 = (tree const *)p2;
-
- return cmp_decls (*d1, *d2);
-}
-
-/* Handle a call to "__analyzer_dump_escaped".
-
- Emit a warning giving the number of decls that have escaped, followed
- by a comma-separated list of their names, in alphabetical order.
-
- This is for use when debugging, and may be of use in DejaGnu tests. */
-
-void
-region_model::impl_call_analyzer_dump_escaped (const gcall *call)
-{
- auto_vec<tree> escaped_decls;
- for (auto iter : m_store)
- {
- const binding_cluster *c = iter.second;
- if (!c->escaped_p ())
- continue;
- if (tree decl = c->get_base_region ()->maybe_get_decl ())
- escaped_decls.safe_push (decl);
- }
-
- /* Sort them into deterministic order; alphabetical is
- probably most user-friendly. */
- escaped_decls.qsort (cmp_decls_ptr_ptr);
-
- pretty_printer pp;
- pp_format_decoder (&pp) = default_tree_printer;
- pp_show_color (&pp) = pp_show_color (global_dc->printer);
- bool first = true;
- for (auto iter : escaped_decls)
- {
- if (first)
- first = false;
- else
- pp_string (&pp, ", ");
- pp_printf (&pp, "%qD", iter);
- }
- /* Print the number to make it easier to write DejaGnu tests for
- the "nothing has escaped" case. */
- warning_at (call->location, 0, "escaped: %i: %s",
- escaped_decls.length (),
- pp_formatted_text (&pp));
-}
-
-/* Handle a call to "__analyzer_eval" by evaluating the input
- and dumping as a dummy warning, so that test cases can use
- dg-warning to validate the result (and so unexpected warnings will
- lead to DejaGnu failures).
- Broken out as a subroutine to make it easier to put a breakpoint on it
- - though typically this doesn't help, as we have an SSA name as the arg,
- and what's more interesting is usually the def stmt for that name. */
-
-void
-region_model::impl_call_analyzer_eval (const gcall *call,
- region_model_context *ctxt)
-{
- tree t_arg = gimple_call_arg (call, 0);
- tristate t = eval_condition (t_arg, NE_EXPR, integer_zero_node, ctxt);
- warning_at (call->location, 0, "%s", t.as_string ());
-}
-
-/* Handle the on_call_pre part of "__analyzer_get_unknown_ptr". */
-
-void
-region_model::impl_call_analyzer_get_unknown_ptr (const call_details &cd)
-{
- const svalue *ptr_sval
- = m_mgr->get_or_create_unknown_svalue (cd.get_lhs_type ());
- cd.maybe_set_lhs (ptr_sval);
-}
-
-/* Handle the on_call_pre part of "__builtin_expect" etc. */
-
-void
-region_model::impl_call_builtin_expect (const call_details &cd)
-{
- /* __builtin_expect's return value is its initial argument. */
- const svalue *sval = cd.get_arg_svalue (0);
- cd.maybe_set_lhs (sval);
-}
-
-/* Handle the on_call_pre part of "calloc". */
-
-void
-region_model::impl_call_calloc (const call_details &cd)
-{
- const svalue *nmemb_sval = cd.get_arg_svalue (0);
- const svalue *size_sval = cd.get_arg_svalue (1);
- /* TODO: check for overflow here? */
- const svalue *prod_sval
- = m_mgr->get_or_create_binop (size_type_node, MULT_EXPR,
- nmemb_sval, size_sval);
- const region *new_reg
- = create_region_for_heap_alloc (prod_sval, cd.get_ctxt ());
- const region *sized_reg
- = m_mgr->get_sized_region (new_reg, NULL_TREE, prod_sval);
- zero_fill_region (sized_reg);
- if (cd.get_lhs_type ())
- {
- const svalue *ptr_sval
- = m_mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
- cd.maybe_set_lhs (ptr_sval);
- }
-}
-
-/* Handle the on_call_pre part of "error" and "error_at_line" from
- GNU's non-standard <error.h>.
- MIN_ARGS identifies the minimum number of expected arguments
- to be consistent with such a call (3 and 5 respectively).
- Return true if handling it as one of these functions.
- Write true to *OUT_TERMINATE_PATH if this execution path should be
- terminated (e.g. the function call terminates the process). */
-
-bool
-region_model::impl_call_error (const call_details &cd, unsigned min_args,
- bool *out_terminate_path)
-{
- /* Bail if not enough args. */
- if (cd.num_args () < min_args)
- return false;
-
- /* Initial argument ought to be of type "int". */
- if (cd.get_arg_type (0) != integer_type_node)
- return false;
-
- /* The process exits if status != 0, so it only continues
- for the case where status == 0.
- Add that constraint, or terminate this analysis path. */
- tree status = cd.get_arg_tree (0);
- if (!add_constraint (status, EQ_EXPR, integer_zero_node, cd.get_ctxt ()))
- *out_terminate_path = true;
-
- return true;
-}
-
-/* Handle the on_call_pre part of "fgets" and "fgets_unlocked". */
-
-void
-region_model::impl_call_fgets (const call_details &cd)
-{
- /* Ideally we would bifurcate state here between the
- error vs no error cases. */
- const svalue *ptr_sval = cd.get_arg_svalue (0);
- if (const region *reg = ptr_sval->maybe_get_region ())
- {
- const region *base_reg = reg->get_base_region ();
- const svalue *new_sval = cd.get_or_create_conjured_svalue (base_reg);
- set_value (base_reg, new_sval, cd.get_ctxt ());
- }
-}
-
-/* Handle the on_call_pre part of "fread". */
-
-void
-region_model::impl_call_fread (const call_details &cd)
-{
- const svalue *ptr_sval = cd.get_arg_svalue (0);
- if (const region *reg = ptr_sval->maybe_get_region ())
- {
- const region *base_reg = reg->get_base_region ();
- const svalue *new_sval = cd.get_or_create_conjured_svalue (base_reg);
- set_value (base_reg, new_sval, cd.get_ctxt ());
- }
-}
-
-/* Handle the on_call_post part of "free", after sm-handling.
-
- If the ptr points to an underlying heap region, delete the region,
- poisoning pointers to it and regions within it.
-
- We delay this until after sm-state has been updated so that the
- sm-handling can transition all of the various casts of the pointer
- to a "freed" state *before* we delete the related region here.
-
- This has to be done here so that the sm-handling can use the fact
- that they point to the same region to establish that they are equal
- (in region_model::eval_condition_without_cm), and thus transition
- all pointers to the region to the "freed" state together, regardless
- of casts. */
-
-void
-region_model::impl_call_free (const call_details &cd)
-{
- const svalue *ptr_sval = cd.get_arg_svalue (0);
- if (const region *freed_reg = ptr_sval->maybe_get_region ())
- {
- /* If the ptr points to an underlying heap region, delete it,
- poisoning pointers. */
- unbind_region_and_descendents (freed_reg, POISON_KIND_FREED);
- m_dynamic_extents.remove (freed_reg);
- }
-}
-
-/* Handle the on_call_pre part of "malloc". */
-
-void
-region_model::impl_call_malloc (const call_details &cd)
-{
- const svalue *size_sval = cd.get_arg_svalue (0);
- const region *new_reg
- = create_region_for_heap_alloc (size_sval, cd.get_ctxt ());
- if (cd.get_lhs_type ())
- {
- const svalue *ptr_sval
- = m_mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
- cd.maybe_set_lhs (ptr_sval);
- }
-}
-
-/* Handle the on_call_pre part of "memcpy" and "__builtin_memcpy". */
-// TODO: complain about overlapping src and dest.
-
-void
-region_model::impl_call_memcpy (const call_details &cd)
-{
- const svalue *dest_ptr_sval = cd.get_arg_svalue (0);
- const svalue *src_ptr_sval = cd.get_arg_svalue (1);
- const svalue *num_bytes_sval = cd.get_arg_svalue (2);
-
- const region *dest_reg = deref_rvalue (dest_ptr_sval, cd.get_arg_tree (0),
- cd.get_ctxt ());
- const region *src_reg = deref_rvalue (src_ptr_sval, cd.get_arg_tree (1),
- cd.get_ctxt ());
-
- cd.maybe_set_lhs (dest_ptr_sval);
-
- const region *sized_src_reg
- = m_mgr->get_sized_region (src_reg, NULL_TREE, num_bytes_sval);
- const region *sized_dest_reg
- = m_mgr->get_sized_region (dest_reg, NULL_TREE, num_bytes_sval);
- const svalue *src_contents_sval
- = get_store_value (sized_src_reg, cd.get_ctxt ());
- set_value (sized_dest_reg, src_contents_sval, cd.get_ctxt ());
-}
-
-/* Handle the on_call_pre part of "memset" and "__builtin_memset". */
-
-void
-region_model::impl_call_memset (const call_details &cd)
-{
- const svalue *dest_sval = cd.get_arg_svalue (0);
- const svalue *fill_value_sval = cd.get_arg_svalue (1);
- const svalue *num_bytes_sval = cd.get_arg_svalue (2);
-
- const region *dest_reg = deref_rvalue (dest_sval, cd.get_arg_tree (0),
- cd.get_ctxt ());
-
- 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_region_for_write (sized_dest_reg, cd.get_ctxt ());
- fill_region (sized_dest_reg, fill_value_u8);
-}
-
-/* Handle the on_call_post part of "pipe". */
-
-void
-region_model::impl_call_pipe (const call_details &cd)
-{
- class failure : public failed_call_info
- {
- public:
- failure (const call_details &cd) : failed_call_info (cd) {}
-
- bool update_model (region_model *model,
- const exploded_edge *,
- region_model_context *ctxt) const final override
- {
- /* Return -1; everything else is unchanged. */
- const call_details cd (get_call_details (model, ctxt));
- model->update_for_int_cst_return (cd, -1, true);
- return true;
- }
- };
-
- class success : public success_call_info
- {
- public:
- success (const call_details &cd) : success_call_info (cd) {}
-
- bool update_model (region_model *model,
- const exploded_edge *,
- region_model_context *ctxt) const final override
- {
- const call_details cd (get_call_details (model, ctxt));
-
- /* Return 0. */
- model->update_for_zero_return (cd, true);
-
- /* Update fd array. */
- region_model_manager *mgr = cd.get_manager ();
- tree arr_tree = cd.get_arg_tree (0);
- const svalue *arr_sval = cd.get_arg_svalue (0);
- for (int idx = 0; idx < 2; idx++)
- {
- const region *arr_reg
- = model->deref_rvalue (arr_sval, arr_tree, cd.get_ctxt ());
- const svalue *idx_sval
- = mgr->get_or_create_int_cst (integer_type_node, idx);
- const region *element_reg
- = mgr->get_element_region (arr_reg, integer_type_node, idx_sval);
- conjured_purge p (model, cd.get_ctxt ());
- const svalue *fd_sval
- = mgr->get_or_create_conjured_svalue (integer_type_node,
- cd.get_call_stmt (),
- element_reg,
- p);
- model->set_value (element_reg, fd_sval, cd.get_ctxt ());
- model->mark_as_valid_fd (fd_sval, cd.get_ctxt ());
-
- }
- return true;
- }
- };
-
- /* Body of region_model::impl_call_pipe. */
- if (cd.get_ctxt ())
- {
- cd.get_ctxt ()->bifurcate (new failure (cd));
- cd.get_ctxt ()->bifurcate (new success (cd));
- cd.get_ctxt ()->terminate_path ();
- }
-}
-
-/* A subclass of pending_diagnostic for complaining about 'putenv'
- called on an auto var. */
-
-class putenv_of_auto_var
-: public pending_diagnostic_subclass<putenv_of_auto_var>
-{
-public:
- putenv_of_auto_var (tree fndecl, const region *reg)
- : m_fndecl (fndecl), m_reg (reg),
- m_var_decl (reg->get_base_region ()->maybe_get_decl ())
- {
- }
-
- const char *get_kind () const final override
- {
- return "putenv_of_auto_var";
- }
-
- bool operator== (const putenv_of_auto_var &other) const
- {
- return (m_fndecl == other.m_fndecl
- && m_reg == other.m_reg
- && same_tree_p (m_var_decl, other.m_var_decl));
- }
-
- int get_controlling_option () const final override
- {
- return OPT_Wanalyzer_putenv_of_auto_var;
- }
-
- bool emit (rich_location *rich_loc) final override
- {
- auto_diagnostic_group d;
- diagnostic_metadata m;
-
- /* SEI CERT C Coding Standard: "POS34-C. Do not call putenv() with a
- pointer to an automatic variable as the argument". */
- diagnostic_metadata::precanned_rule
- rule ("POS34-C", "https://wiki.sei.cmu.edu/confluence/x/6NYxBQ");
- m.add_rule (rule);
-
- bool warned;
- if (m_var_decl)
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "%qE on a pointer to automatic variable %qE",
- m_fndecl, m_var_decl);
- else
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "%qE on a pointer to an on-stack buffer",
- m_fndecl);
- if (warned)
- {
- if (m_var_decl)
- inform (DECL_SOURCE_LOCATION (m_var_decl),
- "%qE declared on stack here", m_var_decl);
- inform (rich_loc->get_loc (), "perhaps use %qs rather than %qE",
- "setenv", m_fndecl);
- }
-
- return warned;
- }
-
- label_text describe_final_event (const evdesc::final_event &ev) final override
- {
- if (m_var_decl)
- return ev.formatted_print ("%qE on a pointer to automatic variable %qE",
- m_fndecl, m_var_decl);
- else
- return ev.formatted_print ("%qE on a pointer to an on-stack buffer",
- m_fndecl);
- }
-
- void mark_interesting_stuff (interesting_t *interest) final override
- {
- if (!m_var_decl)
- interest->add_region_creation (m_reg->get_base_region ());
- }
-
-private:
- tree m_fndecl; // non-NULL
- const region *m_reg; // non-NULL
- tree m_var_decl; // could be NULL
-};
-
-/* Handle the on_call_pre part of "putenv".
-
- In theory we could try to model the state of the environment variables
- for the process; for now we merely complain about putenv of regions
- on the stack. */
-
-void
-region_model::impl_call_putenv (const call_details &cd)
-{
- tree fndecl = cd.get_fndecl_for_call ();
- gcc_assert (fndecl);
- region_model_context *ctxt = cd.get_ctxt ();
- const svalue *ptr_sval = cd.get_arg_svalue (0);
- const region *reg = deref_rvalue (ptr_sval, cd.get_arg_tree (0), ctxt);
- m_store.mark_as_escaped (reg);
- enum memory_space mem_space = reg->get_memory_space ();
- switch (mem_space)
- {
- default:
- gcc_unreachable ();
- case MEMSPACE_UNKNOWN:
- case MEMSPACE_CODE:
- case MEMSPACE_GLOBALS:
- case MEMSPACE_HEAP:
- case MEMSPACE_READONLY_DATA:
- break;
- case MEMSPACE_STACK:
- if (ctxt)
- ctxt->warn (new putenv_of_auto_var (fndecl, reg));
- break;
- }
-}
-
-/* Handle the on_call_pre part of "operator new". */
-
-void
-region_model::impl_call_operator_new (const call_details &cd)
-{
- const svalue *size_sval = cd.get_arg_svalue (0);
- const region *new_reg
- = create_region_for_heap_alloc (size_sval, cd.get_ctxt ());
- if (cd.get_lhs_type ())
- {
- const svalue *ptr_sval
- = m_mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
- cd.maybe_set_lhs (ptr_sval);
- }
-}
-
-/* Handle the on_call_pre part of "operator delete", which comes in
- both sized and unsized variants (2 arguments and 1 argument
- respectively). */
-
-void
-region_model::impl_call_operator_delete (const call_details &cd)
-{
- const svalue *ptr_sval = cd.get_arg_svalue (0);
- if (const region *freed_reg = ptr_sval->maybe_get_region ())
- {
- /* If the ptr points to an underlying heap region, delete it,
- poisoning pointers. */
- unbind_region_and_descendents (freed_reg, POISON_KIND_FREED);
- }
-}
-
-/* Handle the on_call_post part of "realloc":
-
- void *realloc(void *ptr, size_t size);
-
- realloc(3) is awkward, since it has various different outcomes
- that are best modelled as separate exploded nodes/edges.
-
- We first check for sm-state, in
- malloc_state_machine::on_realloc_call, so that we
- can complain about issues such as realloc of a non-heap
- pointer, and terminate the path for such cases (and issue
- the complaints at the call's exploded node).
-
- Assuming that these checks pass, we split the path here into
- three special cases (and terminate the "standard" path):
- (A) failure, returning NULL
- (B) success, growing the buffer in-place without moving it
- (C) success, allocating a new buffer, copying the content
- of the old buffer to it, and freeing the old buffer.
-
- Each of these has a custom_edge_info subclass, which updates
- the region_model and sm-state of the destination state. */
-
-void
-region_model::impl_call_realloc (const call_details &cd)
-{
- /* Three custom subclasses of custom_edge_info, for handling the various
- outcomes of "realloc". */
-
- /* Concrete custom_edge_info: a realloc call that fails, returning NULL. */
- class failure : public failed_call_info
- {
- public:
- failure (const call_details &cd)
- : failed_call_info (cd)
- {
- }
-
- bool update_model (region_model *model,
- const exploded_edge *,
- region_model_context *ctxt) const final override
- {
- /* Return NULL; everything else is unchanged. */
- const call_details cd (get_call_details (model, ctxt));
- if (cd.get_lhs_type ())
- {
- const svalue *zero
- = model->m_mgr->get_or_create_int_cst (cd.get_lhs_type (), 0);
- model->set_value (cd.get_lhs_region (),
- zero,
- cd.get_ctxt ());
- }
- return true;
- }
- };
-
- /* Concrete custom_edge_info: a realloc call that succeeds, growing
- the existing buffer without moving it. */
- class success_no_move : public call_info
- {
- public:
- success_no_move (const call_details &cd)
- : call_info (cd)
- {
- }
-
- label_text get_desc (bool can_colorize) const final override
- {
- return make_label_text (can_colorize,
- "when %qE succeeds, without moving buffer",
- get_fndecl ());
- }
-
- bool update_model (region_model *model,
- const exploded_edge *,
- region_model_context *ctxt) const final override
- {
- /* Update size of buffer and return the ptr unchanged. */
- const call_details cd (get_call_details (model, ctxt));
- const svalue *ptr_sval = cd.get_arg_svalue (0);
- const svalue *size_sval = cd.get_arg_svalue (1);
-
- /* We can only grow in place with a non-NULL pointer. */
- {
- const svalue *null_ptr
- = model->m_mgr->get_or_create_int_cst (ptr_sval->get_type (), 0);
- if (!model->add_constraint (ptr_sval, NE_EXPR, null_ptr,
- cd.get_ctxt ()))
- return false;
- }
-
- if (const region *buffer_reg = model->deref_rvalue (ptr_sval, NULL_TREE,
- ctxt))
- if (compat_types_p (size_sval->get_type (), size_type_node))
- model->set_dynamic_extents (buffer_reg, size_sval, ctxt);
- if (cd.get_lhs_region ())
- {
- model->set_value (cd.get_lhs_region (), ptr_sval, cd.get_ctxt ());
- const svalue *zero
- = model->m_mgr->get_or_create_int_cst (cd.get_lhs_type (), 0);
- return model->add_constraint (ptr_sval, NE_EXPR, zero, cd.get_ctxt ());
- }
- else
- return true;
- }
- };
-
- /* Concrete custom_edge_info: a realloc call that succeeds, freeing
- the existing buffer and moving the content to a freshly allocated
- buffer. */
- class success_with_move : public call_info
- {
- public:
- success_with_move (const call_details &cd)
- : call_info (cd)
- {
- }
-
- label_text get_desc (bool can_colorize) const final override
- {
- return make_label_text (can_colorize,
- "when %qE succeeds, moving buffer",
- get_fndecl ());
- }
- bool update_model (region_model *model,
- const exploded_edge *,
- region_model_context *ctxt) const final override
- {
- const call_details cd (get_call_details (model, ctxt));
- const svalue *old_ptr_sval = cd.get_arg_svalue (0);
- const svalue *new_size_sval = cd.get_arg_svalue (1);
-
- /* Create the new region. */
- const region *new_reg
- = model->create_region_for_heap_alloc (new_size_sval, ctxt);
- const svalue *new_ptr_sval
- = model->m_mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
- if (!model->add_constraint (new_ptr_sval, NE_EXPR, old_ptr_sval,
- cd.get_ctxt ()))
- return false;
-
- if (cd.get_lhs_type ())
- cd.maybe_set_lhs (new_ptr_sval);
-
- if (const region *freed_reg = model->deref_rvalue (old_ptr_sval,
- NULL_TREE, ctxt))
- {
- /* Copy the data. */
- const svalue *old_size_sval = model->get_dynamic_extents (freed_reg);
- if (old_size_sval)
- {
- const svalue *copied_size_sval
- = get_copied_size (model, old_size_sval, new_size_sval);
- const region *copied_old_reg
- = model->m_mgr->get_sized_region (freed_reg, NULL,
- copied_size_sval);
- const svalue *buffer_content_sval
- = model->get_store_value (copied_old_reg, cd.get_ctxt ());
- const region *copied_new_reg
- = model->m_mgr->get_sized_region (new_reg, NULL,
- copied_size_sval);
- model->set_value (copied_new_reg, buffer_content_sval,
- cd.get_ctxt ());
- }
- else
- {
- /* We don't know how big the old region was;
- mark the new region as having been touched to avoid uninit
- issues. */
- model->mark_region_as_unknown (new_reg, cd.get_uncertainty ());
- }
-
- /* Free the old region, so that pointers to the old buffer become
- invalid. */
-
- /* If the ptr points to an underlying heap region, delete it,
- poisoning pointers. */
- model->unbind_region_and_descendents (freed_reg, POISON_KIND_FREED);
- model->m_dynamic_extents.remove (freed_reg);
- }
-
- /* Update the sm-state: mark the old_ptr_sval as "freed",
- and the new_ptr_sval as "nonnull". */
- model->on_realloc_with_move (cd, old_ptr_sval, new_ptr_sval);
-
- if (cd.get_lhs_type ())
- {
- const svalue *zero
- = model->m_mgr->get_or_create_int_cst (cd.get_lhs_type (), 0);
- return model->add_constraint (new_ptr_sval, NE_EXPR, zero,
- cd.get_ctxt ());
- }
- else
- return true;
- }
-
- private:
- /* Return the lesser of OLD_SIZE_SVAL and NEW_SIZE_SVAL.
- If unknown, OLD_SIZE_SVAL is returned. */
- const svalue *get_copied_size (region_model *model,
- const svalue *old_size_sval,
- const svalue *new_size_sval) const
- {
- tristate res
- = model->eval_condition (old_size_sval, GT_EXPR, new_size_sval);
- switch (res.get_value ())
- {
- case tristate::TS_TRUE:
- return new_size_sval;
- case tristate::TS_FALSE:
- case tristate::TS_UNKNOWN:
- return old_size_sval;
- default:
- gcc_unreachable ();
- }
- }
- };
-
- /* Body of region_model::impl_call_realloc. */
-
- if (cd.get_ctxt ())
- {
- cd.get_ctxt ()->bifurcate (new failure (cd));
- cd.get_ctxt ()->bifurcate (new success_no_move (cd));
- cd.get_ctxt ()->bifurcate (new success_with_move (cd));
- cd.get_ctxt ()->terminate_path ();
- }
-}
-
-/* Handle the on_call_pre part of "strchr" and "__builtin_strchr". */
-
-void
-region_model::impl_call_strchr (const call_details &cd)
-{
- class strchr_call_info : public call_info
- {
- public:
- strchr_call_info (const call_details &cd, bool found)
- : call_info (cd), m_found (found)
- {
- }
-
- label_text get_desc (bool can_colorize) const final override
- {
- if (m_found)
- return make_label_text (can_colorize,
- "when %qE returns non-NULL",
- get_fndecl ());
- else
- return make_label_text (can_colorize,
- "when %qE returns NULL",
- get_fndecl ());
- }
-
- bool update_model (region_model *model,
- const exploded_edge *,
- region_model_context *ctxt) const final override
- {
- const call_details cd (get_call_details (model, ctxt));
- if (tree lhs_type = cd.get_lhs_type ())
- {
- region_model_manager *mgr = model->get_manager ();
- const svalue *result;
- if (m_found)
- {
- const svalue *str_sval = cd.get_arg_svalue (0);
- const region *str_reg
- = model->deref_rvalue (str_sval, cd.get_arg_tree (0),
- cd.get_ctxt ());
- /* We want str_sval + OFFSET for some unknown OFFSET.
- Use a conjured_svalue to represent the offset,
- using the str_reg as the id of the conjured_svalue. */
- const svalue *offset
- = mgr->get_or_create_conjured_svalue (size_type_node,
- cd.get_call_stmt (),
- str_reg,
- conjured_purge (model,
- ctxt));
- result = mgr->get_or_create_binop (lhs_type, POINTER_PLUS_EXPR,
- str_sval, offset);
- }
- else
- result = mgr->get_or_create_int_cst (lhs_type, 0);
- cd.maybe_set_lhs (result);
- }
- return true;
- }
- private:
- bool m_found;
- };
-
- /* Bifurcate state, creating a "not found" out-edge. */
- if (cd.get_ctxt ())
- cd.get_ctxt ()->bifurcate (new strchr_call_info (cd, false));
-
- /* The "unbifurcated" state is the "found" case. */
- strchr_call_info found (cd, true);
- found.update_model (this, NULL, cd.get_ctxt ());
-}
-
-/* Handle the on_call_pre part of "strcpy" and "__builtin_strcpy_chk". */
-
-void
-region_model::impl_call_strcpy (const call_details &cd)
-{
- const svalue *dest_sval = cd.get_arg_svalue (0);
- const region *dest_reg = deref_rvalue (dest_sval, cd.get_arg_tree (0),
- cd.get_ctxt ());
- const svalue *src_sval = cd.get_arg_svalue (1);
- const region *src_reg = deref_rvalue (src_sval, cd.get_arg_tree (1),
- cd.get_ctxt ());
- const svalue *src_contents_sval = get_store_value (src_reg,
- cd.get_ctxt ());
-
- cd.maybe_set_lhs (dest_sval);
-
- /* Try to get the string size if SRC_REG is a string_region. */
- const svalue *copied_bytes_sval = get_string_size (src_reg);
- /* Otherwise, check if the contents of SRC_REG is a string. */
- if (copied_bytes_sval->get_kind () == SK_UNKNOWN)
- copied_bytes_sval = get_string_size (src_contents_sval);
-
- const region *sized_dest_reg
- = m_mgr->get_sized_region (dest_reg, NULL_TREE, copied_bytes_sval);
- set_value (sized_dest_reg, src_contents_sval, cd.get_ctxt ());
-}
-
-/* Handle the on_call_pre part of "strlen". */
-
-void
-region_model::impl_call_strlen (const call_details &cd)
-{
- region_model_context *ctxt = cd.get_ctxt ();
- const svalue *arg_sval = cd.get_arg_svalue (0);
- const region *buf_reg = deref_rvalue (arg_sval, cd.get_arg_tree (0), ctxt);
- if (const string_region *str_reg
- = buf_reg->dyn_cast_string_region ())
- {
- tree str_cst = str_reg->get_string_cst ();
- /* TREE_STRING_LENGTH is sizeof, not strlen. */
- int sizeof_cst = TREE_STRING_LENGTH (str_cst);
- int strlen_cst = sizeof_cst - 1;
- if (cd.get_lhs_type ())
- {
- tree t_cst = build_int_cst (cd.get_lhs_type (), strlen_cst);
- const svalue *result_sval
- = m_mgr->get_or_create_constant_svalue (t_cst);
- cd.maybe_set_lhs (result_sval);
- return;
- }
- }
- /* Otherwise a conjured value. */
-}
-
-/* Handle calls to functions referenced by
- __attribute__((malloc(FOO))). */
-
-void
-region_model::impl_deallocation_call (const call_details &cd)
-{
- impl_call_free (cd);
-}
-
-} // namespace ana
-
-#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc
index f5999e6..dad7c41 100644
--- a/gcc/analyzer/region-model-manager.cc
+++ b/gcc/analyzer/region-model-manager.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
@@ -73,6 +74,8 @@ region_model_manager::region_model_manager (logger *logger)
m_fndecls_map (), m_labels_map (),
m_globals_region (alloc_region_id (), &m_root_region),
m_globals_map (),
+ m_thread_local_region (alloc_region_id (), &m_root_region),
+ m_errno_region (alloc_region_id (), &m_thread_local_region),
m_store_mgr (this),
m_range_mgr (new bounded_ranges_manager ()),
m_known_fn_mgr (logger)
@@ -234,6 +237,17 @@ region_model_manager::get_or_create_int_cst (tree type, poly_int64 val)
return get_or_create_constant_svalue (tree_cst);
}
+/* Return the svalue * for the constant_svalue for the NULL pointer
+ of POINTER_TYPE, creating it if necessary. */
+
+const svalue *
+region_model_manager::get_or_create_null_ptr (tree pointer_type)
+{
+ gcc_assert (pointer_type);
+ gcc_assert (POINTER_TYPE_P (pointer_type));
+ return get_or_create_int_cst (pointer_type, 0);
+}
+
/* Return the svalue * for a unknown_svalue for TYPE (which can be NULL),
creating it if necessary.
The unknown_svalue instances are reused, based on pointer equality
@@ -610,13 +624,16 @@ region_model_manager::maybe_fold_binop (tree type, enum tree_code op,
case POINTER_PLUS_EXPR:
case PLUS_EXPR:
/* (VAL + 0) -> VAL. */
- if (cst1 && zerop (cst1) && type == arg0->get_type ())
- return arg0;
+ if (cst1 && zerop (cst1))
+ return get_or_create_cast (type, arg0);
break;
case MINUS_EXPR:
/* (VAL - 0) -> VAL. */
- if (cst1 && zerop (cst1) && type == arg0->get_type ())
- return arg0;
+ if (cst1 && zerop (cst1))
+ return get_or_create_cast (type, arg0);
+ /* (0 - VAL) -> -VAL. */
+ if (cst0 && zerop (cst0))
+ return get_or_create_unaryop (type, NEGATE_EXPR, arg1);
break;
case MULT_EXPR:
/* (VAL * 0). */
@@ -1675,11 +1692,22 @@ get_region_for_unexpected_tree_code (region_model_context *ctxt,
return new_reg;
}
-/* Return a new region describing a heap-allocated block of memory. */
+/* Return a region describing a heap-allocated block of memory.
+ Reuse an existing heap_allocated_region is its id is not within
+ BASE_REGS_IN_USE. */
const region *
-region_model_manager::create_region_for_heap_alloc ()
+region_model_manager::
+get_or_create_region_for_heap_alloc (const bitmap &base_regs_in_use)
{
+ /* Try to reuse an existing region, if it's unreferenced in the
+ client state. */
+ for (auto existing_reg : m_managed_dynamic_regions)
+ if (!bitmap_bit_p (base_regs_in_use, existing_reg->get_id ()))
+ if (existing_reg->get_kind () == RK_HEAP_ALLOCATED)
+ return existing_reg;
+
+ /* All existing ones (if any) are in use; create a new one. */
region *reg
= new heap_allocated_region (alloc_region_id (), &m_heap_region);
m_managed_dynamic_regions.safe_push (reg);
diff --git a/gcc/analyzer/region-model-manager.h b/gcc/analyzer/region-model-manager.h
index 3d8f76e..ca9a498 100644
--- a/gcc/analyzer/region-model-manager.h
+++ b/gcc/analyzer/region-model-manager.h
@@ -43,6 +43,7 @@ public:
/* svalue consolidation. */
const svalue *get_or_create_constant_svalue (tree cst_expr);
const svalue *get_or_create_int_cst (tree type, poly_int64);
+ const svalue *get_or_create_null_ptr (tree pointer_type);
const svalue *get_or_create_unknown_svalue (tree type);
const svalue *get_or_create_setjmp_svalue (const setjmp_record &r,
tree type);
@@ -100,6 +101,7 @@ public:
const svalue *create_unique_svalue (tree type);
/* region consolidation. */
+ unsigned get_num_regions () const { return m_next_region_id; }
const stack_region * get_stack_region () const { return &m_stack_region; }
const heap_region *get_heap_region () const { return &m_heap_region; }
const code_region *get_code_region () const { return &m_code_region; }
@@ -107,6 +109,7 @@ public:
{
return &m_globals_region;
}
+ const errno_region *get_errno_region () const { return &m_errno_region; }
const function_region *get_region_for_fndecl (tree fndecl);
const label_region *get_region_for_label (tree label);
const decl_region *get_region_for_global (tree expr);
@@ -151,7 +154,8 @@ public:
/* Dynamically-allocated region instances.
The number of these within the analysis can grow arbitrarily.
They are still owned by the manager. */
- const region *create_region_for_heap_alloc ();
+ const region *
+ get_or_create_region_for_heap_alloc (const bitmap &base_regs_in_use);
const region *create_region_for_alloca (const frame_region *frame);
void log_stats (logger *logger, bool show_objs) const;
@@ -287,6 +291,9 @@ private:
typedef globals_map_t::iterator globals_iterator_t;
globals_map_t m_globals_map;
+ thread_local_region m_thread_local_region;
+ errno_region m_errno_region;
+
consolidation_map<field_region> m_field_regions;
consolidation_map<element_region> m_element_regions;
consolidation_map<offset_region> m_offset_regions;
diff --git a/gcc/analyzer/region-model-reachability.cc b/gcc/analyzer/region-model-reachability.cc
index be1372c..6d2711a 100644
--- a/gcc/analyzer/region-model-reachability.cc
+++ b/gcc/analyzer/region-model-reachability.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 7c44fc9..f6cd34f 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
+#include "make-unique.h"
#include "tree.h"
#include "function.h"
#include "basic-block.h"
@@ -73,6 +74,8 @@ along with GCC; see the file COPYING3. If not see
#include "calls.h"
#include "is-a.h"
#include "gcc-rich-location.h"
+#include "analyzer/checker-event.h"
+#include "analyzer/checker-path.h"
#if ENABLE_ANALYZER
@@ -208,8 +211,9 @@ region_to_value_map::dump (bool simple) const
to OUT.
For now, write (region, value) mappings that are in common between THIS
- and OTHER to OUT, effectively taking the intersection, rather than
- rejecting differences. */
+ and OTHER to OUT, effectively taking the intersection.
+
+ Reject merger of different values. */
bool
region_to_value_map::can_merge_with_p (const region_to_value_map &other,
@@ -221,8 +225,12 @@ region_to_value_map::can_merge_with_p (const region_to_value_map &other,
const svalue *iter_sval = iter.second;
const svalue * const * other_slot = other.get (iter_reg);
if (other_slot)
- if (iter_sval == *other_slot)
- out->put (iter_reg, iter_sval);
+ {
+ if (iter_sval == *other_slot)
+ out->put (iter_reg, iter_sval);
+ else
+ return false;
+ }
}
return true;
}
@@ -813,14 +821,17 @@ region_model::get_gassign_result (const gassign *assign,
if (TREE_CODE (rhs2_cst) == INTEGER_CST)
{
if (tree_int_cst_sgn (rhs2_cst) < 0)
- ctxt->warn (new shift_count_negative_diagnostic
- (assign, rhs2_cst));
+ ctxt->warn
+ (make_unique<shift_count_negative_diagnostic>
+ (assign, rhs2_cst));
else if (compare_tree_int (rhs2_cst,
TYPE_PRECISION (TREE_TYPE (rhs1)))
>= 0)
- ctxt->warn (new shift_count_overflow_diagnostic
- (assign, TYPE_PRECISION (TREE_TYPE (rhs1)),
- rhs2_cst));
+ ctxt->warn
+ (make_unique<shift_count_overflow_diagnostic>
+ (assign,
+ int (TYPE_PRECISION (TREE_TYPE (rhs1))),
+ rhs2_cst));
}
}
@@ -1038,8 +1049,9 @@ region_model::check_for_poison (const svalue *sval,
const region *src_region = NULL;
if (pkind == POISON_KIND_UNINIT)
src_region = get_region_for_poisoned_expr (expr);
- if (ctxt->warn (new poisoned_value_diagnostic (diag_arg, pkind,
- src_region)))
+ if (ctxt->warn (make_unique<poisoned_value_diagnostic> (diag_arg,
+ pkind,
+ src_region)))
{
/* We only want to report use of a poisoned value at the first
place it gets used; return an unknown value to avoid generating
@@ -1154,39 +1166,12 @@ region_model::on_assignment (const gassign *assign, region_model_context *ctxt)
}
}
-/* A pending_diagnostic subclass for implementing "__analyzer_dump_path". */
-
-class dump_path_diagnostic
- : public pending_diagnostic_subclass<dump_path_diagnostic>
-{
-public:
- int get_controlling_option () const final override
- {
- return 0;
- }
-
- bool emit (rich_location *richloc) final override
- {
- inform (richloc, "path");
- return true;
- }
-
- const char *get_kind () const final override { return "dump_path_diagnostic"; }
-
- bool operator== (const dump_path_diagnostic &) const
- {
- return true;
- }
-};
-
/* Handle the pre-sm-state part of STMT, modifying this object in-place.
- Write true to *OUT_TERMINATE_PATH if the path should be terminated.
Write true to *OUT_UNKNOWN_SIDE_EFFECTS if the stmt has unknown
side effects. */
void
region_model::on_stmt_pre (const gimple *stmt,
- bool *out_terminate_path,
bool *out_unknown_side_effects,
region_model_context *ctxt)
{
@@ -1216,51 +1201,7 @@ region_model::on_stmt_pre (const gimple *stmt,
anything, for which we don't have a function body, or for which we
don't know the fndecl. */
const gcall *call = as_a <const gcall *> (stmt);
-
- /* Debugging/test support. */
- if (is_special_named_call_p (call, "__analyzer_describe", 2))
- impl_call_analyzer_describe (call, ctxt);
- else if (is_special_named_call_p (call, "__analyzer_dump_capacity", 1))
- impl_call_analyzer_dump_capacity (call, ctxt);
- else if (is_special_named_call_p (call, "__analyzer_dump_escaped", 0))
- impl_call_analyzer_dump_escaped (call);
- else if (is_special_named_call_p (call, "__analyzer_dump_path", 0))
- {
- /* Handle the builtin "__analyzer_dump_path" by queuing a
- diagnostic at this exploded_node. */
- ctxt->warn (new dump_path_diagnostic ());
- }
- else if (is_special_named_call_p (call, "__analyzer_dump_region_model",
- 0))
- {
- /* Handle the builtin "__analyzer_dump_region_model" by dumping
- the region model's state to stderr. */
- dump (false);
- }
- else if (is_special_named_call_p (call, "__analyzer_eval", 1))
- impl_call_analyzer_eval (call, ctxt);
- else if (is_special_named_call_p (call, "__analyzer_break", 0))
- {
- /* Handle the builtin "__analyzer_break" by triggering a
- breakpoint. */
- /* TODO: is there a good cross-platform way to do this? */
- raise (SIGINT);
- }
- else if (is_special_named_call_p (call,
- "__analyzer_dump_exploded_nodes",
- 1))
- {
- /* This is handled elsewhere. */
- }
- else if (is_special_named_call_p (call, "__analyzer_get_unknown_ptr",
- 0))
- {
- call_details cd (call, this, ctxt);
- impl_call_analyzer_get_unknown_ptr (cd);
- }
- else
- *out_unknown_side_effects = on_call_pre (call, ctxt,
- out_terminate_path);
+ *out_unknown_side_effects = on_call_pre (call, ctxt);
}
break;
@@ -1273,654 +1214,6 @@ region_model::on_stmt_pre (const gimple *stmt,
}
}
-/* Abstract base class for all out-of-bounds warnings with concrete values. */
-
-class out_of_bounds : public pending_diagnostic_subclass<out_of_bounds>
-{
-public:
- out_of_bounds (const region *reg, tree diag_arg,
- byte_range out_of_bounds_range)
- : m_reg (reg), m_diag_arg (diag_arg),
- m_out_of_bounds_range (out_of_bounds_range)
- {}
-
- const char *get_kind () const final override
- {
- return "out_of_bounds_diagnostic";
- }
-
- bool operator== (const out_of_bounds &other) const
- {
- return m_reg == other.m_reg
- && m_out_of_bounds_range == other.m_out_of_bounds_range
- && pending_diagnostic::same_tree_p (m_diag_arg, other.m_diag_arg);
- }
-
- int get_controlling_option () const final override
- {
- return OPT_Wanalyzer_out_of_bounds;
- }
-
- void mark_interesting_stuff (interesting_t *interest) final override
- {
- interest->add_region_creation (m_reg);
- }
-
-protected:
- const region *m_reg;
- tree m_diag_arg;
- byte_range m_out_of_bounds_range;
-};
-
-/* Abstract subclass to complaing about out-of-bounds
- past the end of the buffer. */
-
-class past_the_end : public out_of_bounds
-{
-public:
- past_the_end (const region *reg, tree diag_arg, byte_range range,
- tree byte_bound)
- : out_of_bounds (reg, diag_arg, range), m_byte_bound (byte_bound)
- {}
-
- bool operator== (const past_the_end &other) const
- {
- return out_of_bounds::operator== (other)
- && pending_diagnostic::same_tree_p (m_byte_bound,
- other.m_byte_bound);
- }
-
- label_text
- describe_region_creation_event (const evdesc::region_creation &ev) final
- override
- {
- if (m_byte_bound && TREE_CODE (m_byte_bound) == INTEGER_CST)
- return ev.formatted_print ("capacity is %E bytes", m_byte_bound);
-
- return label_text ();
- }
-
-protected:
- tree m_byte_bound;
-};
-
-/* Concrete subclass to complain about buffer overflows. */
-
-class buffer_overflow : public past_the_end
-{
-public:
- buffer_overflow (const region *reg, tree diag_arg,
- byte_range range, tree byte_bound)
- : past_the_end (reg, diag_arg, range, byte_bound)
- {}
-
- bool emit (rich_location *rich_loc) final override
- {
- diagnostic_metadata m;
- bool warned;
- switch (m_reg->get_memory_space ())
- {
- default:
- m.add_cwe (787);
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "buffer overflow");
- break;
- case MEMSPACE_STACK:
- m.add_cwe (121);
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "stack-based buffer overflow");
- break;
- case MEMSPACE_HEAP:
- m.add_cwe (122);
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "heap-based buffer overflow");
- break;
- }
-
- if (warned)
- {
- char num_bytes_past_buf[WIDE_INT_PRINT_BUFFER_SIZE];
- print_dec (m_out_of_bounds_range.m_size_in_bytes,
- num_bytes_past_buf, UNSIGNED);
- if (m_diag_arg)
- inform (rich_loc->get_loc (), "write is %s bytes past the end"
- " of %qE", num_bytes_past_buf,
- m_diag_arg);
- else
- inform (rich_loc->get_loc (), "write is %s bytes past the end"
- "of the region",
- num_bytes_past_buf);
- }
-
- return warned;
- }
-
- label_text describe_final_event (const evdesc::final_event &ev)
- final override
- {
- byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
- byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
- char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
- print_dec (start, start_buf, SIGNED);
- char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
- print_dec (end, end_buf, SIGNED);
-
- if (start == end)
- {
- if (m_diag_arg)
- return ev.formatted_print ("out-of-bounds write at byte %s but %qE"
- " ends at byte %E", start_buf, m_diag_arg,
- m_byte_bound);
- return ev.formatted_print ("out-of-bounds write at byte %s but region"
- " ends at byte %E", start_buf,
- m_byte_bound);
- }
- else
- {
- if (m_diag_arg)
- return ev.formatted_print ("out-of-bounds write from byte %s till"
- " byte %s but %qE ends at byte %E",
- start_buf, end_buf, m_diag_arg,
- m_byte_bound);
- return ev.formatted_print ("out-of-bounds write from byte %s till"
- " byte %s but region ends at byte %E",
- start_buf, end_buf, m_byte_bound);
- }
- }
-};
-
-/* Concrete subclass to complain about buffer overreads. */
-
-class buffer_overread : public past_the_end
-{
-public:
- buffer_overread (const region *reg, tree diag_arg,
- byte_range range, tree byte_bound)
- : past_the_end (reg, diag_arg, range, byte_bound)
- {}
-
- bool emit (rich_location *rich_loc) final override
- {
- diagnostic_metadata m;
- m.add_cwe (126);
- bool warned = warning_meta (rich_loc, m, get_controlling_option (),
- "buffer overread");
-
- if (warned)
- {
- char num_bytes_past_buf[WIDE_INT_PRINT_BUFFER_SIZE];
- print_dec (m_out_of_bounds_range.m_size_in_bytes,
- num_bytes_past_buf, UNSIGNED);
- if (m_diag_arg)
- inform (rich_loc->get_loc (), "read is %s bytes past the end"
- " of %qE", num_bytes_past_buf,
- m_diag_arg);
- else
- inform (rich_loc->get_loc (), "read is %s bytes past the end"
- "of the region",
- num_bytes_past_buf);
- }
-
- return warned;
- }
-
- label_text describe_final_event (const evdesc::final_event &ev)
- final override
- {
- byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
- byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
- char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
- print_dec (start, start_buf, SIGNED);
- char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
- print_dec (end, end_buf, SIGNED);
-
- if (start == end)
- {
- if (m_diag_arg)
- return ev.formatted_print ("out-of-bounds read at byte %s but %qE"
- " ends at byte %E", start_buf, m_diag_arg,
- m_byte_bound);
- return ev.formatted_print ("out-of-bounds read at byte %s but region"
- " ends at byte %E", start_buf,
- m_byte_bound);
- }
- else
- {
- if (m_diag_arg)
- return ev.formatted_print ("out-of-bounds read from byte %s till"
- " byte %s but %qE ends at byte %E",
- start_buf, end_buf, m_diag_arg,
- m_byte_bound);
- return ev.formatted_print ("out-of-bounds read from byte %s till"
- " byte %s but region ends at byte %E",
- start_buf, end_buf, m_byte_bound);
- }
- }
-};
-
-/* Concrete subclass to complain about buffer underflows. */
-
-class buffer_underflow : public out_of_bounds
-{
-public:
- buffer_underflow (const region *reg, tree diag_arg, byte_range range)
- : out_of_bounds (reg, diag_arg, range)
- {}
-
- bool emit (rich_location *rich_loc) final override
- {
- diagnostic_metadata m;
- m.add_cwe (124);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "buffer underflow");
- }
-
- label_text describe_final_event (const evdesc::final_event &ev)
- final override
- {
- byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
- byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
- char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
- print_dec (start, start_buf, SIGNED);
- char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
- print_dec (end, end_buf, SIGNED);
-
- if (start == end)
- {
- if (m_diag_arg)
- return ev.formatted_print ("out-of-bounds write at byte %s but %qE"
- " starts at byte 0", start_buf,
- m_diag_arg);
- return ev.formatted_print ("out-of-bounds write at byte %s but region"
- " starts at byte 0", start_buf);
- }
- else
- {
- if (m_diag_arg)
- return ev.formatted_print ("out-of-bounds write from byte %s till"
- " byte %s but %qE starts at byte 0",
- start_buf, end_buf, m_diag_arg);
- return ev.formatted_print ("out-of-bounds write from byte %s till"
- " byte %s but region starts at byte 0",
- start_buf, end_buf);;
- }
- }
-};
-
-/* Concrete subclass to complain about buffer underreads. */
-
-class buffer_underread : public out_of_bounds
-{
-public:
- buffer_underread (const region *reg, tree diag_arg, byte_range range)
- : out_of_bounds (reg, diag_arg, range)
- {}
-
- bool emit (rich_location *rich_loc) final override
- {
- diagnostic_metadata m;
- m.add_cwe (127);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "buffer underread");
- }
-
- label_text describe_final_event (const evdesc::final_event &ev)
- final override
- {
- byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
- byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
- char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
- print_dec (start, start_buf, SIGNED);
- char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
- print_dec (end, end_buf, SIGNED);
-
- if (start == end)
- {
- if (m_diag_arg)
- return ev.formatted_print ("out-of-bounds read at byte %s but %qE"
- " starts at byte 0", start_buf,
- m_diag_arg);
- return ev.formatted_print ("out-of-bounds read at byte %s but region"
- " starts at byte 0", start_buf);
- }
- else
- {
- if (m_diag_arg)
- return ev.formatted_print ("out-of-bounds read from byte %s till"
- " byte %s but %qE starts at byte 0",
- start_buf, end_buf, m_diag_arg);
- return ev.formatted_print ("out-of-bounds read from byte %s till"
- " byte %s but region starts at byte 0",
- start_buf, end_buf);;
- }
- }
-};
-
-/* Abstract class to complain about out-of-bounds read/writes where
- the values are symbolic. */
-
-class symbolic_past_the_end
- : public pending_diagnostic_subclass<symbolic_past_the_end>
-{
-public:
- symbolic_past_the_end (const region *reg, tree diag_arg, tree offset,
- tree num_bytes, tree capacity)
- : m_reg (reg), m_diag_arg (diag_arg), m_offset (offset),
- m_num_bytes (num_bytes), m_capacity (capacity)
- {}
-
- const char *get_kind () const final override
- {
- return "symbolic_past_the_end";
- }
-
- bool operator== (const symbolic_past_the_end &other) const
- {
- return m_reg == other.m_reg
- && pending_diagnostic::same_tree_p (m_diag_arg, other.m_diag_arg)
- && pending_diagnostic::same_tree_p (m_offset, other.m_offset)
- && pending_diagnostic::same_tree_p (m_num_bytes, other.m_num_bytes)
- && pending_diagnostic::same_tree_p (m_capacity, other.m_capacity);
- }
-
- int get_controlling_option () const final override
- {
- return OPT_Wanalyzer_out_of_bounds;
- }
-
- void mark_interesting_stuff (interesting_t *interest) final override
- {
- interest->add_region_creation (m_reg);
- }
-
- label_text
- describe_region_creation_event (const evdesc::region_creation &ev) final
- override
- {
- if (m_capacity)
- return ev.formatted_print ("capacity is %qE bytes", m_capacity);
-
- return label_text ();
- }
-
- label_text
- describe_final_event (const evdesc::final_event &ev) final override
- {
- const char *byte_str;
- if (pending_diagnostic::same_tree_p (m_num_bytes, integer_one_node))
- byte_str = "byte";
- else
- byte_str = "bytes";
-
- if (m_offset)
- {
- if (m_num_bytes && TREE_CODE (m_num_bytes) == INTEGER_CST)
- {
- if (m_diag_arg)
- return ev.formatted_print ("%s of %E %s at offset %qE"
- " exceeds %qE", m_dir_str,
- m_num_bytes, byte_str,
- m_offset, m_diag_arg);
- else
- return ev.formatted_print ("%s of %E %s at offset %qE"
- " exceeds the buffer", m_dir_str,
- m_num_bytes, byte_str, m_offset);
- }
- else if (m_num_bytes)
- {
- if (m_diag_arg)
- return ev.formatted_print ("%s of %qE %s at offset %qE"
- " exceeds %qE", m_dir_str,
- m_num_bytes, byte_str,
- m_offset, m_diag_arg);
- else
- return ev.formatted_print ("%s of %qE %s at offset %qE"
- " exceeds the buffer", m_dir_str,
- m_num_bytes, byte_str, m_offset);
- }
- else
- {
- if (m_diag_arg)
- return ev.formatted_print ("%s at offset %qE exceeds %qE",
- m_dir_str, m_offset, m_diag_arg);
- else
- return ev.formatted_print ("%s at offset %qE exceeds the"
- " buffer", m_dir_str, m_offset);
- }
- }
- if (m_diag_arg)
- return ev.formatted_print ("out-of-bounds %s on %qE",
- m_dir_str, m_diag_arg);
- return ev.formatted_print ("out-of-bounds %s", m_dir_str);
- }
-
-protected:
- const region *m_reg;
- tree m_diag_arg;
- tree m_offset;
- tree m_num_bytes;
- tree m_capacity;
- const char *m_dir_str;
-};
-
-/* Concrete subclass to complain about overflows with symbolic values. */
-
-class symbolic_buffer_overflow : public symbolic_past_the_end
-{
-public:
- symbolic_buffer_overflow (const region *reg, tree diag_arg, tree offset,
- tree num_bytes, tree capacity)
- : symbolic_past_the_end (reg, diag_arg, offset, num_bytes, capacity)
- {
- m_dir_str = "write";
- }
-
- bool emit (rich_location *rich_loc) final override
- {
- diagnostic_metadata m;
- switch (m_reg->get_memory_space ())
- {
- default:
- m.add_cwe (787);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "buffer overflow");
- case MEMSPACE_STACK:
- m.add_cwe (121);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "stack-based buffer overflow");
- case MEMSPACE_HEAP:
- m.add_cwe (122);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "heap-based buffer overflow");
- }
- }
-};
-
-/* Concrete subclass to complain about overreads with symbolic values. */
-
-class symbolic_buffer_overread : public symbolic_past_the_end
-{
-public:
- symbolic_buffer_overread (const region *reg, tree diag_arg, tree offset,
- tree num_bytes, tree capacity)
- : symbolic_past_the_end (reg, diag_arg, offset, num_bytes, capacity)
- {
- m_dir_str = "read";
- }
-
- bool emit (rich_location *rich_loc) final override
- {
- diagnostic_metadata m;
- m.add_cwe (126);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "buffer overread");
- }
-};
-
-/* Check whether an access is past the end of the BASE_REG. */
-
-void region_model::check_symbolic_bounds (const region *base_reg,
- const svalue *sym_byte_offset,
- const svalue *num_bytes_sval,
- const svalue *capacity,
- enum access_direction dir,
- region_model_context *ctxt) const
-{
- gcc_assert (ctxt);
-
- const svalue *next_byte
- = m_mgr->get_or_create_binop (num_bytes_sval->get_type (), PLUS_EXPR,
- sym_byte_offset, num_bytes_sval);
-
- if (eval_condition_without_cm (next_byte, GT_EXPR, capacity).is_true ())
- {
- tree diag_arg = get_representative_tree (base_reg);
- tree offset_tree = get_representative_tree (sym_byte_offset);
- tree num_bytes_tree = get_representative_tree (num_bytes_sval);
- tree capacity_tree = get_representative_tree (capacity);
- switch (dir)
- {
- default:
- gcc_unreachable ();
- break;
- case DIR_READ:
- ctxt->warn (new symbolic_buffer_overread (base_reg, diag_arg,
- offset_tree,
- num_bytes_tree,
- capacity_tree));
- break;
- case DIR_WRITE:
- ctxt->warn (new symbolic_buffer_overflow (base_reg, diag_arg,
- offset_tree,
- num_bytes_tree,
- capacity_tree));
- break;
- }
- }
-}
-
-static tree
-maybe_get_integer_cst_tree (const svalue *sval)
-{
- tree cst_tree = sval->maybe_get_constant ();
- if (cst_tree && TREE_CODE (cst_tree) == INTEGER_CST)
- return cst_tree;
-
- return NULL_TREE;
-}
-
-/* May complain when the access on REG is out-of-bounds. */
-
-void
-region_model::check_region_bounds (const region *reg,
- enum access_direction dir,
- region_model_context *ctxt) const
-{
- gcc_assert (ctxt);
-
- /* Get the offset. */
- region_offset reg_offset = reg->get_offset (m_mgr);
- const region *base_reg = reg_offset.get_base_region ();
-
- /* Bail out on symbolic regions.
- (e.g. because the analyzer did not see previous offsets on the latter,
- it might think that a negative access is before the buffer). */
- if (base_reg->symbolic_p ())
- return;
-
- /* Find out how many bytes were accessed. */
- const svalue *num_bytes_sval = reg->get_byte_size_sval (m_mgr);
- tree num_bytes_tree = maybe_get_integer_cst_tree (num_bytes_sval);
- /* Bail out if 0 bytes are accessed. */
- if (num_bytes_tree && zerop (num_bytes_tree))
- return;
-
- /* Get the capacity of the buffer. */
- const svalue *capacity = get_capacity (base_reg);
- tree cst_capacity_tree = maybe_get_integer_cst_tree (capacity);
-
- /* The constant offset from a pointer is represented internally as a sizetype
- but should be interpreted as a signed value here. The statement below
- converts the offset from bits to bytes and then to a signed integer with
- the same precision the sizetype has on the target system.
-
- For example, this is needed for out-of-bounds-3.c test1 to pass when
- compiled with a 64-bit gcc build targeting 32-bit systems. */
- byte_offset_t offset;
- if (!reg_offset.symbolic_p ())
- offset = wi::sext (reg_offset.get_bit_offset () >> LOG2_BITS_PER_UNIT,
- TYPE_PRECISION (size_type_node));
-
- /* If either the offset or the number of bytes accessed are symbolic,
- we have to reason about symbolic values. */
- if (reg_offset.symbolic_p () || !num_bytes_tree)
- {
- const svalue* byte_offset_sval;
- if (!reg_offset.symbolic_p ())
- {
- tree offset_tree = wide_int_to_tree (integer_type_node, offset);
- byte_offset_sval
- = m_mgr->get_or_create_constant_svalue (offset_tree);
- }
- else
- byte_offset_sval = reg_offset.get_symbolic_byte_offset ();
- check_symbolic_bounds (base_reg, byte_offset_sval, num_bytes_sval,
- capacity, dir, ctxt);
- return;
- }
-
- /* Otherwise continue to check with concrete values. */
- byte_range out (0, 0);
- /* NUM_BYTES_TREE should always be interpreted as unsigned. */
- byte_offset_t num_bytes_unsigned = wi::to_offset (num_bytes_tree);
- byte_range read_bytes (offset, num_bytes_unsigned);
- /* If read_bytes has a subset < 0, we do have an underflow. */
- if (read_bytes.falls_short_of_p (0, &out))
- {
- tree diag_arg = get_representative_tree (base_reg);
- switch (dir)
- {
- default:
- gcc_unreachable ();
- break;
- case DIR_READ:
- ctxt->warn (new buffer_underread (reg, diag_arg, out));
- break;
- case DIR_WRITE:
- ctxt->warn (new buffer_underflow (reg, diag_arg, out));
- break;
- }
- }
-
- /* For accesses past the end, we do need a concrete capacity. No need to
- do a symbolic check here because the inequality check does not reason
- whether constants are greater than symbolic values. */
- if (!cst_capacity_tree)
- return;
-
- byte_range buffer (0, wi::to_offset (cst_capacity_tree));
- /* If READ_BYTES exceeds BUFFER, we do have an overflow. */
- if (read_bytes.exceeds_p (buffer, &out))
- {
- tree byte_bound = wide_int_to_tree (size_type_node,
- buffer.get_next_byte_offset ());
- tree diag_arg = get_representative_tree (base_reg);
-
- switch (dir)
- {
- default:
- gcc_unreachable ();
- break;
- case DIR_READ:
- ctxt->warn (new buffer_overread (reg, diag_arg, out, byte_bound));
- break;
- case DIR_WRITE:
- ctxt->warn (new buffer_overflow (reg, diag_arg, out, byte_bound));
- break;
- }
- }
-}
-
/* Ensure that all arguments at the call described by CD are checked
for poisoned values, by calling get_rvalue on each argument. */
@@ -1988,6 +1281,8 @@ region_model::update_for_int_cst_return (const call_details &cd,
{
if (!cd.get_lhs_type ())
return;
+ if (TREE_CODE (cd.get_lhs_type ()) != INTEGER_TYPE)
+ return;
const svalue *result
= m_mgr->get_or_create_int_cst (cd.get_lhs_type (), retval);
if (unmergeable)
@@ -2013,6 +1308,8 @@ region_model::update_for_nonzero_return (const call_details &cd)
{
if (!cd.get_lhs_type ())
return;
+ if (TREE_CODE (cd.get_lhs_type ()) != INTEGER_TYPE)
+ return;
const svalue *zero
= m_mgr->get_or_create_int_cst (cd.get_lhs_type (), 0);
const svalue *result
@@ -2084,13 +1381,28 @@ region_model::maybe_get_copy_bounds (const region *src_reg,
return NULL;
}
-/* Get any known_function for FNDECL, or NULL if there is none. */
+/* Get any known_function for FNDECL for call CD.
+
+ The call must match all assumptions made by the known_function (such as
+ e.g. "argument 1's type must be a pointer type").
+
+ Return NULL if no known_function is found, or it does not match the
+ assumption(s). */
+
+const known_function *
+region_model::get_known_function (tree fndecl, const call_details &cd) const
+{
+ known_function_manager *known_fn_mgr = m_mgr->get_known_function_manager ();
+ return known_fn_mgr->get_match (fndecl, cd);
+}
+
+/* Get any known_function for IFN, or NULL. */
const known_function *
-region_model::get_known_function (tree fndecl) const
+region_model::get_known_function (enum internal_fn ifn) const
{
known_function_manager *known_fn_mgr = m_mgr->get_known_function_manager ();
- return known_fn_mgr->get_by_fndecl (fndecl);
+ return known_fn_mgr->get_internal_fn (ifn);
}
/* Update this model for the CALL stmt, using CTXT to report any
@@ -2102,14 +1414,10 @@ region_model::get_known_function (tree fndecl) const
Return true if the function call has unknown side effects (it wasn't
recognized and we don't have a body for it, or are unable to tell which
- fndecl it is).
-
- Write true to *OUT_TERMINATE_PATH if this execution path should be
- terminated (e.g. the function call terminates the process). */
+ fndecl it is). */
bool
-region_model::on_call_pre (const gcall *call, region_model_context *ctxt,
- bool *out_terminate_path)
+region_model::on_call_pre (const gcall *call, region_model_context *ctxt)
{
call_details cd (call, this, ctxt);
@@ -2153,215 +1461,28 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt,
}
if (gimple_call_internal_p (call))
- {
- switch (gimple_call_internal_fn (call))
- {
- default:
- break;
- case IFN_BUILTIN_EXPECT:
- impl_call_builtin_expect (cd);
- return false;
- case IFN_UBSAN_BOUNDS:
- return false;
- case IFN_VA_ARG:
- impl_call_va_arg (cd);
- return false;
- }
- }
+ if (const known_function *kf
+ = get_known_function (gimple_call_internal_fn (call)))
+ {
+ kf->impl_call_pre (cd);
+ return false;
+ }
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
- to put breakpoints on the handling of specific functions. */
int callee_fndecl_flags = flags_from_decl_or_type (callee_fndecl);
- if (fndecl_built_in_p (callee_fndecl, BUILT_IN_NORMAL)
- && gimple_builtin_call_types_compatible_p (call, callee_fndecl))
- switch (DECL_UNCHECKED_FUNCTION_CODE (callee_fndecl))
- {
- default:
- if (!(callee_fndecl_flags & (ECF_CONST | ECF_PURE)))
- unknown_side_effects = true;
- break;
- case BUILT_IN_ALLOCA:
- case BUILT_IN_ALLOCA_WITH_ALIGN:
- impl_call_alloca (cd);
- return false;
- case BUILT_IN_CALLOC:
- impl_call_calloc (cd);
- return false;
- case BUILT_IN_EXPECT:
- case BUILT_IN_EXPECT_WITH_PROBABILITY:
- impl_call_builtin_expect (cd);
- return false;
- case BUILT_IN_FREE:
- /* Handle in "on_call_post". */
- break;
- case BUILT_IN_MALLOC:
- impl_call_malloc (cd);
- return false;
- case BUILT_IN_MEMCPY:
- case BUILT_IN_MEMCPY_CHK:
- impl_call_memcpy (cd);
- return false;
- case BUILT_IN_MEMSET:
- case BUILT_IN_MEMSET_CHK:
- impl_call_memset (cd);
- return false;
- break;
- case BUILT_IN_REALLOC:
- return false;
- case BUILT_IN_STRCHR:
- impl_call_strchr (cd);
- return false;
- case BUILT_IN_STRCPY:
- case BUILT_IN_STRCPY_CHK:
- impl_call_strcpy (cd);
- return false;
- case BUILT_IN_STRLEN:
- impl_call_strlen (cd);
- return false;
-
- case BUILT_IN_STACK_SAVE:
- case BUILT_IN_STACK_RESTORE:
- return false;
-
- /* Stdio builtins. */
- case BUILT_IN_FPRINTF:
- case BUILT_IN_FPRINTF_UNLOCKED:
- case BUILT_IN_PUTC:
- case BUILT_IN_PUTC_UNLOCKED:
- case BUILT_IN_FPUTC:
- case BUILT_IN_FPUTC_UNLOCKED:
- case BUILT_IN_FPUTS:
- case BUILT_IN_FPUTS_UNLOCKED:
- case BUILT_IN_FWRITE:
- case BUILT_IN_FWRITE_UNLOCKED:
- case BUILT_IN_PRINTF:
- case BUILT_IN_PRINTF_UNLOCKED:
- case BUILT_IN_PUTCHAR:
- case BUILT_IN_PUTCHAR_UNLOCKED:
- case BUILT_IN_PUTS:
- case BUILT_IN_PUTS_UNLOCKED:
- case BUILT_IN_VFPRINTF:
- case BUILT_IN_VPRINTF:
- /* These stdio builtins have external effects that are out
- of scope for the analyzer: we only want to model the effects
- on the return value. */
- break;
-
- case BUILT_IN_VA_START:
- impl_call_va_start (cd);
- return false;
- case BUILT_IN_VA_COPY:
- impl_call_va_copy (cd);
- return false;
- }
- else if (is_named_call_p (callee_fndecl, "malloc", call, 1))
- {
- impl_call_malloc (cd);
- return false;
- }
- else if (is_named_call_p (callee_fndecl, "calloc", call, 2))
+ if (const known_function *kf = get_known_function (callee_fndecl, cd))
{
- impl_call_calloc (cd);
- return false;
- }
- else if (is_named_call_p (callee_fndecl, "alloca", call, 1))
- {
- impl_call_alloca (cd);
- return false;
- }
- else if (is_named_call_p (callee_fndecl, "realloc", call, 2))
- {
- impl_call_realloc (cd);
+ kf->impl_call_pre (cd);
return false;
}
- else if (is_named_call_p (callee_fndecl, "error"))
- {
- if (impl_call_error (cd, 3, out_terminate_path))
- return false;
- else
- unknown_side_effects = true;
- }
- else if (is_named_call_p (callee_fndecl, "error_at_line"))
+ else if (fndecl_built_in_p (callee_fndecl, BUILT_IN_NORMAL)
+ && gimple_builtin_call_types_compatible_p (call, callee_fndecl))
{
- if (impl_call_error (cd, 5, out_terminate_path))
- return false;
- else
+ if (!(callee_fndecl_flags & (ECF_CONST | ECF_PURE)))
unknown_side_effects = true;
}
- else if (is_named_call_p (callee_fndecl, "fgets", call, 3)
- || is_named_call_p (callee_fndecl, "fgets_unlocked", call, 3))
- {
- impl_call_fgets (cd);
- return false;
- }
- else if (is_named_call_p (callee_fndecl, "fread", call, 4))
- {
- impl_call_fread (cd);
- return false;
- }
- else if (is_named_call_p (callee_fndecl, "getchar", call, 0))
- {
- /* No side-effects (tracking stream state is out-of-scope
- for the analyzer). */
- }
- else if (is_named_call_p (callee_fndecl, "memset", call, 3)
- && POINTER_TYPE_P (cd.get_arg_type (0)))
- {
- impl_call_memset (cd);
- return false;
- }
- else if (is_named_call_p (callee_fndecl, "pipe", call, 1)
- || is_named_call_p (callee_fndecl, "pipe2", call, 2))
- {
- /* Handle in "on_call_post"; bail now so that fd array
- is left untouched so that we can detect use-of-uninit
- for the case where the call fails. */
- return false;
- }
- else if (is_named_call_p (callee_fndecl, "putenv", call, 1)
- && POINTER_TYPE_P (cd.get_arg_type (0)))
- {
- impl_call_putenv (cd);
- return false;
- }
- else if (is_named_call_p (callee_fndecl, "strchr", call, 2)
- && POINTER_TYPE_P (cd.get_arg_type (0)))
- {
- impl_call_strchr (cd);
- return false;
- }
- else if (is_named_call_p (callee_fndecl, "strlen", call, 1)
- && POINTER_TYPE_P (cd.get_arg_type (0)))
- {
- impl_call_strlen (cd);
- return false;
- }
- else if (is_named_call_p (callee_fndecl, "operator new", call, 1))
- {
- impl_call_operator_new (cd);
- return false;
- }
- else if (is_named_call_p (callee_fndecl, "operator new []", call, 1))
- {
- impl_call_operator_new (cd);
- return false;
- }
- else if (is_named_call_p (callee_fndecl, "operator delete", call, 1)
- || is_named_call_p (callee_fndecl, "operator delete", call, 2)
- || is_named_call_p (callee_fndecl, "operator delete []", call, 1))
- {
- /* Handle in "on_call_post". */
- }
- else if (const known_function *kf = get_known_function (callee_fndecl))
- {
- kf->impl_call_pre (cd);
- return false;
- }
else if (!fndecl_has_gimple_body_p (callee_fndecl)
&& (!(callee_fndecl_flags & (ECF_CONST | ECF_PURE)))
&& !fndecl_built_in_p (callee_fndecl))
@@ -2391,22 +1512,9 @@ region_model::on_call_post (const gcall *call,
if (tree callee_fndecl = get_fndecl_for_call (call, ctxt))
{
call_details cd (call, this, ctxt);
- if (is_named_call_p (callee_fndecl, "free", call, 1))
+ if (const known_function *kf = get_known_function (callee_fndecl, cd))
{
- impl_call_free (cd);
- return;
- }
- if (is_named_call_p (callee_fndecl, "operator delete", call, 1)
- || is_named_call_p (callee_fndecl, "operator delete", call, 2)
- || is_named_call_p (callee_fndecl, "operator delete []", call, 1))
- {
- impl_call_operator_delete (cd);
- return;
- }
- else if (is_named_call_p (callee_fndecl, "pipe", call, 1)
- || is_named_call_p (callee_fndecl, "pipe2", call, 2))
- {
- impl_call_pipe (cd);
+ kf->impl_call_post (cd);
return;
}
/* Was this fndecl referenced by
@@ -2416,20 +1524,6 @@ region_model::on_call_post (const gcall *call,
impl_deallocation_call (cd);
return;
}
- if (fndecl_built_in_p (callee_fndecl, BUILT_IN_NORMAL)
- && gimple_builtin_call_types_compatible_p (call, callee_fndecl))
- switch (DECL_UNCHECKED_FUNCTION_CODE (callee_fndecl))
- {
- default:
- break;
- case BUILT_IN_REALLOC:
- impl_call_realloc (cd);
- return;
-
- case BUILT_IN_VA_END:
- impl_call_va_end (cd);
- return;
- }
}
if (unknown_side_effects)
@@ -2564,9 +1658,10 @@ check_external_function_for_access_attr (const gcall *call,
m_access (access)
{
}
- pending_note *make_note () final override
+ std::unique_ptr<pending_note> make_note () final override
{
- return new reason_attr_access (m_callee_fndecl, m_access);
+ return make_unique<reason_attr_access>
+ (m_callee_fndecl, m_access);
}
private:
tree m_callee_fndecl;
@@ -3226,6 +2321,10 @@ const svalue *
region_model::get_store_value (const region *reg,
region_model_context *ctxt) const
{
+ /* Getting the value of an empty region gives an unknown_svalue. */
+ if (reg->empty_p ())
+ return m_mgr->get_or_create_unknown_svalue (reg->get_type ());
+
check_region_for_read (reg, ctxt);
/* Special-case: handle var_decls in the constant pool. */
@@ -3374,7 +2473,8 @@ region_model::deref_rvalue (const svalue *ptr_sval, tree ptr_tree,
const poisoned_svalue *poisoned_sval
= as_a <const poisoned_svalue *> (ptr_sval);
enum poison_kind pkind = poisoned_sval->get_poison_kind ();
- ctxt->warn (new poisoned_value_diagnostic (ptr, pkind, NULL));
+ ctxt->warn (make_unique<poisoned_value_diagnostic>
+ (ptr, pkind, NULL));
}
}
}
@@ -3531,14 +2631,16 @@ region_model::check_for_writable_region (const region* dest_reg,
{
const function_region *func_reg = as_a <const function_region *> (base_reg);
tree fndecl = func_reg->get_fndecl ();
- ctxt->warn (new write_to_const_diagnostic (func_reg, fndecl));
+ ctxt->warn (make_unique<write_to_const_diagnostic>
+ (func_reg, fndecl));
}
break;
case RK_LABEL:
{
const label_region *label_reg = as_a <const label_region *> (base_reg);
tree label = label_reg->get_label ();
- ctxt->warn (new write_to_const_diagnostic (label_reg, label));
+ ctxt->warn (make_unique<write_to_const_diagnostic>
+ (label_reg, label));
}
break;
case RK_DECL:
@@ -3551,11 +2653,11 @@ region_model::check_for_writable_region (const region* dest_reg,
"this" param is "T* const"). */
if (TREE_READONLY (decl)
&& is_global_var (decl))
- ctxt->warn (new write_to_const_diagnostic (dest_reg, decl));
+ ctxt->warn (make_unique<write_to_const_diagnostic> (dest_reg, decl));
}
break;
case RK_STRING:
- ctxt->warn (new write_to_string_literal_diagnostic (dest_reg));
+ ctxt->warn (make_unique<write_to_string_literal_diagnostic> (dest_reg));
break;
}
}
@@ -3681,12 +2783,14 @@ class dubious_allocation_size
{
public:
dubious_allocation_size (const region *lhs, const region *rhs)
- : m_lhs (lhs), m_rhs (rhs), m_expr (NULL_TREE)
+ : m_lhs (lhs), m_rhs (rhs), m_expr (NULL_TREE),
+ m_has_allocation_event (false)
{}
dubious_allocation_size (const region *lhs, const region *rhs,
tree expr)
- : m_lhs (lhs), m_rhs (rhs), m_expr (expr)
+ : m_lhs (lhs), m_rhs (rhs), m_expr (expr),
+ m_has_allocation_event (false)
{}
const char *get_kind () const final override
@@ -3715,34 +2819,17 @@ public:
" of the pointee's size");
}
- label_text
- describe_region_creation_event (const evdesc::region_creation &ev) final
- override
- {
- m_allocation_event = &ev;
- if (m_expr)
- {
- if (TREE_CODE (m_expr) == INTEGER_CST)
- return ev.formatted_print ("allocated %E bytes here", m_expr);
- else
- return ev.formatted_print ("allocated %qE bytes here", m_expr);
- }
-
- return ev.formatted_print ("allocated here");
- }
-
label_text describe_final_event (const evdesc::final_event &ev) final
override
{
tree pointee_type = TREE_TYPE (m_lhs->get_type ());
- if (m_allocation_event)
- /* Fallback: Typically, we should always
- see an m_allocation_event before. */
+ if (m_has_allocation_event)
return ev.formatted_print ("assigned to %qT here;"
" %<sizeof (%T)%> is %qE",
m_lhs->get_type (), pointee_type,
size_in_bytes (pointee_type));
-
+ /* Fallback: Typically, we should always see an allocation_event
+ before. */
if (m_expr)
{
if (TREE_CODE (m_expr) == INTEGER_CST)
@@ -3763,6 +2850,18 @@ public:
size_in_bytes (pointee_type));
}
+ void
+ add_region_creation_events (const region *,
+ tree capacity,
+ const event_loc_info &loc_info,
+ checker_path &emission_path) final override
+ {
+ emission_path.add_event
+ (make_unique<region_creation_event_allocation_size> (capacity, loc_info));
+
+ m_has_allocation_event = true;
+ }
+
void mark_interesting_stuff (interesting_t *interest) final override
{
interest->add_region_creation (m_rhs);
@@ -3772,7 +2871,7 @@ private:
const region *m_lhs;
const region *m_rhs;
const tree m_expr;
- const evdesc::region_creation *m_allocation_event;
+ bool m_has_allocation_event;
};
/* Return true on dubious allocation sizes for constant sizes. */
@@ -4031,8 +3130,8 @@ region_model::check_region_size (const region *lhs_reg, const svalue *rhs_sval,
if (TREE_CODE (cst_cap) == INTEGER_CST
&& !capacity_compatible_with_type (cst_cap, pointee_size_tree,
is_struct))
- ctxt->warn (new dubious_allocation_size (lhs_reg, rhs_reg,
- cst_cap));
+ ctxt->warn (make_unique <dubious_allocation_size> (lhs_reg, rhs_reg,
+ cst_cap));
}
break;
default:
@@ -4043,8 +3142,9 @@ region_model::check_region_size (const region *lhs_reg, const svalue *rhs_sval,
if (!v.get_result ())
{
tree expr = get_representative_tree (capacity);
- ctxt->warn (new dubious_allocation_size (lhs_reg, rhs_reg,
- expr));
+ ctxt->warn (make_unique <dubious_allocation_size> (lhs_reg,
+ rhs_reg,
+ expr));
}
}
break;
@@ -4063,6 +3163,10 @@ region_model::set_value (const region *lhs_reg, const svalue *rhs_sval,
gcc_assert (lhs_reg);
gcc_assert (rhs_sval);
+ /* Setting the value of an empty region is a no-op. */
+ if (lhs_reg->empty_p ())
+ return;
+
check_region_size (lhs_reg, rhs_sval, ctxt);
check_region_for_write (lhs_reg, ctxt);
@@ -4133,43 +3237,17 @@ region_model::eval_condition (const svalue *lhs,
enum tree_code op,
const svalue *rhs) const
{
- /* For now, make no attempt to capture constraints on floating-point
- values. */
- if ((lhs->get_type () && FLOAT_TYPE_P (lhs->get_type ()))
- || (rhs->get_type () && FLOAT_TYPE_P (rhs->get_type ())))
- return tristate::unknown ();
-
- tristate ts = eval_condition_without_cm (lhs, op, rhs);
- if (ts.is_known ())
- return ts;
-
- /* Otherwise, try constraints. */
- return m_constraints->eval_condition (lhs, op, rhs);
-}
-
-/* Determine what is known about the condition "LHS_SVAL OP RHS_SVAL" within
- this model, without resorting to the constraint_manager.
-
- This is exposed so that impl_region_model_context::on_state_leak can
- check for equality part-way through region_model::purge_unused_svalues
- without risking creating new ECs. */
-
-tristate
-region_model::eval_condition_without_cm (const svalue *lhs,
- enum tree_code op,
- const svalue *rhs) const
-{
gcc_assert (lhs);
gcc_assert (rhs);
- /* See what we know based on the values. */
-
/* For now, make no attempt to capture constraints on floating-point
values. */
if ((lhs->get_type () && FLOAT_TYPE_P (lhs->get_type ()))
|| (rhs->get_type () && FLOAT_TYPE_P (rhs->get_type ())))
return tristate::unknown ();
+ /* See what we know based on the values. */
+
/* Unwrap any unmergeable values. */
lhs = lhs->unwrap_any_unmergeable ();
rhs = rhs->unwrap_any_unmergeable ();
@@ -4263,9 +3341,20 @@ region_model::eval_condition_without_cm (const svalue *lhs,
shouldn't warn for. */
if (binop->get_op () == POINTER_PLUS_EXPR)
{
- tristate lhs_ts
- = eval_condition_without_cm (binop->get_arg0 (),
- op, rhs);
+ tristate lhs_ts = eval_condition (binop->get_arg0 (), op, rhs);
+ if (lhs_ts.is_known ())
+ return lhs_ts;
+ }
+ }
+ else if (const unaryop_svalue *unaryop
+ = lhs->dyn_cast_unaryop_svalue ())
+ {
+ if (unaryop->get_op () == NEGATE_EXPR)
+ {
+ /* e.g. "-X <= 0" is equivalent to X >= 0". */
+ tristate lhs_ts = eval_condition (unaryop->get_arg (),
+ swap_tree_comparison (op),
+ rhs);
if (lhs_ts.is_known ())
return lhs_ts;
}
@@ -4298,7 +3387,7 @@ region_model::eval_condition_without_cm (const svalue *lhs,
}
/* Handle comparisons between two svalues with more than one operand. */
- if (const binop_svalue *binop = lhs->dyn_cast_binop_svalue ())
+ if (const binop_svalue *binop = lhs->dyn_cast_binop_svalue ())
{
switch (op)
{
@@ -4340,10 +3429,14 @@ region_model::eval_condition_without_cm (const svalue *lhs,
}
}
- return tristate::TS_UNKNOWN;
+ /* Otherwise, try constraints.
+ Cast to const to ensure we don't change the constraint_manager as we
+ do this (e.g. by creating equivalence classes). */
+ const constraint_manager *constraints = m_constraints;
+ return constraints->eval_condition (lhs, op, rhs);
}
-/* Subroutine of region_model::eval_condition_without_cm, for rejecting
+/* Subroutine of region_model::eval_condition, for rejecting
equality of INIT_VAL(PARM) with &LOCAL. */
tristate
@@ -4395,18 +3488,18 @@ region_model::symbolic_greater_than (const binop_svalue *bin_a,
/* Eliminate the right-hand side of both svalues. */
if (const binop_svalue *bin_b = dyn_cast <const binop_svalue *> (b))
if (bin_a->get_op () == bin_b->get_op ()
- && eval_condition_without_cm (bin_a->get_arg1 (),
- GT_EXPR,
- bin_b->get_arg1 ()).is_true ()
- && eval_condition_without_cm (bin_a->get_arg0 (),
- GE_EXPR,
- bin_b->get_arg0 ()).is_true ())
+ && eval_condition (bin_a->get_arg1 (),
+ GT_EXPR,
+ bin_b->get_arg1 ()).is_true ()
+ && eval_condition (bin_a->get_arg0 (),
+ GE_EXPR,
+ bin_b->get_arg0 ()).is_true ())
return tristate (tristate::TS_TRUE);
/* Otherwise, try to remove a positive offset or factor from BIN_A. */
if (is_positive_svalue (bin_a->get_arg1 ())
- && eval_condition_without_cm (bin_a->get_arg0 (),
- GE_EXPR, b).is_true ())
+ && eval_condition (bin_a->get_arg0 (),
+ GE_EXPR, b).is_true ())
return tristate (tristate::TS_TRUE);
}
return tristate::unknown ();
@@ -4684,7 +3777,7 @@ tristate
region_model::eval_condition (tree lhs,
enum tree_code op,
tree rhs,
- region_model_context *ctxt)
+ region_model_context *ctxt) const
{
/* For now, make no attempt to model constraints on floating-point
values. */
@@ -4853,6 +3946,7 @@ region_model::get_representative_path_var_1 (const region *reg,
case RK_CODE:
case RK_HEAP:
case RK_STACK:
+ case RK_THREAD_LOCAL:
case RK_ROOT:
/* Regions that represent memory spaces are not expressible as trees. */
return path_var (NULL_TREE, 0);
@@ -4972,6 +4066,7 @@ region_model::get_representative_path_var_1 (const region *reg,
}
case RK_VAR_ARG:
+ case RK_ERRNO:
case RK_UNKNOWN:
return path_var (NULL_TREE, 0);
}
@@ -5298,11 +4393,13 @@ region_model::apply_constraints_for_exception (const gimple *last_stmt,
PARAM has a defined but unknown initial value.
Anything it points to has escaped, since the calling context "knows"
the pointer, and thus calls to unknown functions could read/write into
- the region. */
+ the region.
+ If NONNULL is true, then assume that PARAM must be non-NULL. */
void
region_model::on_top_level_param (tree param,
- region_model_context *ctxt)
+ bool nonnull,
+ region_model_context *ctxt)
{
if (POINTER_TYPE_P (TREE_TYPE (param)))
{
@@ -5311,6 +4408,12 @@ region_model::on_top_level_param (tree param,
= m_mgr->get_or_create_initial_value (param_reg);
const region *pointee_reg = m_mgr->get_symbolic_region (init_ptr_sval);
m_store.mark_as_escaped (pointee_reg);
+ if (nonnull)
+ {
+ const svalue *null_ptr_sval
+ = m_mgr->get_or_create_null_ptr (TREE_TYPE (param));
+ add_constraint (init_ptr_sval, NE_EXPR, null_ptr_sval, ctxt);
+ }
}
}
@@ -5366,14 +4469,27 @@ region_model::push_frame (function *fun, const vec<const svalue *> *arg_svals,
have defined but unknown initial values.
Anything they point to has escaped. */
tree fndecl = fun->decl;
+
+ /* Handle "__attribute__((nonnull))". */
+ tree fntype = TREE_TYPE (fndecl);
+ bitmap nonnull_args = get_nonnull_args (fntype);
+
+ unsigned parm_idx = 0;
for (tree iter_parm = DECL_ARGUMENTS (fndecl); iter_parm;
iter_parm = DECL_CHAIN (iter_parm))
{
+ bool non_null = (nonnull_args
+ ? (bitmap_empty_p (nonnull_args)
+ || bitmap_bit_p (nonnull_args, parm_idx))
+ : false);
if (tree parm_default_ssa = ssa_default_def (fun, iter_parm))
- on_top_level_param (parm_default_ssa, ctxt);
+ on_top_level_param (parm_default_ssa, non_null, ctxt);
else
- on_top_level_param (iter_parm, ctxt);
+ on_top_level_param (iter_parm, non_null, ctxt);
+ parm_idx++;
}
+
+ BITMAP_FREE (nonnull_args);
}
return m_current_frame;
@@ -5409,8 +4525,13 @@ region_model::pop_frame (tree result_lvalue,
{
gcc_assert (m_current_frame);
- /* Evaluate the result, within the callee frame. */
const frame_region *frame_reg = m_current_frame;
+
+ /* Notify state machines. */
+ if (ctxt)
+ ctxt->on_pop_frame (frame_reg);
+
+ /* Evaluate the result, within the callee frame. */
tree fndecl = m_current_frame->get_function ()->decl;
tree result = DECL_RESULT (fndecl);
const svalue *retval = NULL;
@@ -5766,23 +4887,56 @@ region_model::check_dynamic_size_for_floats (const svalue *size_in_bytes,
if (const svalue *float_sval = v.get_svalue_to_report ())
{
tree diag_arg = get_representative_tree (float_sval);
- ctxt->warn (new float_as_size_arg (diag_arg));
+ ctxt->warn (make_unique<float_as_size_arg> (diag_arg));
}
}
-/* Return a new region describing a heap-allocated block of memory.
- Use CTXT to complain about tainted sizes. */
+/* Return a region describing a heap-allocated block of memory.
+ Use CTXT to complain about tainted sizes.
+
+ Reuse an existing heap_allocated_region if it's not being referenced by
+ this region_model; otherwise create a new one. */
const region *
-region_model::create_region_for_heap_alloc (const svalue *size_in_bytes,
- region_model_context *ctxt)
-{
- const region *reg = m_mgr->create_region_for_heap_alloc ();
+region_model::get_or_create_region_for_heap_alloc (const svalue *size_in_bytes,
+ region_model_context *ctxt)
+{
+ /* Determine which regions are referenced in this region_model, so that
+ we can reuse an existing heap_allocated_region if it's not in use on
+ this path. */
+ auto_bitmap base_regs_in_use;
+ get_referenced_base_regions (base_regs_in_use);
+ const region *reg
+ = m_mgr->get_or_create_region_for_heap_alloc (base_regs_in_use);
if (compat_types_p (size_in_bytes->get_type (), size_type_node))
set_dynamic_extents (reg, size_in_bytes, ctxt);
return reg;
}
+/* Populate OUT_IDS with the set of IDs of those base regions which are
+ reachable in this region_model. */
+
+void
+region_model::get_referenced_base_regions (auto_bitmap &out_ids) const
+{
+ reachable_regions reachable_regs (const_cast<region_model *> (this));
+ m_store.for_each_cluster (reachable_regions::init_cluster_cb,
+ &reachable_regs);
+ /* Get regions for locals that have explicitly bound values. */
+ for (store::cluster_map_t::iterator iter = m_store.begin ();
+ iter != m_store.end (); ++iter)
+ {
+ const region *base_reg = (*iter).first;
+ if (const region *parent = base_reg->get_parent_region ())
+ if (parent->get_kind () == RK_FRAME)
+ reachable_regs.add (base_reg, false);
+ }
+
+ bitmap_clear (out_ids);
+ for (auto iter_reg : reachable_regs)
+ bitmap_set_bit (out_ids, iter_reg->get_id ());
+}
+
/* Return a new region describing a block of memory allocated within the
current frame.
Use CTXT to complain about tainted sizes. */
@@ -6389,23 +5543,38 @@ region_model::maybe_complain_about_infoleak (const region *dst_reg,
{
/* Check for exposure. */
if (contains_uninit_p (copied_sval))
- ctxt->warn (new exposure_through_uninit_copy (src_reg,
- dst_reg,
- copied_sval));
+ ctxt->warn (make_unique<exposure_through_uninit_copy> (src_reg,
+ dst_reg,
+ copied_sval));
+}
+
+/* Set errno to a positive symbolic int, as if some error has occurred. */
+
+void
+region_model::set_errno (const call_details &cd)
+{
+ const region *errno_reg = m_mgr->get_errno_region ();
+ conjured_purge p (this, cd.get_ctxt ());
+ const svalue *new_errno_sval
+ = m_mgr->get_or_create_conjured_svalue (integer_type_node,
+ cd.get_call_stmt (),
+ errno_reg, p);
+ const svalue *zero
+ = m_mgr->get_or_create_int_cst (integer_type_node, 0);
+ add_constraint (new_errno_sval, GT_EXPR, zero, cd.get_ctxt ());
+ set_value (errno_reg, new_errno_sval, cd.get_ctxt ());
}
/* class noop_region_model_context : public region_model_context. */
void
-noop_region_model_context::add_note (pending_note *pn)
+noop_region_model_context::add_note (std::unique_ptr<pending_note>)
{
- delete pn;
}
void
-noop_region_model_context::bifurcate (custom_edge_info *info)
+noop_region_model_context::bifurcate (std::unique_ptr<custom_edge_info>)
{
- delete info;
}
void
@@ -7865,7 +7034,7 @@ test_state_merging ()
tree size = build_int_cst (size_type_node, 1024);
const svalue *size_sval = mgr.get_or_create_constant_svalue (size);
const region *new_reg
- = model0.create_region_for_heap_alloc (size_sval, &ctxt);
+ = model0.get_or_create_region_for_heap_alloc (size_sval, &ctxt);
const svalue *ptr_sval = mgr.get_ptr_svalue (ptr_type_node, new_reg);
model0.set_value (model0.get_lvalue (p, &ctxt),
ptr_sval, &ctxt);
@@ -8253,7 +7422,8 @@ test_malloc_constraints ()
const svalue *size_in_bytes
= mgr.get_or_create_unknown_svalue (size_type_node);
- const region *reg = model.create_region_for_heap_alloc (size_in_bytes, NULL);
+ const region *reg
+ = model.get_or_create_region_for_heap_alloc (size_in_bytes, NULL);
const svalue *sval = mgr.get_ptr_svalue (ptr_type_node, reg);
model.set_value (model.get_lvalue (p, NULL), sval, NULL);
model.set_value (q, p, NULL);
@@ -8482,7 +7652,8 @@ test_malloc ()
/* "p = malloc (n * 4);". */
const svalue *size_sval = model.get_rvalue (n_times_4, &ctxt);
- const region *reg = model.create_region_for_heap_alloc (size_sval, &ctxt);
+ const region *reg
+ = model.get_or_create_region_for_heap_alloc (size_sval, &ctxt);
const svalue *ptr = mgr.get_ptr_svalue (int_star, reg);
model.set_value (model.get_lvalue (p, &ctxt), ptr, &ctxt);
ASSERT_EQ (model.get_capacity (reg), size_sval);
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 19e8043..626b10d 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -26,11 +26,13 @@ along with GCC; see the file COPYING3. If not see
(Zhongxing Xu, Ted Kremenek, and Jian Zhang)
http://lcs.ios.ac.cn/~xuzb/canalyze/memmodel.pdf */
+#include "bitmap.h"
#include "selftest.h"
#include "analyzer/svalue.h"
#include "analyzer/region.h"
#include "analyzer/known-function-manager.h"
#include "analyzer/region-model-manager.h"
+#include "analyzer/pending-diagnostic.h"
using namespace ana;
@@ -234,50 +236,6 @@ public:
struct append_regions_cb_data;
-/* Helper class for handling calls to functions with known behavior.
- Implemented in region-model-impl-calls.c. */
-
-class call_details
-{
-public:
- call_details (const gcall *call, region_model *model,
- region_model_context *ctxt);
-
- region_model *get_model () const { return m_model; }
- region_model_manager *get_manager () const;
- region_model_context *get_ctxt () const { return m_ctxt; }
- logger *get_logger () const;
-
- uncertainty_t *get_uncertainty () const;
- tree get_lhs_type () const { return m_lhs_type; }
- const region *get_lhs_region () const { return m_lhs_region; }
-
- bool maybe_set_lhs (const svalue *result) const;
-
- unsigned num_args () const;
-
- const gcall *get_call_stmt () const { return m_call; }
-
- tree get_arg_tree (unsigned idx) const;
- tree get_arg_type (unsigned idx) const;
- const svalue *get_arg_svalue (unsigned idx) const;
- const char *get_arg_string_literal (unsigned idx) const;
-
- tree get_fndecl_for_call () const;
-
- void dump_to_pp (pretty_printer *pp, bool simple) const;
- void dump (bool simple) const;
-
- const svalue *get_or_create_conjured_svalue (const region *) const;
-
-private:
- const gcall *m_call;
- region_model *m_model;
- region_model_context *m_ctxt;
- tree m_lhs_type;
- const region *m_lhs_region;
-};
-
/* A region_model encapsulates a representation of the state of memory, with
a tree of regions, along with their associated values.
The representation is graph-like because values can be pointers to
@@ -320,7 +278,6 @@ class region_model
void
on_stmt_pre (const gimple *stmt,
- bool *out_terminate_path,
bool *out_unknown_side_effects,
region_model_context *ctxt);
@@ -328,50 +285,15 @@ class region_model
const svalue *get_gassign_result (const gassign *assign,
region_model_context *ctxt);
void on_asm_stmt (const gasm *asm_stmt, region_model_context *ctxt);
- bool on_call_pre (const gcall *stmt, region_model_context *ctxt,
- bool *out_terminate_path);
+ bool on_call_pre (const gcall *stmt, region_model_context *ctxt);
void on_call_post (const gcall *stmt,
bool unknown_side_effects,
region_model_context *ctxt);
void purge_state_involving (const svalue *sval, region_model_context *ctxt);
- /* Specific handling for on_call_pre. */
- void impl_call_alloca (const call_details &cd);
- void impl_call_analyzer_describe (const gcall *call,
- region_model_context *ctxt);
- void impl_call_analyzer_dump_capacity (const gcall *call,
- region_model_context *ctxt);
- void impl_call_analyzer_dump_escaped (const gcall *call);
- void impl_call_analyzer_eval (const gcall *call,
- region_model_context *ctxt);
- void impl_call_analyzer_get_unknown_ptr (const call_details &cd);
- void impl_call_builtin_expect (const call_details &cd);
- void impl_call_calloc (const call_details &cd);
- bool impl_call_error (const call_details &cd, unsigned min_args,
- bool *out_terminate_path);
- void impl_call_fgets (const call_details &cd);
- void impl_call_fread (const call_details &cd);
- void impl_call_free (const call_details &cd);
- void impl_call_malloc (const call_details &cd);
- void impl_call_memcpy (const call_details &cd);
- void impl_call_memset (const call_details &cd);
- void impl_call_pipe (const call_details &cd);
- void impl_call_putenv (const call_details &cd);
- void impl_call_realloc (const call_details &cd);
- void impl_call_strchr (const call_details &cd);
- void impl_call_strcpy (const call_details &cd);
- void impl_call_strlen (const call_details &cd);
- void impl_call_operator_new (const call_details &cd);
- void impl_call_operator_delete (const call_details &cd);
void impl_deallocation_call (const call_details &cd);
- /* Implemented in varargs.cc. */
- void impl_call_va_start (const call_details &cd);
- void impl_call_va_copy (const call_details &cd);
- void impl_call_va_arg (const call_details &cd);
- void impl_call_va_end (const call_details &cd);
-
const svalue *maybe_get_copy_bounds (const region *src_reg,
const svalue *num_bytes_sval);
void update_for_int_cst_return (const call_details &cd,
@@ -448,9 +370,6 @@ class region_model
tristate eval_condition (const svalue *lhs,
enum tree_code op,
const svalue *rhs) const;
- tristate eval_condition_without_cm (const svalue *lhs,
- enum tree_code op,
- const svalue *rhs) const;
tristate compare_initial_and_pointer (const initial_svalue *init,
const region_svalue *ptr) const;
tristate symbolic_greater_than (const binop_svalue *a,
@@ -459,17 +378,19 @@ class region_model
tristate eval_condition (tree lhs,
enum tree_code op,
tree rhs,
- region_model_context *ctxt);
+ region_model_context *ctxt) const;
bool add_constraint (tree lhs, enum tree_code op, tree rhs,
region_model_context *ctxt);
bool add_constraint (tree lhs, enum tree_code op, tree rhs,
region_model_context *ctxt,
rejected_constraint **out);
- const region *create_region_for_heap_alloc (const svalue *size_in_bytes,
- region_model_context *ctxt);
+ const region *
+ get_or_create_region_for_heap_alloc (const svalue *size_in_bytes,
+ region_model_context *ctxt);
const region *create_region_for_alloca (const svalue *size_in_bytes,
region_model_context *ctxt);
+ void get_referenced_base_regions (auto_bitmap &out_ids) const;
tree get_representative_tree (const svalue *sval) const;
tree get_representative_tree (const region *reg) const;
@@ -543,6 +464,8 @@ class region_model
const region *src_reg,
region_model_context *ctxt);
+ void set_errno (const call_details &cd);
+
/* Implemented in sm-fd.cc */
void mark_as_valid_fd (const svalue *sval, region_model_context *ctxt);
@@ -555,7 +478,19 @@ class region_model
void mark_as_tainted (const svalue *sval,
region_model_context *ctxt);
- private:
+ bool add_constraint (const svalue *lhs,
+ enum tree_code op,
+ const svalue *rhs,
+ region_model_context *ctxt);
+
+ const svalue *check_for_poison (const svalue *sval,
+ tree expr,
+ region_model_context *ctxt) const;
+
+ void check_region_for_write (const region *dest_reg,
+ region_model_context *ctxt) const;
+
+private:
const region *get_lvalue_1 (path_var pv, region_model_context *ctxt) const;
const svalue *get_rvalue_1 (path_var pv, region_model_context *ctxt) const;
@@ -566,12 +501,10 @@ class region_model
get_representative_path_var_1 (const region *reg,
svalue_set *visited) const;
- const known_function *get_known_function (tree fndecl) const;
+ const known_function *get_known_function (tree fndecl,
+ const call_details &cd) const;
+ const known_function *get_known_function (enum internal_fn) const;
- 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,
@@ -597,14 +530,13 @@ class region_model
int poison_any_pointers_to_descendents (const region *reg,
enum poison_kind pkind);
- void on_top_level_param (tree param, region_model_context *ctxt);
+ void on_top_level_param (tree param,
+ bool nonnull,
+ region_model_context *ctxt);
bool called_from_main_p () const;
const svalue *get_initial_value_for_global (const region *reg) const;
- const svalue *check_for_poison (const svalue *sval,
- tree expr,
- region_model_context *ctxt) const;
const region * get_region_for_poisoned_expr (tree expr) const;
void check_dynamic_size_for_taint (enum memory_space mem_space,
@@ -622,12 +554,12 @@ class region_model
void check_region_access (const region *reg,
enum access_direction dir,
region_model_context *ctxt) const;
- void check_region_for_write (const region *dest_reg,
- region_model_context *ctxt) const;
void check_region_for_read (const region *src_reg,
region_model_context *ctxt) const;
void check_region_size (const region *lhs_reg, const svalue *rhs_sval,
region_model_context *ctxt) const;
+
+ /* Implemented in bounds-checking.cc */
void check_symbolic_bounds (const region *base_reg,
const svalue *sym_byte_offset,
const svalue *num_bytes_sval,
@@ -671,11 +603,11 @@ class region_model_context
public:
/* Hook for clients to store pending diagnostics.
Return true if the diagnostic was stored, or false if it was deleted. */
- virtual bool warn (pending_diagnostic *d) = 0;
+ virtual bool warn (std::unique_ptr<pending_diagnostic> d) = 0;
- /* Hook for clients to add a note to the last previously stored pending diagnostic.
- Takes ownership of the pending_node (or deletes it). */
- virtual void add_note (pending_note *pn) = 0;
+ /* Hook for clients to add a note to the last previously stored
+ pending diagnostic. */
+ virtual void add_note (std::unique_ptr<pending_note> pn) = 0;
/* Hook for clients to be notified when an SVAL that was reachable
in a previous state is no longer live, so that clients can emit warnings
@@ -707,6 +639,9 @@ class region_model_context
virtual void on_bounded_ranges (const svalue &sval,
const bounded_ranges &ranges) = 0;
+ /* Hook for clients to be notified when a frame is popped from the stack. */
+ virtual void on_pop_frame (const frame_region *) = 0;
+
/* Hooks for clients to be notified when an unknown change happens
to SVAL (in response to a call to an unknown function). */
virtual void on_unknown_change (const svalue *sval, bool is_mutable) = 0;
@@ -728,9 +663,8 @@ class region_model_context
/* Hook for clients to purge state involving SVAL. */
virtual void purge_state_involving (const svalue *sval) = 0;
- /* Hook for clients to split state with a non-standard path.
- Take ownership of INFO. */
- virtual void bifurcate (custom_edge_info *info) = 0;
+ /* Hook for clients to split state with a non-standard path. */
+ virtual void bifurcate (std::unique_ptr<custom_edge_info> info) = 0;
/* Hook for clients to terminate the standard path. */
virtual void terminate_path () = 0;
@@ -739,30 +673,33 @@ class region_model_context
/* Hook for clients to access the a specific state machine in
any underlying program_state. */
- virtual bool get_state_map_by_name (const char *name,
- sm_state_map **out_smap,
- const state_machine **out_sm,
- unsigned *out_sm_idx) = 0;
+ virtual bool
+ get_state_map_by_name (const char *name,
+ sm_state_map **out_smap,
+ const state_machine **out_sm,
+ unsigned *out_sm_idx,
+ std::unique_ptr<sm_context> *out_sm_context) = 0;
/* Precanned ways for clients to access specific state machines. */
bool get_fd_map (sm_state_map **out_smap,
const state_machine **out_sm,
- unsigned *out_sm_idx)
+ unsigned *out_sm_idx,
+ std::unique_ptr<sm_context> *out_sm_context)
{
return get_state_map_by_name ("file-descriptor", out_smap, out_sm,
- out_sm_idx);
+ out_sm_idx, out_sm_context);
}
bool get_malloc_map (sm_state_map **out_smap,
const state_machine **out_sm,
unsigned *out_sm_idx)
{
- return get_state_map_by_name ("malloc", out_smap, out_sm, out_sm_idx);
+ return get_state_map_by_name ("malloc", out_smap, out_sm, out_sm_idx, NULL);
}
bool get_taint_map (sm_state_map **out_smap,
const state_machine **out_sm,
unsigned *out_sm_idx)
{
- return get_state_map_by_name ("taint", out_smap, out_sm, out_sm_idx);
+ return get_state_map_by_name ("taint", out_smap, out_sm, out_sm_idx, NULL);
}
/* Get the current statement, if any. */
@@ -774,8 +711,8 @@ class region_model_context
class noop_region_model_context : public region_model_context
{
public:
- bool warn (pending_diagnostic *) override { return false; }
- void add_note (pending_note *pn) override;
+ bool warn (std::unique_ptr<pending_diagnostic>) override { return false; }
+ void add_note (std::unique_ptr<pending_note>) override;
void on_svalue_leak (const svalue *) override {}
void on_liveness_change (const svalue_set &,
const region_model *) override {}
@@ -789,6 +726,7 @@ public:
const bounded_ranges &) override
{
}
+ void on_pop_frame (const frame_region *) override {}
void on_unknown_change (const svalue *sval ATTRIBUTE_UNUSED,
bool is_mutable ATTRIBUTE_UNUSED) override
{
@@ -805,7 +743,7 @@ public:
void purge_state_involving (const svalue *sval ATTRIBUTE_UNUSED) override {}
- void bifurcate (custom_edge_info *info) override;
+ void bifurcate (std::unique_ptr<custom_edge_info> info) override;
void terminate_path () override;
const extrinsic_state *get_ext_state () const override { return NULL; }
@@ -813,7 +751,8 @@ public:
bool get_state_map_by_name (const char *,
sm_state_map **,
const state_machine **,
- unsigned *) override
+ unsigned *,
+ std::unique_ptr<sm_context> *) override
{
return false;
}
@@ -847,14 +786,14 @@ private:
class region_model_context_decorator : public region_model_context
{
public:
- bool warn (pending_diagnostic *d) override
+ bool warn (std::unique_ptr<pending_diagnostic> d) override
{
- return m_inner->warn (d);
+ return m_inner->warn (std::move (d));
}
- void add_note (pending_note *pn) override
+ void add_note (std::unique_ptr<pending_note> pn) override
{
- m_inner->add_note (pn);
+ m_inner->add_note (std::move (pn));
}
void on_svalue_leak (const svalue *sval) override
@@ -886,6 +825,11 @@ class region_model_context_decorator : public region_model_context
m_inner->on_bounded_ranges (sval, ranges);
}
+ void on_pop_frame (const frame_region *frame_reg) override
+ {
+ m_inner->on_pop_frame (frame_reg);
+ }
+
void on_unknown_change (const svalue *sval, bool is_mutable) override
{
m_inner->on_unknown_change (sval, is_mutable);
@@ -917,9 +861,9 @@ class region_model_context_decorator : public region_model_context
m_inner->purge_state_involving (sval);
}
- void bifurcate (custom_edge_info *info) override
+ void bifurcate (std::unique_ptr<custom_edge_info> info) override
{
- m_inner->bifurcate (info);
+ m_inner->bifurcate (std::move (info));
}
void terminate_path () override
@@ -935,9 +879,12 @@ class region_model_context_decorator : public region_model_context
bool get_state_map_by_name (const char *name,
sm_state_map **out_smap,
const state_machine **out_sm,
- unsigned *out_sm_idx) override
+ unsigned *out_sm_idx,
+ std::unique_ptr<sm_context> *out_sm_context)
+ override
{
- return m_inner->get_state_map_by_name (name, out_smap, out_sm, out_sm_idx);
+ return m_inner->get_state_map_by_name (name, out_smap, out_sm, out_sm_idx,
+ out_sm_context);
}
const gimple *get_stmt () const override
@@ -961,9 +908,9 @@ protected:
class note_adding_context : public region_model_context_decorator
{
public:
- bool warn (pending_diagnostic *d) override
+ bool warn (std::unique_ptr<pending_diagnostic> d) override
{
- if (m_inner->warn (d))
+ if (m_inner->warn (std::move (d)))
{
add_note (make_note ());
return true;
@@ -973,7 +920,7 @@ public:
}
/* Hook to make the new note. */
- virtual pending_note *make_note () = 0;
+ virtual std::unique_ptr<pending_note> make_note () = 0;
protected:
note_adding_context (region_model_context *inner)
@@ -1116,9 +1063,9 @@ using namespace ::selftest;
class test_region_model_context : public noop_region_model_context
{
public:
- bool warn (pending_diagnostic *d) final override
+ bool warn (std::unique_ptr<pending_diagnostic> d) final override
{
- m_diagnostics.safe_push (d);
+ m_diagnostics.safe_push (d.release ());
return true;
}
diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc
index da5a13e..67ba948 100644
--- a/gcc/analyzer/region.cc
+++ b/gcc/analyzer/region.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
@@ -670,6 +671,18 @@ region::symbolic_p () const
return get_kind () == RK_SYMBOLIC;
}
+/* Return true if this region is known to be zero bits in size. */
+
+bool
+region::empty_p () const
+{
+ bit_size_t num_bits;
+ if (get_bit_size (&num_bits))
+ if (num_bits == 0)
+ return true;
+ return false;
+}
+
/* Return true if this is a region for a decl with name DECL_NAME.
Intended for use when debugging (for assertions and conditional
breakpoints). */
@@ -1049,6 +1062,17 @@ root_region::dump_to_pp (pretty_printer *pp, bool simple) const
pp_string (pp, "root_region()");
}
+/* class thread_local_region : public space_region. */
+
+void
+thread_local_region::dump_to_pp (pretty_printer *pp, bool simple) const
+{
+ if (simple)
+ pp_string (pp, "thread_local_region");
+ else
+ pp_string (pp, "thread_local_region()");
+}
+
/* class symbolic_region : public map_region. */
/* symbolic_region's ctor. */
@@ -1810,6 +1834,17 @@ var_arg_region::get_frame_region () const
return as_a <const frame_region *> (get_parent_region ());
}
+/* class errno_region : public region. */
+
+void
+errno_region::dump_to_pp (pretty_printer *pp, bool simple) const
+{
+ if (simple)
+ pp_string (pp, "errno_region");
+ else
+ pp_string (pp, "errno_region()");
+}
+
/* class unknown_region : public region. */
/* Implementation of region::dump_to_pp vfunc for unknown_region. */
diff --git a/gcc/analyzer/region.h b/gcc/analyzer/region.h
index 6315fac..6d8bcfb 100644
--- a/gcc/analyzer/region.h
+++ b/gcc/analyzer/region.h
@@ -34,7 +34,8 @@ enum memory_space
MEMSPACE_GLOBALS,
MEMSPACE_STACK,
MEMSPACE_HEAP,
- MEMSPACE_READONLY_DATA
+ MEMSPACE_READONLY_DATA,
+ MEMSPACE_THREAD_LOCAL
};
/* An enum for discriminating between the different concrete subclasses
@@ -49,6 +50,7 @@ enum region_kind
RK_LABEL,
RK_STACK,
RK_HEAP,
+ RK_THREAD_LOCAL,
RK_ROOT,
RK_SYMBOLIC,
RK_DECL,
@@ -62,6 +64,7 @@ enum region_kind
RK_STRING,
RK_BIT_RANGE,
RK_VAR_ARG,
+ RK_ERRNO,
RK_UNKNOWN,
};
@@ -77,6 +80,8 @@ enum region_kind
code_region (RK_CODE): represents the code segment, containing functions
stack_region (RK_STACK): a stack, containing all stack frames
heap_region (RK_HEAP): the heap, containing heap_allocated_regions
+ thread_local_region (RK_THREAD_LOCAL): thread-local data for the thread
+ being analyzed
root_region (RK_ROOT): the top-level region
function_region (RK_FUNCTION): the code for a particular function
label_region (RK_LABEL): a particular label within a function
@@ -102,6 +107,7 @@ enum region_kind
within another region
var_arg_region (RK_VAR_ARG): a region for the N-th vararg within a
frame_region for a variadic call
+ errno_region (RK_ERRNO): a region for holding "errno"
unknown_region (RK_UNKNOWN): for handling unimplemented tree codes. */
/* Abstract base class for representing ways of accessing chunks of memory.
@@ -227,6 +233,8 @@ public:
bool is_named_decl_p (const char *decl_name) const;
+ bool empty_p () const;
+
protected:
region (complexity c, unsigned id, const region *parent, tree type);
@@ -555,6 +563,32 @@ is_a_helper <const heap_region *>::test (const region *reg)
namespace ana {
+/* Concrete space_region subclass: thread-local data for the thread
+ being analyzed. */
+
+class thread_local_region : public space_region
+{
+public:
+ thread_local_region (unsigned id, region *parent)
+ : space_region (id, parent)
+ {}
+
+ enum region_kind get_kind () const final override { return RK_THREAD_LOCAL; }
+ void dump_to_pp (pretty_printer *pp, bool simple) const final override;
+};
+
+} // namespace ana
+
+template <>
+template <>
+inline bool
+is_a_helper <const thread_local_region *>::test (const region *reg)
+{
+ return reg->get_kind () == RK_THREAD_LOCAL;
+}
+
+namespace ana {
+
/* Concrete region subclass. The root region, containing all regions
(either directly, or as descendents).
Unique within a region_model_manager. */
@@ -1362,6 +1396,32 @@ template <> struct default_hash_traits<var_arg_region::key_t>
namespace ana {
+/* A region for errno for the current thread. */
+
+class errno_region : public region
+{
+public:
+ errno_region (unsigned id, const thread_local_region *parent)
+ : region (complexity (parent), id, parent, integer_type_node)
+ {}
+
+ enum region_kind get_kind () const final override { return RK_ERRNO; }
+
+ void dump_to_pp (pretty_printer *pp, bool simple) const final override;
+};
+
+} // namespace ana
+
+template <>
+template <>
+inline bool
+is_a_helper <const errno_region *>::test (const region *reg)
+{
+ return reg->get_kind () == RK_ERRNO;
+}
+
+namespace ana {
+
/* An unknown region, for handling unimplemented tree codes. */
class unknown_region : public region
diff --git a/gcc/analyzer/sm-fd.cc b/gcc/analyzer/sm-fd.cc
index ae846cd..50e1313 100644
--- a/gcc/analyzer/sm-fd.cc
+++ b/gcc/analyzer/sm-fd.cc
@@ -19,8 +19,10 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
+#include "make-unique.h"
#include "tree.h"
#include "function.h"
#include "basic-block.h"
@@ -43,6 +45,10 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/region-model.h"
#include "bitmap.h"
#include "analyzer/program-state.h"
+#include "analyzer/supergraph.h"
+#include "analyzer/analyzer-language.h"
+#include "analyzer/call-details.h"
+#include "analyzer/call-info.h"
#if ENABLE_ANALYZER
@@ -74,6 +80,17 @@ enum dup
DUP_3
};
+/* Enum for use by -Wanalyzer-fd-phase-mismatch. */
+
+enum expected_phase
+{
+ EXPECTED_PHASE_CAN_TRANSFER, /* can "read"/"write". */
+ EXPECTED_PHASE_CAN_BIND,
+ EXPECTED_PHASE_CAN_LISTEN,
+ EXPECTED_PHASE_CAN_ACCEPT,
+ EXPECTED_PHASE_CAN_CONNECT
+};
+
class fd_state_machine : public state_machine
{
public:
@@ -110,10 +127,13 @@ public:
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;
+ std::unique_ptr<pending_diagnostic> on_leak (tree var) const final override;
bool is_unchecked_fd_p (state_t s) const;
bool is_valid_fd_p (state_t s) const;
+ bool is_socket_fd_p (state_t s) const;
+ bool is_datagram_socket_fd_p (state_t s) const;
+ bool is_stream_socket_fd_p (state_t s) const;
bool is_closed_fd_p (state_t s) const;
bool is_constant_fd_p (state_t s) const;
bool is_readonly_fd_p (state_t s) const;
@@ -128,6 +148,27 @@ public:
const svalue *fd_sval,
const extrinsic_state &ext_state) const;
+ bool on_socket (const call_details &cd,
+ bool successful,
+ sm_context *sm_ctxt,
+ const extrinsic_state &ext_state) const;
+ bool on_bind (const call_details &cd,
+ bool successful,
+ sm_context *sm_ctxt,
+ const extrinsic_state &ext_state) const;
+ bool on_listen (const call_details &cd,
+ bool successful,
+ sm_context *sm_ctxt,
+ const extrinsic_state &ext_state) const;
+ bool on_accept (const call_details &cd,
+ bool successful,
+ sm_context *sm_ctxt,
+ const extrinsic_state &ext_state) const;
+ bool on_connect (const call_details &cd,
+ bool successful,
+ sm_context *sm_ctxt,
+ const extrinsic_state &ext_state) const;
+
/* State for a constant file descriptor (>= 0) */
state_t m_constant_fd;
@@ -154,9 +195,39 @@ public:
/* State for a file descriptor that has been closed. */
state_t m_closed;
+ /* States for FDs relating to socket APIs. */
+
+ /* Result of successful "socket" with SOCK_DGRAM. */
+ state_t m_new_datagram_socket;
+ /* Result of successful "socket" with SOCK_STREAM. */
+ state_t m_new_stream_socket;
+ /* Result of successful "socket" with unknown type. */
+ state_t m_new_unknown_socket;
+
+ /* The above after a successful call to "bind". */
+ state_t m_bound_datagram_socket;
+ state_t m_bound_stream_socket;
+ state_t m_bound_unknown_socket;
+
+ /* A bound socket after a successful call to "listen" (stream or unknown). */
+ state_t m_listening_stream_socket;
+
+ /* (i) the new FD as a result of a succesful call to "accept" on a
+ listening socket (via a passive open), or
+ (ii) an active socket after a successful call to "connect"
+ (via an active open). */
+ state_t m_connected_stream_socket;
+
/* State for a file descriptor that we do not want to track anymore . */
state_t m_stop;
+ /* Stashed constant values from the frontend. These could be NULL. */
+ tree m_O_ACCMODE;
+ tree m_O_RDONLY;
+ tree m_O_WRONLY;
+ tree m_SOCK_STREAM;
+ tree m_SOCK_DGRAM;
+
private:
void on_open (sm_context *sm_ctxt, const supernode *node, const gimple *stmt,
const gcall *call) const;
@@ -188,6 +259,23 @@ private:
void check_for_dup (sm_context *sm_ctxt, const supernode *node,
const gimple *stmt, const gcall *call, const tree callee_fndecl,
enum dup kind) const;
+
+ state_t get_state_for_socket_type (const svalue *socket_type_sval) const;
+
+ bool check_for_socket_fd (const call_details &cd,
+ bool successful,
+ sm_context *sm_ctxt,
+ const svalue *fd_sval,
+ const supernode *node,
+ state_t old_state,
+ bool *complained = NULL) const;
+ bool check_for_new_socket_fd (const call_details &cd,
+ bool successful,
+ sm_context *sm_ctxt,
+ const svalue *fd_sval,
+ const supernode *node,
+ state_t old_state,
+ enum expected_phase expected_phase) const;
};
/* Base diagnostic class relative to fd_state_machine. */
@@ -207,9 +295,7 @@ public:
label_text
describe_state_change (const evdesc::state_change &change) override
{
- if (change.m_old_state == m_sm.get_start_state ()
- && (m_sm.is_unchecked_fd_p (change.m_new_state)
- || m_sm.is_valid_fd_p (change.m_new_state)))
+ if (change.m_old_state == m_sm.get_start_state ())
{
if (change.m_new_state == m_sm.m_unchecked_read_write
|| change.m_new_state == m_sm.m_valid_read_write)
@@ -222,8 +308,32 @@ public:
if (change.m_new_state == m_sm.m_unchecked_write_only
|| change.m_new_state == m_sm.m_valid_write_only)
return change.formatted_print ("opened here as write-only");
+
+ if (change.m_new_state == m_sm.m_new_datagram_socket)
+ return change.formatted_print ("datagram socket created here");
+
+ if (change.m_new_state == m_sm.m_new_stream_socket)
+ return change.formatted_print ("stream socket created here");
+
+ if (change.m_new_state == m_sm.m_new_unknown_socket
+ || change.m_new_state == m_sm.m_connected_stream_socket)
+ return change.formatted_print ("socket created here");
}
+ if (change.m_new_state == m_sm.m_bound_datagram_socket)
+ return change.formatted_print ("datagram socket bound here");
+
+ if (change.m_new_state == m_sm.m_bound_stream_socket)
+ return change.formatted_print ("stream socket bound here");
+
+ if (change.m_new_state == m_sm.m_bound_unknown_socket
+ || change.m_new_state == m_sm.m_connected_stream_socket)
+ return change.formatted_print ("socket bound here");
+
+ if (change.m_new_state == m_sm.m_listening_stream_socket)
+ return change.formatted_print
+ ("stream socket marked as passive here via %qs", "listen");
+
if (change.m_new_state == m_sm.m_closed)
return change.formatted_print ("closed here");
@@ -256,7 +366,10 @@ public:
const evdesc::state_change &change) const final override
{
if (change.m_old_state == m_sm.get_start_state ()
- && (m_sm.is_unchecked_fd_p (change.m_new_state)))
+ && (m_sm.is_unchecked_fd_p (change.m_new_state)
+ || change.m_new_state == m_sm.m_new_datagram_socket
+ || change.m_new_state == m_sm.m_new_stream_socket
+ || change.m_new_state == m_sm.m_new_unknown_socket))
return diagnostic_event::meaning (diagnostic_event::VERB_acquire,
diagnostic_event::NOUN_resource);
if (change.m_new_state == m_sm.m_closed)
@@ -673,6 +786,289 @@ private:
diagnostic_event_id_t m_first_open_event;
};
+/* Concrete pending_diagnostic subclass for -Wanalyzer-fd-phase-mismatch. */
+
+class fd_phase_mismatch : public fd_param_diagnostic
+{
+public:
+ fd_phase_mismatch (const fd_state_machine &sm, tree arg,
+ const tree callee_fndecl,
+ state_machine::state_t actual_state,
+ enum expected_phase expected_phase)
+ : fd_param_diagnostic (sm, arg, callee_fndecl),
+ m_actual_state (actual_state),
+ m_expected_phase (expected_phase)
+ {
+ gcc_assert (m_sm.is_socket_fd_p (actual_state));
+ switch (expected_phase)
+ {
+ case EXPECTED_PHASE_CAN_TRANSFER:
+ gcc_assert (actual_state == m_sm.m_new_stream_socket
+ || actual_state == m_sm.m_bound_stream_socket
+ || actual_state == m_sm.m_listening_stream_socket);
+ break;
+ case EXPECTED_PHASE_CAN_BIND:
+ gcc_assert (actual_state == m_sm.m_bound_datagram_socket
+ || actual_state == m_sm.m_bound_stream_socket
+ || actual_state == m_sm.m_bound_unknown_socket
+ || actual_state == m_sm.m_connected_stream_socket
+ || actual_state == m_sm.m_listening_stream_socket);
+ break;
+ case EXPECTED_PHASE_CAN_LISTEN:
+ gcc_assert (actual_state == m_sm.m_new_stream_socket
+ || actual_state == m_sm.m_new_unknown_socket
+ || actual_state == m_sm.m_connected_stream_socket);
+ break;
+ case EXPECTED_PHASE_CAN_ACCEPT:
+ gcc_assert (actual_state == m_sm.m_new_stream_socket
+ || actual_state == m_sm.m_new_unknown_socket
+ || actual_state == m_sm.m_bound_stream_socket
+ || actual_state == m_sm.m_bound_unknown_socket
+ || actual_state == m_sm.m_connected_stream_socket);
+ break;
+ case EXPECTED_PHASE_CAN_CONNECT:
+ gcc_assert (actual_state == m_sm.m_bound_datagram_socket
+ || actual_state == m_sm.m_bound_stream_socket
+ || actual_state == m_sm.m_bound_unknown_socket
+ || actual_state == m_sm.m_listening_stream_socket
+ || actual_state == m_sm.m_connected_stream_socket);
+ break;
+ }
+ }
+
+ const char *
+ get_kind () const final override
+ {
+ return "fd_phase_mismatch";
+ }
+
+ bool
+ subclass_equal_p (const pending_diagnostic &base_other) const final override
+ {
+ const fd_phase_mismatch &sub_other = (const fd_phase_mismatch &)base_other;
+ if (!fd_param_diagnostic ::subclass_equal_p (sub_other))
+ return false;
+ return (m_actual_state == sub_other.m_actual_state
+ && m_expected_phase == sub_other.m_expected_phase);
+ }
+
+ int
+ get_controlling_option () const final override
+ {
+ return OPT_Wanalyzer_fd_phase_mismatch;
+ }
+
+ bool
+ emit (rich_location *rich_loc) final override
+ {
+ /* CWE-666: Operation on Resource in Wrong Phase of Lifetime. */
+ diagnostic_metadata m;
+ m.add_cwe (666);
+ return warning_at (rich_loc, get_controlling_option (),
+ "%qE on file descriptor %qE in wrong phase",
+ m_callee_fndecl, m_arg);
+ }
+
+ label_text
+ describe_final_event (const evdesc::final_event &ev) final override
+ {
+ switch (m_expected_phase)
+ {
+ case EXPECTED_PHASE_CAN_TRANSFER:
+ {
+ if (m_actual_state == m_sm.m_new_stream_socket)
+ return ev.formatted_print
+ ("%qE expects a stream socket to be connected via %qs"
+ " but %qE has not yet been bound",
+ m_callee_fndecl, "accept", m_arg);
+ if (m_actual_state == m_sm.m_bound_stream_socket)
+ return ev.formatted_print
+ ("%qE expects a stream socket to be connected via %qs"
+ " but %qE is not yet listening",
+ m_callee_fndecl, "accept", m_arg);
+ if (m_actual_state == m_sm.m_listening_stream_socket)
+ return ev.formatted_print
+ ("%qE expects a stream socket to be connected via"
+ " the return value of %qs"
+ " but %qE is listening; wrong file descriptor?",
+ m_callee_fndecl, "accept", m_arg);
+ }
+ break;
+ case EXPECTED_PHASE_CAN_BIND:
+ {
+ if (m_actual_state == m_sm.m_bound_datagram_socket
+ || m_actual_state == m_sm.m_bound_stream_socket
+ || m_actual_state == m_sm.m_bound_unknown_socket)
+ return ev.formatted_print
+ ("%qE expects a new socket file descriptor"
+ " but %qE has already been bound",
+ m_callee_fndecl, m_arg);
+ if (m_actual_state == m_sm.m_connected_stream_socket)
+ return ev.formatted_print
+ ("%qE expects a new socket file descriptor"
+ " but %qE is already connected",
+ m_callee_fndecl, m_arg);
+ if (m_actual_state == m_sm.m_listening_stream_socket)
+ return ev.formatted_print
+ ("%qE expects a new socket file descriptor"
+ " but %qE is already listening",
+ m_callee_fndecl, m_arg);
+ }
+ break;
+ case EXPECTED_PHASE_CAN_LISTEN:
+ {
+ if (m_actual_state == m_sm.m_new_stream_socket
+ || m_actual_state == m_sm.m_new_unknown_socket)
+ return ev.formatted_print
+ ("%qE expects a bound stream socket file descriptor"
+ " but %qE has not yet been bound",
+ m_callee_fndecl, m_arg);
+ if (m_actual_state == m_sm.m_connected_stream_socket)
+ return ev.formatted_print
+ ("%qE expects a bound stream socket file descriptor"
+ " but %qE is connected",
+ m_callee_fndecl, m_arg);
+ }
+ break;
+ case EXPECTED_PHASE_CAN_ACCEPT:
+ {
+ if (m_actual_state == m_sm.m_new_stream_socket
+ || m_actual_state == m_sm.m_new_unknown_socket)
+ return ev.formatted_print
+ ("%qE expects a listening stream socket file descriptor"
+ " but %qE has not yet been bound",
+ m_callee_fndecl, m_arg);
+ if (m_actual_state == m_sm.m_bound_stream_socket
+ || m_actual_state == m_sm.m_bound_unknown_socket)
+ return ev.formatted_print
+ ("%qE expects a listening stream socket file descriptor"
+ " whereas %qE is bound but not yet listening",
+ m_callee_fndecl, m_arg);
+ if (m_actual_state == m_sm.m_connected_stream_socket)
+ return ev.formatted_print
+ ("%qE expects a listening stream socket file descriptor"
+ " but %qE is connected",
+ m_callee_fndecl, m_arg);
+ }
+ break;
+ case EXPECTED_PHASE_CAN_CONNECT:
+ {
+ if (m_actual_state == m_sm.m_bound_datagram_socket
+ || m_actual_state == m_sm.m_bound_stream_socket
+ || m_actual_state == m_sm.m_bound_unknown_socket)
+ return ev.formatted_print
+ ("%qE expects a new socket file descriptor but %qE is bound",
+ m_callee_fndecl, m_arg);
+ else
+ return ev.formatted_print
+ ("%qE expects a new socket file descriptor", m_callee_fndecl);
+ }
+ break;
+ }
+ gcc_unreachable ();
+ }
+
+private:
+ state_machine::state_t m_actual_state;
+ enum expected_phase m_expected_phase;
+};
+
+/* Enum for use by -Wanalyzer-fd-type-mismatch. */
+
+enum expected_type
+{
+ EXPECTED_TYPE_SOCKET,
+ EXPECTED_TYPE_STREAM_SOCKET
+};
+
+/* Concrete pending_diagnostic subclass for -Wanalyzer-fd-type-mismatch. */
+
+class fd_type_mismatch : public fd_param_diagnostic
+{
+public:
+ fd_type_mismatch (const fd_state_machine &sm, tree arg,
+ const tree callee_fndecl,
+ state_machine::state_t actual_state,
+ enum expected_type expected_type)
+ : fd_param_diagnostic (sm, arg, callee_fndecl),
+ m_actual_state (actual_state),
+ m_expected_type (expected_type)
+ {
+ }
+
+ const char *
+ get_kind () const final override
+ {
+ return "fd_type_mismatch";
+ }
+
+ bool
+ subclass_equal_p (const pending_diagnostic &base_other) const final override
+ {
+ const fd_type_mismatch &sub_other = (const fd_type_mismatch &)base_other;
+ if (!fd_param_diagnostic ::subclass_equal_p (sub_other))
+ return false;
+ return (m_actual_state == sub_other.m_actual_state
+ && m_expected_type == sub_other.m_expected_type);
+ }
+
+ int
+ get_controlling_option () const final override
+ {
+ return OPT_Wanalyzer_fd_type_mismatch;
+ }
+
+ bool
+ emit (rich_location *rich_loc) final override
+ {
+ switch (m_expected_type)
+ {
+ default:
+ gcc_unreachable ();
+ case EXPECTED_TYPE_SOCKET:
+ return warning_at (rich_loc, get_controlling_option (),
+ "%qE on non-socket file descriptor %qE",
+ m_callee_fndecl, m_arg);
+ case EXPECTED_TYPE_STREAM_SOCKET:
+ if (m_sm.is_datagram_socket_fd_p (m_actual_state))
+ return warning_at (rich_loc, get_controlling_option (),
+ "%qE on datagram socket file descriptor %qE",
+ m_callee_fndecl, m_arg);
+ else
+ return warning_at (rich_loc, get_controlling_option (),
+ "%qE on non-stream-socket file descriptor %qE",
+ m_callee_fndecl, m_arg);
+ }
+ }
+
+ label_text
+ describe_final_event (const evdesc::final_event &ev) final override
+ {
+ switch (m_expected_type)
+ {
+ default:
+ break;
+ gcc_unreachable ();
+ case EXPECTED_TYPE_SOCKET:
+ case EXPECTED_TYPE_STREAM_SOCKET:
+ if (!m_sm.is_socket_fd_p (m_actual_state))
+ return ev.formatted_print ("%qE expects a socket file descriptor"
+ " but %qE is not a socket",
+ m_callee_fndecl, m_arg);
+ }
+ gcc_assert (m_expected_type == EXPECTED_TYPE_STREAM_SOCKET);
+ gcc_assert (m_sm.is_datagram_socket_fd_p (m_actual_state));
+ return ev.formatted_print
+ ("%qE expects a stream socket file descriptor"
+ " but %qE is a datagram socket",
+ m_callee_fndecl, m_arg);
+ }
+
+private:
+ state_machine::state_t m_actual_state;
+ enum expected_type m_expected_type;
+};
+
fd_state_machine::fd_state_machine (logger *logger)
: state_machine ("file-descriptor", logger),
m_constant_fd (add_state ("fd-constant")),
@@ -684,7 +1080,20 @@ fd_state_machine::fd_state_machine (logger *logger)
m_valid_write_only (add_state ("fd-valid-write-only")),
m_invalid (add_state ("fd-invalid")),
m_closed (add_state ("fd-closed")),
- m_stop (add_state ("fd-stop"))
+ m_new_datagram_socket (add_state ("fd-new-datagram-socket")),
+ m_new_stream_socket (add_state ("fd-new-stream-socket")),
+ m_new_unknown_socket (add_state ("fd-new-unknown-socket")),
+ m_bound_datagram_socket (add_state ("fd-bound-datagram-socket")),
+ m_bound_stream_socket (add_state ("fd-bound-stream-socket")),
+ m_bound_unknown_socket (add_state ("fd-bound-unknown-socket")),
+ m_listening_stream_socket (add_state ("fd-listening-stream-socket")),
+ m_connected_stream_socket (add_state ("fd-connected-stream-socket")),
+ m_stop (add_state ("fd-stop")),
+ m_O_ACCMODE (get_stashed_constant_by_name ("O_ACCMODE")),
+ m_O_RDONLY (get_stashed_constant_by_name ("O_RDONLY")),
+ m_O_WRONLY (get_stashed_constant_by_name ("O_WRONLY")),
+ m_SOCK_STREAM (get_stashed_constant_by_name ("SOCK_STREAM")),
+ m_SOCK_DGRAM (get_stashed_constant_by_name ("SOCK_DGRAM"))
{
}
@@ -704,19 +1113,54 @@ fd_state_machine::is_valid_fd_p (state_t s) const
|| s == m_valid_write_only);
}
+bool
+fd_state_machine::is_socket_fd_p (state_t s) const
+{
+ return (s == m_new_datagram_socket
+ || s == m_new_stream_socket
+ || s == m_new_unknown_socket
+ || s == m_bound_datagram_socket
+ || s == m_bound_stream_socket
+ || s == m_bound_unknown_socket
+ || s == m_listening_stream_socket
+ || s == m_connected_stream_socket);
+}
+
+bool
+fd_state_machine::is_datagram_socket_fd_p (state_t s) const
+{
+ return (s == m_new_datagram_socket
+ || s == m_new_unknown_socket
+ || s == m_bound_datagram_socket
+ || s == m_bound_unknown_socket);
+}
+
+bool
+fd_state_machine::is_stream_socket_fd_p (state_t s) const
+{
+ return (s == m_new_stream_socket
+ || s == m_new_unknown_socket
+ || s == m_bound_stream_socket
+ || s == m_bound_unknown_socket
+ || s == m_listening_stream_socket
+ || s == m_connected_stream_socket);
+}
+
enum access_mode
fd_state_machine::get_access_mode_from_flag (int flag) const
{
- /* FIXME: this code assumes the access modes on the host and
- target are the same, which in practice might not be the case. */
-
- if ((flag & O_ACCMODE) == O_RDONLY)
- {
- return READ_ONLY;
- }
- else if ((flag & O_ACCMODE) == O_WRONLY)
+ if (m_O_ACCMODE && TREE_CODE (m_O_ACCMODE) == INTEGER_CST)
{
- return WRITE_ONLY;
+ const unsigned HOST_WIDE_INT mask_val = TREE_INT_CST_LOW (m_O_ACCMODE);
+ const unsigned HOST_WIDE_INT masked_flag = flag & mask_val;
+
+ if (m_O_RDONLY && TREE_CODE (m_O_RDONLY) == INTEGER_CST)
+ if (masked_flag == TREE_INT_CST_LOW (m_O_RDONLY))
+ return READ_ONLY;
+
+ if (m_O_WRONLY && TREE_CODE (m_O_WRONLY) == INTEGER_CST)
+ if (masked_flag == TREE_INT_CST_LOW (m_O_WRONLY))
+ return WRITE_ONLY;
}
return READ_WRITE;
}
@@ -885,9 +1329,10 @@ fd_state_machine::check_for_fd_attrs (
{
sm_ctxt->warn (node, stmt, arg,
- new fd_use_after_close (*this, diag_arg,
- callee_fndecl, attr_name,
- arg_idx));
+ make_unique<fd_use_after_close>
+ (*this, diag_arg,
+ callee_fndecl, attr_name,
+ arg_idx));
continue;
}
@@ -895,9 +1340,10 @@ fd_state_machine::check_for_fd_attrs (
{
if (!is_constant_fd_p (state))
sm_ctxt->warn (node, stmt, arg,
- new fd_use_without_check (*this, diag_arg,
- callee_fndecl, attr_name,
- arg_idx));
+ make_unique<fd_use_without_check>
+ (*this, diag_arg,
+ callee_fndecl, attr_name,
+ arg_idx));
}
switch (fd_attr_access_dir)
@@ -910,8 +1356,11 @@ fd_state_machine::check_for_fd_attrs (
{
sm_ctxt->warn (
node, stmt, arg,
- new fd_access_mode_mismatch (*this, diag_arg, DIRS_WRITE,
- callee_fndecl, attr_name, arg_idx));
+ make_unique<fd_access_mode_mismatch> (*this, diag_arg,
+ DIRS_WRITE,
+ callee_fndecl,
+ attr_name,
+ arg_idx));
}
break;
@@ -921,8 +1370,11 @@ fd_state_machine::check_for_fd_attrs (
{
sm_ctxt->warn (
node, stmt, arg,
- new fd_access_mode_mismatch (*this, diag_arg, DIRS_READ,
- callee_fndecl, attr_name, arg_idx));
+ make_unique<fd_access_mode_mismatch> (*this, diag_arg,
+ DIRS_READ,
+ callee_fndecl,
+ attr_name,
+ arg_idx));
}
break;
@@ -963,7 +1415,8 @@ fd_state_machine::on_open (sm_context *sm_ctxt, const supernode *node,
}
else
{
- sm_ctxt->warn (node, stmt, NULL_TREE, new fd_leak (*this, NULL_TREE));
+ sm_ctxt->warn (node, stmt, NULL_TREE,
+ make_unique<fd_leak> (*this, NULL_TREE));
}
}
@@ -975,7 +1428,8 @@ fd_state_machine::on_creat (sm_context *sm_ctxt, const supernode *node,
if (lhs)
sm_ctxt->on_transition (node, stmt, lhs, m_start, m_unchecked_write_only);
else
- sm_ctxt->warn (node, stmt, NULL_TREE, new fd_leak (*this, NULL_TREE));
+ sm_ctxt->warn (node, stmt, NULL_TREE,
+ make_unique<fd_leak> (*this, NULL_TREE));
}
void
@@ -1021,7 +1475,8 @@ fd_state_machine::check_for_dup (sm_context *sm_ctxt, const supernode *node,
{
sm_ctxt->warn (
node, stmt, arg_2,
- new fd_use_without_check (*this, diag_arg_2, callee_fndecl));
+ make_unique<fd_use_without_check> (*this, diag_arg_2,
+ callee_fndecl));
return;
}
/* dup2 returns value of its second argument on success.But, the
@@ -1056,10 +1511,19 @@ fd_state_machine::on_close (sm_context *sm_ctxt, const supernode *node,
sm_ctxt->on_transition (node, stmt, arg, m_valid_read_only, m_closed);
sm_ctxt->on_transition (node, stmt, arg, m_valid_write_only, m_closed);
sm_ctxt->on_transition (node, stmt, arg, m_constant_fd, m_closed);
+ sm_ctxt->on_transition (node, stmt, arg, m_new_datagram_socket, m_closed);
+ sm_ctxt->on_transition (node, stmt, arg, m_new_stream_socket, m_closed);
+ sm_ctxt->on_transition (node, stmt, arg, m_new_unknown_socket, m_closed);
+ sm_ctxt->on_transition (node, stmt, arg, m_bound_datagram_socket, m_closed);
+ sm_ctxt->on_transition (node, stmt, arg, m_bound_stream_socket, m_closed);
+ sm_ctxt->on_transition (node, stmt, arg, m_bound_unknown_socket, m_closed);
+ sm_ctxt->on_transition (node, stmt, arg, m_listening_stream_socket, m_closed);
+ sm_ctxt->on_transition (node, stmt, arg, m_connected_stream_socket, m_closed);
if (is_closed_fd_p (state))
{
- sm_ctxt->warn (node, stmt, arg, new fd_double_close (*this, diag_arg));
+ sm_ctxt->warn (node, stmt, arg,
+ make_unique<fd_double_close> (*this, diag_arg));
sm_ctxt->set_next_state (stmt, arg, m_stop);
}
}
@@ -1091,17 +1555,34 @@ fd_state_machine::check_for_open_fd (
if (is_closed_fd_p (state))
{
sm_ctxt->warn (node, stmt, arg,
- new fd_use_after_close (*this, diag_arg, callee_fndecl));
+ make_unique<fd_use_after_close> (*this, diag_arg,
+ callee_fndecl));
}
else
{
- if (!(is_valid_fd_p (state) || state == m_start || state == m_stop))
+ if (state == m_new_stream_socket
+ || state == m_bound_stream_socket
+ || state == m_listening_stream_socket)
+ /* Complain about fncall on socket in wrong phase. */
+ sm_ctxt->warn
+ (node, stmt, arg,
+ make_unique<fd_phase_mismatch> (*this, diag_arg,
+ callee_fndecl,
+ state,
+ EXPECTED_PHASE_CAN_TRANSFER));
+ else if (!(is_valid_fd_p (state)
+ || state == m_new_datagram_socket
+ || state == m_bound_unknown_socket
+ || state == m_connected_stream_socket
+ || state == m_start
+ || state == m_stop))
{
if (!is_constant_fd_p (state))
sm_ctxt->warn (
node, stmt, arg,
- new fd_use_without_check (*this, diag_arg, callee_fndecl));
+ make_unique<fd_use_without_check> (*this, diag_arg,
+ callee_fndecl));
}
switch (callee_fndecl_dir)
{
@@ -1112,7 +1593,7 @@ fd_state_machine::check_for_open_fd (
{
tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
sm_ctxt->warn (node, stmt, arg,
- new fd_access_mode_mismatch (
+ make_unique<fd_access_mode_mismatch> (
*this, diag_arg, DIRS_WRITE, callee_fndecl));
}
@@ -1123,7 +1604,7 @@ fd_state_machine::check_for_open_fd (
{
tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
sm_ctxt->warn (node, stmt, arg,
- new fd_access_mode_mismatch (
+ make_unique<fd_access_mode_mismatch> (
*this, diag_arg, DIRS_READ, callee_fndecl));
}
break;
@@ -1131,6 +1612,534 @@ fd_state_machine::check_for_open_fd (
}
}
+static bool
+add_constraint_ge_zero (region_model *model,
+ const svalue *fd_sval,
+ region_model_context *ctxt)
+{
+ const svalue *zero
+ = model->get_manager ()->get_or_create_int_cst (integer_type_node, 0);
+ return model->add_constraint (fd_sval, GE_EXPR, zero, ctxt);
+}
+
+/* Get the state for a new socket type based on SOCKET_TYPE_SVAL,
+ a SOCK_* value. */
+
+state_machine::state_t
+fd_state_machine::
+get_state_for_socket_type (const svalue *socket_type_sval) const
+{
+ if (tree socket_type_cst = socket_type_sval->maybe_get_constant ())
+ {
+ /* Attempt to use SOCK_* constants stashed from the frontend. */
+ if (tree_int_cst_equal (socket_type_cst, m_SOCK_STREAM))
+ return m_new_stream_socket;
+ if (tree_int_cst_equal (socket_type_cst, m_SOCK_DGRAM))
+ return m_new_datagram_socket;
+ }
+
+ /* Unrecognized constant, or a symbolic "type" value. */
+ return m_new_unknown_socket;
+}
+
+/* Update the model and fd state for an outcome of a call to "socket",
+ where SUCCESSFUL indicate which of the two outcomes.
+ Return true if the outcome is feasible, or false to reject it. */
+
+bool
+fd_state_machine::on_socket (const call_details &cd,
+ bool successful,
+ sm_context *sm_ctxt,
+ const extrinsic_state &ext_state) const
+{
+ const gcall *stmt = cd.get_call_stmt ();
+ engine *eng = ext_state.get_engine ();
+ const supergraph *sg = eng->get_supergraph ();
+ const supernode *node = sg->get_supernode_for_stmt (stmt);
+ region_model *model = cd.get_model ();
+
+ if (successful)
+ {
+ if (gimple_call_lhs (stmt))
+ {
+ conjured_purge p (model, cd.get_ctxt ());
+ region_model_manager *mgr = model->get_manager ();
+ const svalue *new_fd
+ = mgr->get_or_create_conjured_svalue (integer_type_node,
+ stmt,
+ cd.get_lhs_region (),
+ p);
+ if (!add_constraint_ge_zero (model, new_fd, cd.get_ctxt ()))
+ return false;
+
+ const svalue *socket_type_sval = cd.get_arg_svalue (1);
+ state_machine::state_t new_state
+ = get_state_for_socket_type (socket_type_sval);
+ sm_ctxt->on_transition (node, stmt, new_fd, m_start, new_state);
+ model->set_value (cd.get_lhs_region (), new_fd, cd.get_ctxt ());
+ }
+ else
+ sm_ctxt->warn (node, stmt, NULL_TREE,
+ make_unique<fd_leak> (*this, NULL_TREE));
+ }
+ else
+ {
+ /* Return -1; set errno. */
+ model->update_for_int_cst_return (cd, -1, true);
+ model->set_errno (cd);
+ }
+
+ return true;
+}
+
+/* Check that FD_SVAL is usable by socket APIs.
+ Complain if it has been closed, if it is a non-socket,
+ or is invalid.
+ If COMPLAINED is non-NULL and a problem is found,
+ write *COMPLAINED = true.
+
+ If SUCCESSFUL is true, attempt to add the constraint that FD_SVAL >= 0.
+ Return true if this outcome is feasible. */
+
+bool
+fd_state_machine::check_for_socket_fd (const call_details &cd,
+ bool successful,
+ sm_context *sm_ctxt,
+ const svalue *fd_sval,
+ const supernode *node,
+ state_t old_state,
+ bool *complained) const
+{
+ const gcall *stmt = cd.get_call_stmt ();
+
+ if (is_closed_fd_p (old_state))
+ {
+ tree diag_arg = sm_ctxt->get_diagnostic_tree (fd_sval);
+ sm_ctxt->warn
+ (node, stmt, fd_sval,
+ make_unique<fd_use_after_close> (*this, diag_arg,
+ cd.get_fndecl_for_call ()));
+ if (complained)
+ *complained = true;
+ if (successful)
+ return false;
+ }
+ else if (is_unchecked_fd_p (old_state) || is_valid_fd_p (old_state))
+ {
+ /* Complain about non-socket. */
+ tree diag_arg = sm_ctxt->get_diagnostic_tree (fd_sval);
+ sm_ctxt->warn
+ (node, stmt, fd_sval,
+ make_unique<fd_type_mismatch> (*this, diag_arg,
+ cd.get_fndecl_for_call (),
+ old_state,
+ EXPECTED_TYPE_SOCKET));
+ if (complained)
+ *complained = true;
+ if (successful)
+ return false;
+ }
+ else if (old_state == m_invalid)
+ {
+ tree diag_arg = sm_ctxt->get_diagnostic_tree (fd_sval);
+ sm_ctxt->warn
+ (node, stmt, fd_sval,
+ make_unique<fd_use_without_check> (*this, diag_arg,
+ cd.get_fndecl_for_call ()));
+ if (complained)
+ *complained = true;
+ if (successful)
+ return false;
+ }
+
+ if (successful)
+ if (!add_constraint_ge_zero (cd.get_model (), fd_sval, cd.get_ctxt ()))
+ return false;
+
+ return true;
+}
+
+/* For use by "bind" and "connect".
+ As per fd_state_machine::check_for_socket_fd above,
+ but also complain if we don't have a new socket, and check that
+ we can read up to the size bytes from the address. */
+
+bool
+fd_state_machine::check_for_new_socket_fd (const call_details &cd,
+ bool successful,
+ sm_context *sm_ctxt,
+ const svalue *fd_sval,
+ const supernode *node,
+ state_t old_state,
+ enum expected_phase expected_phase)
+ const
+{
+ bool complained = false;
+
+ /* Check address and len. */
+ const svalue *address_sval = cd.get_arg_svalue (1);
+ const svalue *len_sval = cd.get_arg_svalue (2);
+
+ /* Check that we can read the given number of bytes from the
+ address. */
+ region_model *model = cd.get_model ();
+ const region *address_reg
+ = model->deref_rvalue (address_sval, cd.get_arg_tree (1),
+ cd.get_ctxt ());
+ const region *sized_address_reg
+ = model->get_manager ()->get_sized_region (address_reg,
+ NULL_TREE,
+ len_sval);
+ model->get_store_value (sized_address_reg, cd.get_ctxt ());
+
+ if (!check_for_socket_fd (cd, successful, sm_ctxt,
+ fd_sval, node, old_state, &complained))
+ return false;
+ else if (!complained
+ && !(old_state == m_new_stream_socket
+ || old_state == m_new_datagram_socket
+ || old_state == m_new_unknown_socket
+ || old_state == m_start
+ || old_state == m_stop
+ || old_state == m_constant_fd))
+ {
+ /* Complain about "bind" or "connect" in wrong phase. */
+ tree diag_arg = sm_ctxt->get_diagnostic_tree (fd_sval);
+ sm_ctxt->warn
+ (node, cd.get_call_stmt (), fd_sval,
+ make_unique<fd_phase_mismatch> (*this, diag_arg,
+ cd.get_fndecl_for_call (),
+ old_state,
+ expected_phase));
+ if (successful)
+ return false;
+ }
+ else if (!successful)
+ {
+ /* If we were in the start state, assume we had a new socket. */
+ if (old_state == m_start)
+ sm_ctxt->set_next_state (cd.get_call_stmt (), fd_sval,
+ m_new_unknown_socket);
+ }
+
+ /* Passing NULL as the address will lead to failure. */
+ if (successful)
+ if (address_sval->all_zeroes_p ())
+ return false;
+
+ return true;
+}
+
+/* Update the model and fd state for an outcome of a call to "bind",
+ where SUCCESSFUL indicate which of the two outcomes.
+ Return true if the outcome is feasible, or false to reject it. */
+
+bool
+fd_state_machine::on_bind (const call_details &cd,
+ bool successful,
+ sm_context *sm_ctxt,
+ const extrinsic_state &ext_state) const
+{
+ const gcall *stmt = cd.get_call_stmt ();
+ engine *eng = ext_state.get_engine ();
+ const supergraph *sg = eng->get_supergraph ();
+ const supernode *node = sg->get_supernode_for_stmt (stmt);
+ const svalue *fd_sval = cd.get_arg_svalue (0);
+ region_model *model = cd.get_model ();
+ state_t old_state = sm_ctxt->get_state (stmt, fd_sval);
+
+ if (!check_for_new_socket_fd (cd, successful, sm_ctxt,
+ fd_sval, node, old_state,
+ EXPECTED_PHASE_CAN_BIND))
+ return false;
+
+ if (successful)
+ {
+ state_t next_state = NULL;
+ if (old_state == m_new_stream_socket)
+ next_state = m_bound_stream_socket;
+ else if (old_state == m_new_datagram_socket)
+ next_state = m_bound_datagram_socket;
+ else if (old_state == m_new_unknown_socket)
+ next_state = m_bound_unknown_socket;
+ else if (old_state == m_start
+ || old_state == m_constant_fd)
+ next_state = m_bound_unknown_socket;
+ else if (old_state == m_stop)
+ next_state = m_stop;
+ else
+ gcc_unreachable ();
+ sm_ctxt->set_next_state (cd.get_call_stmt (), fd_sval, next_state);
+ model->update_for_zero_return (cd, true);
+ }
+ else
+ {
+ /* Return -1; set errno. */
+ model->update_for_int_cst_return (cd, -1, true);
+ model->set_errno (cd);
+ }
+
+ return true;
+}
+
+/* Update the model and fd state for an outcome of a call to "listen",
+ where SUCCESSFUL indicate which of the two outcomes.
+ Return true if the outcome is feasible, or false to reject it. */
+
+bool
+fd_state_machine::on_listen (const call_details &cd,
+ bool successful,
+ sm_context *sm_ctxt,
+ const extrinsic_state &ext_state) const
+{
+ const gcall *stmt = cd.get_call_stmt ();
+ engine *eng = ext_state.get_engine ();
+ const supergraph *sg = eng->get_supergraph ();
+ const supernode *node = sg->get_supernode_for_stmt (cd.get_call_stmt ());
+ const svalue *fd_sval = cd.get_arg_svalue (0);
+ region_model *model = cd.get_model ();
+ state_t old_state = sm_ctxt->get_state (stmt, fd_sval);
+
+ /* We expect a stream socket that's had "bind" called on it. */
+ if (!check_for_socket_fd (cd, successful, sm_ctxt, fd_sval, node, old_state))
+ return false;
+ if (!(old_state == m_start
+ || old_state == m_constant_fd
+ || old_state == m_stop
+ || old_state == m_bound_stream_socket
+ || old_state == m_bound_unknown_socket
+ /* Assume it's OK to call "listen" more than once. */
+ || old_state == m_listening_stream_socket))
+ {
+ /* Complain about fncall on wrong type or in wrong phase. */
+ tree diag_arg = sm_ctxt->get_diagnostic_tree (fd_sval);
+ if (is_stream_socket_fd_p (old_state))
+ sm_ctxt->warn
+ (node, stmt, fd_sval,
+ make_unique<fd_phase_mismatch> (*this, diag_arg,
+ cd.get_fndecl_for_call (),
+ old_state,
+ EXPECTED_PHASE_CAN_LISTEN));
+ else
+ sm_ctxt->warn
+ (node, stmt, fd_sval,
+ make_unique<fd_type_mismatch> (*this, diag_arg,
+ cd.get_fndecl_for_call (),
+ old_state,
+ EXPECTED_TYPE_STREAM_SOCKET));
+ if (successful)
+ return false;
+ }
+
+ if (successful)
+ {
+ model->update_for_zero_return (cd, true);
+ sm_ctxt->set_next_state (cd.get_call_stmt (), fd_sval,
+ m_listening_stream_socket);
+ }
+ else
+ {
+ /* Return -1; set errno. */
+ model->update_for_int_cst_return (cd, -1, true);
+ model->set_errno (cd);
+ if (old_state == m_start)
+ sm_ctxt->set_next_state (cd.get_call_stmt (), fd_sval,
+ m_bound_stream_socket);
+ }
+
+ return true;
+}
+
+/* Update the model and fd state for an outcome of a call to "accept",
+ where SUCCESSFUL indicate which of the two outcomes.
+ Return true if the outcome is feasible, or false to reject it. */
+
+bool
+fd_state_machine::on_accept (const call_details &cd,
+ bool successful,
+ sm_context *sm_ctxt,
+ const extrinsic_state &ext_state) const
+{
+ const gcall *stmt = cd.get_call_stmt ();
+ engine *eng = ext_state.get_engine ();
+ const supergraph *sg = eng->get_supergraph ();
+ const supernode *node = sg->get_supernode_for_stmt (stmt);
+ const svalue *fd_sval = cd.get_arg_svalue (0);
+ const svalue *address_sval = cd.get_arg_svalue (1);
+ const svalue *len_ptr_sval = cd.get_arg_svalue (2);
+ region_model *model = cd.get_model ();
+ state_t old_state = sm_ctxt->get_state (stmt, fd_sval);
+
+ if (!address_sval->all_zeroes_p ())
+ {
+ region_model_manager *mgr = model->get_manager ();
+
+ /* We might have a union of various pointer types, rather than a
+ pointer type; cast to (void *) before dereferencing. */
+ address_sval = mgr->get_or_create_cast (ptr_type_node, address_sval);
+
+ const region *address_reg
+ = model->deref_rvalue (address_sval, cd.get_arg_tree (1),
+ cd.get_ctxt ());
+ const region *len_reg
+ = model->deref_rvalue (len_ptr_sval, cd.get_arg_tree (2),
+ cd.get_ctxt ());
+ const svalue *old_len_sval
+ = model->get_store_value (len_reg, cd.get_ctxt ());
+ tree len_ptr = cd.get_arg_tree (2);
+ tree star_len_ptr = build2 (MEM_REF, TREE_TYPE (TREE_TYPE (len_ptr)),
+ len_ptr,
+ build_int_cst (TREE_TYPE (len_ptr), 0));
+ old_len_sval = model->check_for_poison (old_len_sval,
+ star_len_ptr,
+ cd.get_ctxt ());
+ if (successful)
+ {
+ conjured_purge p (model, cd.get_ctxt ());
+ const region *old_sized_address_reg
+ = mgr->get_sized_region (address_reg,
+ NULL_TREE,
+ old_len_sval);
+ const svalue *new_addr_sval
+ = mgr->get_or_create_conjured_svalue (NULL_TREE,
+ stmt,
+ old_sized_address_reg,
+ p);
+ model->set_value (old_sized_address_reg, new_addr_sval,
+ cd.get_ctxt ());
+ const svalue *new_addr_len
+ = mgr->get_or_create_conjured_svalue (NULL_TREE,
+ stmt,
+ len_reg,
+ p);
+ model->set_value (len_reg, new_addr_len, cd.get_ctxt ());
+ }
+ }
+
+ /* We expect a stream socket in the "listening" state. */
+ if (!check_for_socket_fd (cd, successful, sm_ctxt, fd_sval, node, old_state))
+ return false;
+
+ if (old_state == m_start || old_state == m_constant_fd)
+ /* If we were in the start state (or a constant), assume we had the
+ expected state. */
+ sm_ctxt->set_next_state (cd.get_call_stmt (), fd_sval,
+ m_listening_stream_socket);
+ else if (old_state == m_stop)
+ {
+ /* No further complaints. */
+ }
+ else if (old_state != m_listening_stream_socket)
+ {
+ /* Complain about fncall on wrong type or in wrong phase. */
+ tree diag_arg = sm_ctxt->get_diagnostic_tree (fd_sval);
+ if (is_stream_socket_fd_p (old_state))
+ sm_ctxt->warn
+ (node, stmt, fd_sval,
+ make_unique<fd_phase_mismatch> (*this, diag_arg,
+ cd.get_fndecl_for_call (),
+ old_state,
+ EXPECTED_PHASE_CAN_ACCEPT));
+ else
+ sm_ctxt->warn
+ (node, stmt, fd_sval,
+ make_unique<fd_type_mismatch> (*this, diag_arg,
+ cd.get_fndecl_for_call (),
+ old_state,
+ EXPECTED_TYPE_STREAM_SOCKET));
+ if (successful)
+ return false;
+ }
+
+ if (successful)
+ {
+ /* Return new conjured FD in "connected" state. */
+ if (gimple_call_lhs (stmt))
+ {
+ conjured_purge p (model, cd.get_ctxt ());
+ region_model_manager *mgr = model->get_manager ();
+ const svalue *new_fd
+ = mgr->get_or_create_conjured_svalue (integer_type_node,
+ stmt,
+ cd.get_lhs_region (),
+ p);
+ if (!add_constraint_ge_zero (model, new_fd, cd.get_ctxt ()))
+ return false;
+ sm_ctxt->on_transition (node, stmt, new_fd,
+ m_start, m_connected_stream_socket);
+ model->set_value (cd.get_lhs_region (), new_fd, cd.get_ctxt ());
+ }
+ else
+ sm_ctxt->warn (node, stmt, NULL_TREE,
+ make_unique<fd_leak> (*this, NULL_TREE));
+ }
+ else
+ {
+ /* Return -1; set errno. */
+ model->update_for_int_cst_return (cd, -1, true);
+ model->set_errno (cd);
+ }
+
+ return true;
+}
+
+/* Update the model and fd state for an outcome of a call to "connect",
+ where SUCCESSFUL indicate which of the two outcomes.
+ Return true if the outcome is feasible, or false to reject it. */
+
+bool
+fd_state_machine::on_connect (const call_details &cd,
+ bool successful,
+ sm_context *sm_ctxt,
+ const extrinsic_state &ext_state) const
+{
+ const gcall *stmt = cd.get_call_stmt ();
+ engine *eng = ext_state.get_engine ();
+ const supergraph *sg = eng->get_supergraph ();
+ const supernode *node = sg->get_supernode_for_stmt (stmt);
+ const svalue *fd_sval = cd.get_arg_svalue (0);
+ region_model *model = cd.get_model ();
+ state_t old_state = sm_ctxt->get_state (stmt, fd_sval);
+
+ if (!check_for_new_socket_fd (cd, successful, sm_ctxt,
+ fd_sval, node, old_state,
+ EXPECTED_PHASE_CAN_CONNECT))
+ return false;
+
+ if (successful)
+ {
+ model->update_for_zero_return (cd, true);
+ state_t next_state = NULL;
+ if (old_state == m_new_stream_socket)
+ next_state = m_connected_stream_socket;
+ else if (old_state == m_new_datagram_socket)
+ /* It's legal to call connect on a datagram socket, potentially
+ more than once. We don't transition states for this. */
+ next_state = m_new_datagram_socket;
+ else if (old_state == m_new_unknown_socket)
+ next_state = m_stop;
+ else if (old_state == m_start
+ || old_state == m_constant_fd)
+ next_state = m_stop;
+ else if (old_state == m_stop)
+ next_state = m_stop;
+ else
+ gcc_unreachable ();
+ sm_ctxt->set_next_state (cd.get_call_stmt (), fd_sval, next_state);
+ }
+ else
+ {
+ /* Return -1; set errno. */
+ model->update_for_int_cst_return (cd, -1, true);
+ model->set_errno (cd);
+ /* TODO: perhaps transition to a failed state, since the
+ portable way to handle a failed "connect" is to close
+ the socket and try again with a new socket. */
+ }
+
+ return true;
+}
+
void
fd_state_machine::on_condition (sm_context *sm_ctxt, const supernode *node,
const gimple *stmt, const svalue *lhs,
@@ -1189,16 +2198,18 @@ fd_state_machine::make_invalid_transitions_on_condition (
bool
fd_state_machine::can_purge_p (state_t s) const
{
- if (is_unchecked_fd_p (s) || is_valid_fd_p (s))
+ if (is_unchecked_fd_p (s)
+ || is_valid_fd_p (s)
+ || is_socket_fd_p (s))
return false;
else
return true;
}
-pending_diagnostic *
+std::unique_ptr<pending_diagnostic>
fd_state_machine::on_leak (tree var) const
{
- return new fd_leak (*this, var);
+ return make_unique<fd_leak> (*this, var);
}
} // namespace
@@ -1208,30 +2219,455 @@ make_fd_state_machine (logger *logger)
return new fd_state_machine (logger);
}
+static bool
+get_fd_state (region_model_context *ctxt,
+ sm_state_map **out_smap,
+ const fd_state_machine **out_sm,
+ unsigned *out_sm_idx,
+ std::unique_ptr<sm_context> *out_sm_context)
+{
+ if (!ctxt)
+ return false;
+
+ const state_machine *sm;
+ if (!ctxt->get_fd_map (out_smap, &sm, out_sm_idx, out_sm_context))
+ return false;
+
+ gcc_assert (sm);
+
+ *out_sm = (const fd_state_machine *)sm;
+ return true;
+}
+
/* Specialcase hook for handling pipe, for use by
- region_model::impl_call_pipe::success::update_model. */
+ kf_pipe::success::update_model. */
void
region_model::mark_as_valid_fd (const svalue *sval, region_model_context *ctxt)
{
- if (!ctxt)
+ sm_state_map *smap;
+ const fd_state_machine *fd_sm;
+ if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, NULL))
return;
const extrinsic_state *ext_state = ctxt->get_ext_state ();
if (!ext_state)
return;
+ fd_sm->mark_as_valid_fd (this, smap, sval, *ext_state);
+}
- sm_state_map *smap;
- const state_machine *sm;
- unsigned sm_idx;
- if (!ctxt->get_fd_map (&smap, &sm, &sm_idx))
- return;
+/* Handle calls to "socket".
+ See e.g. https://man7.org/linux/man-pages/man3/socket.3p.html */
- gcc_assert (smap);
- gcc_assert (sm);
+class kf_socket : public known_function
+{
+public:
+ class outcome_of_socket : public succeed_or_fail_call_info
+ {
+ public:
+ outcome_of_socket (const call_details &cd, bool success)
+ : succeed_or_fail_call_info (cd, success)
+ {}
+
+ bool update_model (region_model *model,
+ const exploded_edge *,
+ region_model_context *ctxt) const final override
+ {
+ const call_details cd (get_call_details (model, ctxt));
+ sm_state_map *smap;
+ const fd_state_machine *fd_sm;
+ std::unique_ptr<sm_context> sm_ctxt;
+ if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt))
+ return true;
+ const extrinsic_state *ext_state = ctxt->get_ext_state ();
+ if (!ext_state)
+ return true;
+
+ return fd_sm->on_socket (cd, m_success, sm_ctxt.get (), *ext_state);
+ }
+ };
+
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 3;
+ }
+
+ void impl_call_post (const call_details &cd) const final override
+ {
+ if (cd.get_ctxt ())
+ {
+ cd.get_ctxt ()->bifurcate (make_unique<outcome_of_socket> (cd, false));
+ cd.get_ctxt ()->bifurcate (make_unique<outcome_of_socket> (cd, true));
+ cd.get_ctxt ()->terminate_path ();
+ }
+ }
+};
+
+/* Handle calls to "bind".
+ See e.g. https://man7.org/linux/man-pages/man3/bind.3p.html */
+
+class kf_bind : public known_function
+{
+public:
+ class outcome_of_bind : public succeed_or_fail_call_info
+ {
+ public:
+ outcome_of_bind (const call_details &cd, bool success)
+ : succeed_or_fail_call_info (cd, success)
+ {}
+
+ bool update_model (region_model *model,
+ const exploded_edge *,
+ region_model_context *ctxt) const final override
+ {
+ const call_details cd (get_call_details (model, ctxt));
+ sm_state_map *smap;
+ const fd_state_machine *fd_sm;
+ std::unique_ptr<sm_context> sm_ctxt;
+ if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt))
+ return true;
+ const extrinsic_state *ext_state = ctxt->get_ext_state ();
+ if (!ext_state)
+ return true;
+ return fd_sm->on_bind (cd, m_success, sm_ctxt.get (), *ext_state);
+ }
+ };
+
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 3 && cd.arg_is_pointer_p (1));
+ }
+
+ void impl_call_post (const call_details &cd) const final override
+ {
+ if (cd.get_ctxt ())
+ {
+ cd.get_ctxt ()->bifurcate (make_unique<outcome_of_bind> (cd, false));
+ cd.get_ctxt ()->bifurcate (make_unique<outcome_of_bind> (cd, true));
+ cd.get_ctxt ()->terminate_path ();
+ }
+ }
+};
+
+/* Handle calls to "listen".
+ See e.g. https://man7.org/linux/man-pages/man3/listen.3p.html */
+
+class kf_listen : public known_function
+{
+ class outcome_of_listen : public succeed_or_fail_call_info
+ {
+ public:
+ outcome_of_listen (const call_details &cd, bool success)
+ : succeed_or_fail_call_info (cd, success)
+ {}
+
+ bool update_model (region_model *model,
+ const exploded_edge *,
+ region_model_context *ctxt) const final override
+ {
+ const call_details cd (get_call_details (model, ctxt));
+ sm_state_map *smap;
+ const fd_state_machine *fd_sm;
+ std::unique_ptr<sm_context> sm_ctxt;
+ if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt))
+ return true;
+ const extrinsic_state *ext_state = ctxt->get_ext_state ();
+ if (!ext_state)
+ return true;
+
+ return fd_sm->on_listen (cd, m_success, sm_ctxt.get (), *ext_state);
+ }
+ };
+
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 2;
+ }
+
+ void impl_call_post (const call_details &cd) const final override
+ {
+ if (cd.get_ctxt ())
+ {
+ cd.get_ctxt ()->bifurcate (make_unique<outcome_of_listen> (cd, false));
+ cd.get_ctxt ()->bifurcate (make_unique<outcome_of_listen> (cd, true));
+ cd.get_ctxt ()->terminate_path ();
+ }
+ }
+};
+
+/* Handle calls to "accept".
+ See e.g. https://man7.org/linux/man-pages/man3/accept.3p.html */
+
+class kf_accept : public known_function
+{
+ class outcome_of_accept : public succeed_or_fail_call_info
+ {
+ public:
+ outcome_of_accept (const call_details &cd, bool success)
+ : succeed_or_fail_call_info (cd, success)
+ {}
+
+ bool update_model (region_model *model,
+ const exploded_edge *,
+ region_model_context *ctxt) const final override
+ {
+ const call_details cd (get_call_details (model, ctxt));
+ sm_state_map *smap;
+ const fd_state_machine *fd_sm;
+ std::unique_ptr<sm_context> sm_ctxt;
+ if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt))
+ return true;
+ const extrinsic_state *ext_state = ctxt->get_ext_state ();
+ if (!ext_state)
+ return true;
+
+ return fd_sm->on_accept (cd, m_success, sm_ctxt.get (), *ext_state);
+ }
+ };
+
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 3
+ && cd.arg_is_pointer_p (1)
+ && cd.arg_is_pointer_p (2));
+ }
+
+ void impl_call_post (const call_details &cd) const final override
+ {
+ if (cd.get_ctxt ())
+ {
+ cd.get_ctxt ()->bifurcate (make_unique<outcome_of_accept> (cd, false));
+ cd.get_ctxt ()->bifurcate (make_unique<outcome_of_accept> (cd, true));
+ cd.get_ctxt ()->terminate_path ();
+ }
+ }
+};
+
+/* Handle calls to "connect".
+ See e.g. https://man7.org/linux/man-pages/man3/connect.3p.html */
+
+class kf_connect : public known_function
+{
+public:
+ class outcome_of_connect : public succeed_or_fail_call_info
+ {
+ public:
+ outcome_of_connect (const call_details &cd, bool success)
+ : succeed_or_fail_call_info (cd, success)
+ {}
+
+ bool update_model (region_model *model,
+ const exploded_edge *,
+ region_model_context *ctxt) const final override
+ {
+ const call_details cd (get_call_details (model, ctxt));
+ sm_state_map *smap;
+ const fd_state_machine *fd_sm;
+ std::unique_ptr<sm_context> sm_ctxt;
+ if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt))
+ return true;
+ const extrinsic_state *ext_state = ctxt->get_ext_state ();
+ if (!ext_state)
+ return true;
+
+ return fd_sm->on_connect (cd, m_success, sm_ctxt.get (), *ext_state);
+ }
+ };
+
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 3
+ && cd.arg_is_pointer_p (1));
+ }
+
+ void impl_call_post (const call_details &cd) const final override
+ {
+ if (cd.get_ctxt ())
+ {
+ cd.get_ctxt ()->bifurcate (make_unique<outcome_of_connect> (cd, false));
+ cd.get_ctxt ()->bifurcate (make_unique<outcome_of_connect> (cd, true));
+ cd.get_ctxt ()->terminate_path ();
+ }
+ }
+};
+
+/* Handler for "isatty"".
+ See e.g. https://man7.org/linux/man-pages/man3/isatty.3.html */
+
+class kf_isatty : public known_function
+{
+ class outcome_of_isatty : public succeed_or_fail_call_info
+ {
+ public:
+ outcome_of_isatty (const call_details &cd, bool success)
+ : succeed_or_fail_call_info (cd, success)
+ {}
+
+ bool update_model (region_model *model,
+ const exploded_edge *,
+ region_model_context *ctxt) const final override
+ {
+ const call_details cd (get_call_details (model, ctxt));
+
+ if (m_success)
+ {
+ /* Return 1. */
+ model->update_for_int_cst_return (cd, 1, true);
+ }
+ else
+ {
+ /* Return 0; set errno. */
+ model->update_for_int_cst_return (cd, 0, true);
+ model->set_errno (cd);
+ }
- const fd_state_machine &fd_sm = (const fd_state_machine &)*sm;
+ return feasible_p (cd, ctxt);
+ }
+
+ private:
+ bool feasible_p (const call_details &cd,
+ region_model_context *ctxt) const
+ {
+ if (m_success)
+ {
+ /* Can't be "success" on a closed/invalid fd. */
+ sm_state_map *smap;
+ const fd_state_machine *fd_sm;
+ std::unique_ptr<sm_context> sm_ctxt;
+ if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt))
+ return true;
+ const extrinsic_state *ext_state = ctxt->get_ext_state ();
+ if (!ext_state)
+ return true;
+
+ const svalue *fd_sval = cd.get_arg_svalue (0);
+ state_machine::state_t old_state
+ = sm_ctxt->get_state (cd.get_call_stmt (), fd_sval);
+
+ if (fd_sm->is_closed_fd_p (old_state)
+ || old_state == fd_sm->m_invalid)
+ return false;
+ }
+ return true;
+ }
+ }; // class outcome_of_isatty
+
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 1;
+ }
+
+ void impl_call_post (const call_details &cd) const final override
+ {
+ if (cd.get_ctxt ())
+ {
+ cd.get_ctxt ()->bifurcate (make_unique<outcome_of_isatty> (cd, false));
+ cd.get_ctxt ()->bifurcate (make_unique<outcome_of_isatty> (cd, true));
+ cd.get_ctxt ()->terminate_path ();
+ }
+ }
+};
+
+/* Handler for calls to "pipe" and "pipe2".
+ See e.g. https://www.man7.org/linux/man-pages/man2/pipe.2.html */
+
+class kf_pipe : public known_function
+{
+ class failure : public failed_call_info
+ {
+ public:
+ failure (const call_details &cd) : failed_call_info (cd) {}
+
+ bool update_model (region_model *model,
+ const exploded_edge *,
+ region_model_context *ctxt) const final override
+ {
+ /* Return -1; everything else is unchanged. */
+ const call_details cd (get_call_details (model, ctxt));
+ model->update_for_int_cst_return (cd, -1, true);
+ return true;
+ }
+ };
- fd_sm.mark_as_valid_fd (this, smap, sval, *ext_state);
+ class success : public success_call_info
+ {
+ public:
+ success (const call_details &cd) : success_call_info (cd) {}
+
+ bool update_model (region_model *model,
+ const exploded_edge *,
+ region_model_context *ctxt) const final override
+ {
+ const call_details cd (get_call_details (model, ctxt));
+
+ /* Return 0. */
+ model->update_for_zero_return (cd, true);
+
+ /* Update fd array. */
+ region_model_manager *mgr = cd.get_manager ();
+ tree arr_tree = cd.get_arg_tree (0);
+ const svalue *arr_sval = cd.get_arg_svalue (0);
+ for (int idx = 0; idx < 2; idx++)
+ {
+ const region *arr_reg
+ = model->deref_rvalue (arr_sval, arr_tree, cd.get_ctxt ());
+ const svalue *idx_sval
+ = mgr->get_or_create_int_cst (integer_type_node, idx);
+ const region *element_reg
+ = mgr->get_element_region (arr_reg, integer_type_node, idx_sval);
+ conjured_purge p (model, cd.get_ctxt ());
+ const svalue *fd_sval
+ = mgr->get_or_create_conjured_svalue (integer_type_node,
+ cd.get_call_stmt (),
+ element_reg,
+ p);
+ model->set_value (element_reg, fd_sval, cd.get_ctxt ());
+ model->mark_as_valid_fd (fd_sval, cd.get_ctxt ());
+ }
+ return true;
+ }
+ };
+
+public:
+ kf_pipe (unsigned num_args)
+ : m_num_args (num_args)
+ {
+ gcc_assert (num_args > 0);
+ }
+
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == m_num_args && cd.arg_is_pointer_p (0));
+ }
+
+ void impl_call_post (const call_details &cd) const final override
+ {
+ if (cd.get_ctxt ())
+ {
+ cd.get_ctxt ()->bifurcate (make_unique<failure> (cd));
+ cd.get_ctxt ()->bifurcate (make_unique<success> (cd));
+ cd.get_ctxt ()->terminate_path ();
+ }
+ }
+
+private:
+ unsigned m_num_args;
+};
+
+/* Populate KFM with instances of known functions relating to
+ file descriptors. */
+
+void
+register_known_fd_functions (known_function_manager &kfm)
+{
+ kfm.add ("accept", make_unique<kf_accept> ());
+ kfm.add ("bind", make_unique<kf_bind> ());
+ kfm.add ("connect", make_unique<kf_connect> ());
+ kfm.add ("isatty", make_unique<kf_isatty> ());
+ kfm.add ("listen", make_unique<kf_listen> ());
+ kfm.add ("pipe", make_unique<kf_pipe> (1));
+ kfm.add ("pipe2", make_unique<kf_pipe> (2));
+ kfm.add ("socket", make_unique<kf_socket> ());
}
} // namespace ana
diff --git a/gcc/analyzer/sm-fd.dot b/gcc/analyzer/sm-fd.dot
index 175daae..d7676b1 100644
--- a/gcc/analyzer/sm-fd.dot
+++ b/gcc/analyzer/sm-fd.dot
@@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
-/* Keep this in-sync with sm-dot.cc */
+/* Keep this in-sync with sm-fd.cc */
digraph "fd" {
@@ -27,6 +27,9 @@ digraph "fd" {
/* Start state. */
start;
+ /* State for a constant file descriptor (>= 0). */
+ constant_fd;
+
/* States representing a file descriptor that hasn't yet been
checked for validity after opening, for three different
access modes. */
@@ -46,6 +49,29 @@ digraph "fd" {
/* State for a file descriptor that has been closed. */
closed;
+ /* States for FDs relating to socket APIs. */
+
+ /* Result of successful "socket" with SOCK_DGRAM. */
+ new_datagram_socket;
+ /* Result of successful "socket" with SOCK_STREAM. */
+ new_stream_socket;
+ /* Result of successful "socket" with unknown type. */
+ new_unknown_socket;
+
+ /* The above after a successful call to "bind". */
+ bound_datagram_socket;
+ bound_stream_socket;
+ bound_unknown_socket;
+
+ /* A bound socket after a successful call to "listen" (stream or unknown). */
+ listening_stream_socket;
+
+ /* (i) the new FD as a result of a succesful call to "accept" on a
+ listening socket (via a passive open), or
+ (ii) an active socket after a successful call to "connect"
+ (via an active open). */
+ connected_stream_socket;
+
/* State for a file descriptor that we do not want to track anymore . */
stop;
@@ -68,6 +94,14 @@ digraph "fd" {
valid_read_only -> closed [label="on 'close(X);'"];
valid_write_only -> closed [label="on 'close(X);'"];
constant_fd -> closed [label="on 'close(X);'"];
+ new_datagram_socket -> closed [label="on 'close(X);'"];
+ new_stream_socket -> closed [label="on 'close(X);'"];
+ new_unknown_socket -> closed [label="on 'close(X);'"];
+ bound_datagram_socket -> closed [label="on 'close(X);'"];
+ bound_stream_socket -> closed [label="on 'close(X);'"];
+ bound_unknown_socket -> closed [label="on 'close(X);'"];
+ listening_stream_socket -> closed [label="on 'close(X);'"];
+ connected_stream_socket -> closed [label="on 'close(X);'"];
closed -> stop [label="on 'close(X);':\nWarn('double close')"];
/* On "read". */
@@ -91,6 +125,34 @@ digraph "fd" {
/* On "pipe". */
start -> valid_read_write [label="when 'pipe()' succeeds"];
+ /* On "socket". */
+ start -> new_datagram_socket [label="when 'socket(..., SOCK_DGRAM, ...)' succeeds"];
+ start -> new_stream_socket [label="when 'socket(..., SOCK_STREAM, ...)' succeeds"];
+ start -> new_unknown_socket [label="when 'socket(..., ..., ...)' succeeds"];
+
+ /* On "bind". */
+ start -> bound_unknown_socket [label="when 'bind(X, ...)' succeeds"];
+ constant_fd -> bound_unknown_socket [label="when 'bind(X, ...)' succeeds"];
+ new_stream_socket -> bound_stream_socket [label="when 'bind(X, ...)' succeeds"];
+ new_datagram_socket -> bound_datagram_socket [label="when 'bind(X, ...)' succeeds"];
+ new_unknown_socket -> bound_unknown_socket [label="when 'bind(X, ...)' succeeds"];
+
+ /* On "listen". */
+ start -> listening_stream_socket [label="when 'listen(X, ...)' succeeds"];
+ bound_stream_socket -> listening_stream_socket [label="when 'listen(X, ...)' succeeds"];
+ bound_unknown_socket -> listening_stream_socket [label="when 'listen(X, ...)' succeeds"];
+
+ /* On "accept". */
+ start -> connected_stream_socket [label="when 'accept(OTHER, ...)' succeeds on a listening_stream_socket"];
+ constant_fd -> connected_stream_socket [label="when 'accept(OTHER, ...)' succeeds on a listening_stream_socket"];
+
+ /* On "connect". */
+ new_stream_socket -> connected_stream_socket [label="when 'connect(X, ...)' succeeds"];
+ new_datagram_socket -> new_datagram_socket [label="when 'connect(X, ...)' succeeds"];
+ new_unknown_socket -> stop [label="when 'connect(X, ...)' succeeds"];
+ start -> stop [label="when 'connect(X, ...)' succeeds"];
+ constant_fd -> stop [label="when 'connect(X, ...)' succeeds"];
+
/* on_condition. */
unchecked_read_write -> valid_read_write [label="on 'X >= 0'"];
unchecked_read_only -> valid_read_only [label="on 'X >= 0'"];
@@ -106,4 +168,12 @@ digraph "fd" {
valid_read_write -> stop [label="on leak:\nWarn('leak')"];
valid_read_only -> stop [label="on leak:\nWarn('leak')"];
valid_write_only -> stop [label="on leak:\nWarn('leak')"];
+ new_datagram_socket -> stop [label="on leak:\nWarn('leak')"];
+ new_stream_socket -> stop [label="on leak:\nWarn('leak')"];
+ new_unknown_socket -> stop [label="on leak:\nWarn('leak')"];
+ bound_datagram_socket -> stop [label="on leak:\nWarn('leak')"];
+ bound_stream_socket -> stop [label="on leak:\nWarn('leak')"];
+ bound_unknown_socket -> stop [label="on leak:\nWarn('leak')"];
+ listening_stream_socket -> stop [label="on leak:\nWarn('leak')"];
+ connected_stream_socket -> stop [label="on leak:\nWarn('leak')"];
}
diff --git a/gcc/analyzer/sm-file.cc b/gcc/analyzer/sm-file.cc
index 13f2507..1bd594b 100644
--- a/gcc/analyzer/sm-file.cc
+++ b/gcc/analyzer/sm-file.cc
@@ -19,8 +19,10 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
+#include "make-unique.h"
#include "tree.h"
#include "function.h"
#include "basic-block.h"
@@ -40,6 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/program-point.h"
#include "analyzer/store.h"
#include "analyzer/region-model.h"
+#include "analyzer/call-details.h"
#if ENABLE_ANALYZER
@@ -79,7 +82,7 @@ public:
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;
+ std::unique_ptr<pending_diagnostic> on_leak (tree var) const final override;
/* State for a FILE * returned from fopen that hasn't been checked for
NULL.
@@ -404,7 +407,7 @@ fileptr_state_machine::on_stmt (sm_context *sm_ctxt,
{
tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
sm_ctxt->warn (node, stmt, arg,
- new double_fclose (*this, diag_arg));
+ make_unique<double_fclose> (*this, diag_arg));
sm_ctxt->set_next_state (stmt, arg, m_stop);
}
return true;
@@ -471,10 +474,10 @@ fileptr_state_machine::can_purge_p (state_t s) const
fileptr_state_machine, for complaining about leaks of FILE * in
state 'unchecked' and 'nonnull'. */
-pending_diagnostic *
+std::unique_ptr<pending_diagnostic>
fileptr_state_machine::on_leak (tree var) const
{
- return new file_leak (*this, var);
+ return make_unique<file_leak> (*this, var);
}
} // anonymous namespace
@@ -487,6 +490,165 @@ make_fileptr_state_machine (logger *logger)
return new fileptr_state_machine (logger);
}
+/* Handler for various stdio-related builtins that merely have external
+ effects that are out of scope for the analyzer: we only want to model
+ the effects on the return value. */
+
+class kf_stdio_output_fn : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &) const final override
+ {
+ return true;
+ }
+
+ /* A no-op; we just want the conjured return value. */
+};
+
+/* Handler for "ferror"". */
+
+class kf_ferror : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 1
+ && cd.arg_is_pointer_p (0));
+ }
+
+ /* No side effects. */
+};
+
+/* Handler for "fileno"". */
+
+class kf_fileno : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 1
+ && cd.arg_is_pointer_p (0));
+ }
+
+ /* No side effects. */
+};
+
+/* Handler for "fgets" and "fgets_unlocked". */
+
+class kf_fgets : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 3
+ && cd.arg_is_pointer_p (0)
+ && cd.arg_is_pointer_p (2));
+ }
+
+ void impl_call_pre (const call_details &cd) const final override
+ {
+ /* Ideally we would bifurcate state here between the
+ error vs no error cases. */
+ region_model *model = cd.get_model ();
+ const svalue *ptr_sval = cd.get_arg_svalue (0);
+ if (const region *reg = ptr_sval->maybe_get_region ())
+ {
+ const region *base_reg = reg->get_base_region ();
+ const svalue *new_sval = cd.get_or_create_conjured_svalue (base_reg);
+ model->set_value (base_reg, new_sval, cd.get_ctxt ());
+ }
+ }
+};
+
+/* Handler for "fread"". */
+
+class kf_fread : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 4
+ && cd.arg_is_pointer_p (0)
+ && cd.arg_is_size_p (1)
+ && cd.arg_is_size_p (2)
+ && cd.arg_is_pointer_p (3));
+ }
+
+ void impl_call_pre (const call_details &cd) const final override
+ {
+ region_model *model = cd.get_model ();
+ const svalue *ptr_sval = cd.get_arg_svalue (0);
+ if (const region *reg = ptr_sval->maybe_get_region ())
+ {
+ const region *base_reg = reg->get_base_region ();
+ const svalue *new_sval = cd.get_or_create_conjured_svalue (base_reg);
+ model->set_value (base_reg, new_sval, cd.get_ctxt ());
+ }
+ }
+};
+
+/* Handler for "getc"". */
+
+class kf_getc : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return (cd.num_args () == 1
+ && cd.arg_is_pointer_p (0));
+ }
+
+ /* No side effects. */
+};
+
+/* Handler for "getchar"". */
+
+class kf_getchar : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 0;
+ }
+
+ /* Empty. No side-effects (tracking stream state is out-of-scope
+ for the analyzer). */
+};
+
+/* Populate KFM with instances of known functions relating to
+ stdio streams. */
+
+void
+register_known_file_functions (known_function_manager &kfm)
+{
+ kfm.add (BUILT_IN_FPRINTF, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_FPRINTF_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_FPUTC, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_FPUTC_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_FPUTS, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_FPUTS_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_FWRITE, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_FWRITE_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_PRINTF, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_PRINTF_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_PUTC, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_PUTCHAR, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_PUTCHAR_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_PUTC_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_PUTS, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_PUTS_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_VFPRINTF, make_unique<kf_stdio_output_fn> ());
+ kfm.add (BUILT_IN_VPRINTF, make_unique<kf_stdio_output_fn> ());
+
+ kfm.add ("ferror", make_unique<kf_ferror> ());
+ kfm.add ("fgets", make_unique<kf_fgets> ());
+ kfm.add ("fgets_unlocked", make_unique<kf_fgets> ()); // non-standard
+ kfm.add ("fileno", make_unique<kf_fileno> ());
+ kfm.add ("fread", make_unique<kf_fread> ());
+ kfm.add ("getc", make_unique<kf_getc> ());
+ kfm.add ("getchar", make_unique<kf_getchar> ());
+}
+
#if CHECKING_P
namespace selftest {
diff --git a/gcc/analyzer/sm-file.dot b/gcc/analyzer/sm-file.dot
new file mode 100644
index 0000000..ac0f361
--- /dev/null
+++ b/gcc/analyzer/sm-file.dot
@@ -0,0 +1,67 @@
+/* An overview of the state machine from sm-file.cc.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* Keep this in-sync with sm-file.cc */
+
+digraph "file" {
+
+ /* STATES. */
+
+ /* Start state. */
+ start;
+
+ /* State for a FILE * returned from fopen that hasn't been checked for
+ NULL.
+ It could be an open stream, or could be NULL. */
+ unchecked;
+
+ /* State for a FILE * that's known to be NULL. */
+ null;
+
+ /* State for a FILE * that's known to be a non-NULL open stream. */
+ nonnull;
+
+ /* State for a FILE * that's had fclose called on it. */
+ closed;
+
+ /* Stop state, for a FILE * we don't want to track any more. */
+ stop;
+
+ /* TRANSITIONS. */
+
+ /* On "fopen". */
+ start -> unchecked [label="on 'X = fopen(...);'"];
+
+ /* On "fclose". */
+ start -> closed [label="on 'close(X);'"];
+ /* TODO: is it safe to call fclose (NULL) ? */
+ unchecked -> closed [label="on 'close(X);'"];
+ null -> closed [label="on 'close(X);'"];
+ nonnull -> closed [label="on 'close(X);'"];
+ closed -> stop [label="on 'close(X);':\nWarn('double fclose')"];
+
+ /* on_condition. */
+ unchecked -> nonnull [label="on 'X != 0'"];
+ unchecked -> null [label="on 'X == 0'"];
+
+ /* Leaks. */
+ unchecked -> stop [label="on leak:\nWarn('leak')"];
+ nonnull -> stop [label="on leak:\nWarn('leak')"];
+}
diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index fef6e63..b520c9b 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -19,8 +19,10 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
+#include "make-unique.h"
#include "tree.h"
#include "function.h"
#include "basic-block.h"
@@ -38,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/program-point.h"
#include "analyzer/store.h"
#include "analyzer/region-model.h"
+#include "analyzer/call-details.h"
#include "stringpool.h"
#include "attribs.h"
#include "analyzer/function-set.h"
@@ -85,6 +88,9 @@ enum resource_state
/* The start state. */
RS_START,
+ /* State for a pointer that's been unconditionally dereferenced. */
+ RS_ASSUMED_NON_NULL,
+
/* State for a pointer that's known to be NULL. */
RS_NULL,
@@ -124,7 +130,7 @@ struct allocation_state : public state_machine::state
m_deallocator (deallocator)
{}
- void dump_to_pp (pretty_printer *pp) const final override;
+ void dump_to_pp (pretty_printer *pp) const override;
const allocation_state *get_nonnull () const;
@@ -133,6 +139,25 @@ struct allocation_state : public state_machine::state
const deallocator *m_deallocator;
};
+/* Custom state subclass, for the "assumed-non-null" state
+ where the assumption happens in a particular frame. */
+
+struct assumed_non_null_state : public allocation_state
+{
+ assumed_non_null_state (const char *name, unsigned id,
+ const frame_region *frame)
+ : allocation_state (name, id, RS_ASSUMED_NON_NULL,
+ NULL, NULL),
+ m_frame (frame)
+ {
+ gcc_assert (m_frame);
+ }
+
+ void dump_to_pp (pretty_printer *pp) const final override;
+
+ const frame_region *m_frame;
+};
+
/* An enum for choosing which wording to use in various diagnostics
when describing deallocations. */
@@ -382,14 +407,25 @@ public:
enum tree_code op,
const svalue *rhs) const final override;
+ void on_pop_frame (sm_state_map *smap,
+ const frame_region *) const final override;
+
bool can_purge_p (state_t s) const final override;
- pending_diagnostic *on_leak (tree var) const final override;
+ std::unique_ptr<pending_diagnostic> on_leak (tree var) const final override;
bool reset_when_passed_to_unknown_fn_p (state_t s,
bool is_mutable) const final override;
+ state_t
+ maybe_get_merged_states_nonequal (state_t state_a,
+ state_t state_b) const final override;
+
static bool unaffected_by_call_p (tree fndecl);
+ void maybe_assume_non_null (sm_context *sm_ctxt,
+ tree ptr,
+ const gimple *stmt) const;
+
void on_realloc_with_move (region_model *model,
sm_state_map *smap,
const svalue *old_ptr_sval,
@@ -404,6 +440,10 @@ public:
/* States that are independent of api. */
+ /* States for a pointer that's been unconditionally dereferenced
+ in a particular stack frame. */
+ hash_map<const frame_region *, state_t> m_assumed_non_null;
+
/* State for a pointer that's known to be NULL. */
state_t m_null;
@@ -423,6 +463,16 @@ private:
const deallocator *
get_or_create_deallocator (tree deallocator_fndecl);
+ state_t
+ get_or_create_assumed_non_null_state_for_frame (const frame_region *frame);
+
+ void
+ maybe_complain_about_deref_before_check (sm_context *sm_ctxt,
+ const supernode *node,
+ const gimple *stmt,
+ const assumed_non_null_state *,
+ tree ptr) const;
+
void on_allocator_call (sm_context *sm_ctxt,
const gcall *call,
const deallocator_set *deallocators,
@@ -676,6 +726,14 @@ freed_p (state_machine::state_t state)
return get_rs (state) == RS_FREED;
}
+/* Return true if STATE is a value that has been assumed to be non-NULL. */
+
+static bool
+assumed_non_null_p (state_machine::state_t state)
+{
+ return get_rs (state) == RS_ASSUMED_NON_NULL;
+}
+
/* Class for diagnostics relating to malloc_state_machine. */
class malloc_diagnostic : public pending_diagnostic
@@ -1426,6 +1484,80 @@ private:
const char *m_funcname;
};
+/* Concrete pending_diagnostic subclass for -Wanalyzer-deref-before-check. */
+
+class deref_before_check : public malloc_diagnostic
+{
+public:
+ deref_before_check (const malloc_state_machine &sm, tree arg)
+ : malloc_diagnostic (sm, arg)
+ {}
+
+ const char *get_kind () const final override { return "deref_before_check"; }
+
+ int get_controlling_option () const final override
+ {
+ return OPT_Wanalyzer_deref_before_check;
+ }
+
+ bool emit (rich_location *rich_loc) final override
+ {
+ if (m_arg)
+ return warning_at (rich_loc, get_controlling_option (),
+ "check of %qE for NULL after already"
+ " dereferencing it",
+ m_arg);
+ else
+ return warning_at (rich_loc, get_controlling_option (),
+ "check of pointer for NULL after already"
+ " dereferencing it");
+ }
+
+ label_text describe_state_change (const evdesc::state_change &change)
+ final override
+ {
+ if (change.m_old_state == m_sm.get_start_state ()
+ && assumed_non_null_p (change.m_new_state))
+ {
+ m_first_deref_event = change.m_event_id;
+ if (m_arg)
+ return change.formatted_print ("pointer %qE is dereferenced here",
+ m_arg);
+ else
+ return label_text::borrow ("pointer is dereferenced here");
+ }
+ return malloc_diagnostic::describe_state_change (change);
+ }
+
+ label_text describe_final_event (const evdesc::final_event &ev) final override
+ {
+ if (m_first_deref_event.known_p ())
+ {
+ if (m_arg)
+ return ev.formatted_print ("pointer %qE is checked for NULL here but"
+ " it was already dereferenced at %@",
+ m_arg, &m_first_deref_event);
+ else
+ return ev.formatted_print ("pointer is checked for NULL here but"
+ " it was already dereferenced at %@",
+ &m_first_deref_event);
+ }
+ else
+ {
+ if (m_arg)
+ return ev.formatted_print ("pointer %qE is checked for NULL here but"
+ " it was already dereferenced",
+ m_arg);
+ else
+ return ev.formatted_print ("pointer is checked for NULL here but"
+ " it was already dereferenced");
+ }
+ }
+
+private:
+ diagnostic_event_id_t m_first_deref_event;
+};
+
/* struct allocation_state : public state_machine::state. */
/* Implementation of state_machine::state::dump_to_pp vfunc
@@ -1454,6 +1586,17 @@ allocation_state::get_nonnull () const
return as_a_allocation_state (m_deallocators->m_nonnull);
}
+/* struct assumed_non_null_state : public allocation_state. */
+
+void
+assumed_non_null_state::dump_to_pp (pretty_printer *pp) const
+{
+ allocation_state::dump_to_pp (pp);
+ pp_string (pp, " (in ");
+ m_frame->dump_to_pp (pp, true);
+ pp_character (pp, ')');
+}
+
/* malloc_state_machine's ctor. */
malloc_state_machine::malloc_state_machine (logger *logger)
@@ -1595,6 +1738,22 @@ malloc_state_machine::get_or_create_deallocator (tree deallocator_fndecl)
return d;
}
+/* Get the "assumed-non-null" state for assumptions made within FRAME,
+ creating it if necessary. */
+
+state_machine::state_t
+malloc_state_machine::
+get_or_create_assumed_non_null_state_for_frame (const frame_region *frame)
+{
+ if (state_t *slot = m_assumed_non_null.get (frame))
+ return *slot;
+ state_machine::state *new_state
+ = new assumed_non_null_state ("assumed-non-null", alloc_state_id (), frame);
+ add_custom_state (new_state);
+ m_assumed_non_null.put (frame, new_state);
+ return new_state;
+}
+
/* Try to identify the function declaration either by name or as a known malloc
builtin. */
@@ -1627,6 +1786,33 @@ known_allocator_p (const_tree fndecl, const gcall *call)
return false;
}
+/* If PTR's nullness is not known, transition it to the "assumed-non-null"
+ state for the current frame. */
+
+void
+malloc_state_machine::maybe_assume_non_null (sm_context *sm_ctxt,
+ tree ptr,
+ const gimple *stmt) const
+{
+ const region_model *old_model = sm_ctxt->get_old_region_model ();
+ if (!old_model)
+ return;
+
+ tree null_ptr_cst = build_int_cst (TREE_TYPE (ptr), 0);
+ tristate known_non_null
+ = old_model->eval_condition (ptr, NE_EXPR, null_ptr_cst, NULL);
+ if (known_non_null.is_unknown ())
+ {
+ /* Cast away const-ness for cache-like operations. */
+ malloc_state_machine *mut_this
+ = const_cast <malloc_state_machine *> (this);
+ state_t next_state
+ = mut_this->get_or_create_assumed_non_null_state_for_frame
+ (old_model->get_current_frame ());
+ sm_ctxt->set_next_state (stmt, ptr, next_state);
+ }
+}
+
/* Implementation of state_machine::on_stmt vfunc for malloc_state_machine. */
bool
@@ -1726,9 +1912,8 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt,
{
tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
sm_ctxt->warn (node, stmt, arg,
- new possible_null_arg (*this, diag_arg,
- callee_fndecl,
- i));
+ make_unique<possible_null_arg>
+ (*this, diag_arg, callee_fndecl, i));
const allocation_state *astate
= as_a_allocation_state (state);
sm_ctxt->set_next_state (stmt, arg,
@@ -1738,10 +1923,12 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt,
{
tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
sm_ctxt->warn (node, stmt, arg,
- new null_arg (*this, diag_arg,
- callee_fndecl, i));
+ make_unique<null_arg>
+ (*this, diag_arg, callee_fndecl, i));
sm_ctxt->set_next_state (stmt, arg, m_stop);
}
+ else if (state == m_start)
+ maybe_assume_non_null (sm_ctxt, arg, stmt);
}
}
BITMAP_FREE (nonnull_args);
@@ -1759,6 +1946,36 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt,
}
}
+ /* Look for pointers explicitly being compared against zero
+ that are in state assumed_non_null i.e. we already defererenced
+ them.
+ We have to do this check here, rather than in on_condition
+ because we add a constraint that the pointer is non-null when
+ dereferencing it, and this makes the apply_constraints_for_gcond
+ find known-true and known-false conditions; on_condition is only
+ called when adding new constraints. */
+ if (const gcond *cond_stmt = dyn_cast <const gcond *> (stmt))
+ {
+ enum tree_code op = gimple_cond_code (cond_stmt);
+ if (op == EQ_EXPR || op == NE_EXPR)
+ {
+ tree lhs = gimple_cond_lhs (cond_stmt);
+ tree rhs = gimple_cond_rhs (cond_stmt);
+ if (any_pointer_p (lhs)
+ && any_pointer_p (rhs)
+ && zerop (rhs))
+ {
+ state_t state = sm_ctxt->get_state (stmt, lhs);
+ if (assumed_non_null_p (state))
+ maybe_complain_about_deref_before_check
+ (sm_ctxt, node,
+ stmt,
+ (const assumed_non_null_state *)state,
+ lhs);
+ }
+ }
+ }
+
if (tree lhs = sm_ctxt->is_zero_assignment (stmt))
if (any_pointer_p (lhs))
on_zero_assignment (sm_ctxt, stmt,lhs);
@@ -1777,11 +1994,14 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt,
tree arg = TREE_OPERAND (op, 0);
state_t state = sm_ctxt->get_state (stmt, arg);
- if (unchecked_p (state))
+ if (state == m_start)
+ maybe_assume_non_null (sm_ctxt, arg, stmt);
+ else if (unchecked_p (state))
{
tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
sm_ctxt->warn (node, stmt, arg,
- new possible_null_deref (*this, diag_arg));
+ make_unique<possible_null_deref> (*this,
+ diag_arg));
const allocation_state *astate = as_a_allocation_state (state);
sm_ctxt->set_next_state (stmt, arg, astate->get_nonnull ());
}
@@ -1789,7 +2009,7 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt,
{
tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
sm_ctxt->warn (node, stmt, arg,
- new null_deref (*this, diag_arg));
+ make_unique<null_deref> (*this, diag_arg));
sm_ctxt->set_next_state (stmt, arg, m_stop);
}
else if (freed_p (state))
@@ -1797,8 +2017,8 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt,
tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
const allocation_state *astate = as_a_allocation_state (state);
sm_ctxt->warn (node, stmt, arg,
- new use_after_free (*this, diag_arg,
- astate->m_deallocator));
+ make_unique<use_after_free>
+ (*this, diag_arg, astate->m_deallocator));
sm_ctxt->set_next_state (stmt, arg, m_stop);
}
}
@@ -1806,6 +2026,53 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt,
return false;
}
+/* Given a check against null of PTR in assumed-non-null state STATE,
+ potentially add a deref_before_check warning to SM_CTXT. */
+
+void
+malloc_state_machine::
+maybe_complain_about_deref_before_check (sm_context *sm_ctxt,
+ const supernode *node,
+ const gimple *stmt,
+ const assumed_non_null_state *state,
+ tree ptr) const
+{
+ const region_model *model = sm_ctxt->get_old_region_model ();
+ if (!model)
+ return;
+
+ /* Don't complain if the current frame (where the check is occurring) is
+ deeper than the frame in which the "not null" assumption was made.
+ This suppress false positives for cases like:
+
+ void foo (struct s *p)
+ {
+ int val = s->some_field; // deref here
+ shared_helper (p);
+ }
+
+ where "shared_helper" has:
+
+ void shared_helper (struct s *p)
+ {
+ if (!p) // check here
+ return;
+ // etc
+ }
+
+ since the check in "shared_helper" is OK. */
+ const frame_region *checked_in_frame = model->get_current_frame ();
+ const frame_region *assumed_nonnull_in_frame = state->m_frame;
+ if (checked_in_frame->get_index () > assumed_nonnull_in_frame->get_index ())
+ return;
+
+ tree diag_ptr = sm_ctxt->get_diagnostic_tree (ptr);
+ sm_ctxt->warn
+ (node, stmt, ptr,
+ make_unique<deref_before_check> (*this, diag_ptr));
+ sm_ctxt->set_next_state (stmt, ptr, m_stop);
+}
+
/* Handle a call to an allocator.
RETURNS_NONNULL is true if CALL is to a fndecl known to have
__attribute__((returns_nonnull)). */
@@ -1850,8 +2117,8 @@ malloc_state_machine::handle_free_of_non_heap (sm_context *sm_ctxt,
freed_reg = old_model->deref_rvalue (ptr_sval, arg, NULL);
}
sm_ctxt->warn (node, call, arg,
- new free_of_non_heap (*this, diag_arg, freed_reg,
- d->m_name));
+ make_unique<free_of_non_heap>
+ (*this, diag_arg, freed_reg, d->m_name));
sm_ctxt->set_next_state (call, arg, m_stop);
}
@@ -1868,8 +2135,8 @@ malloc_state_machine::on_deallocator_call (sm_context *sm_ctxt,
state_t state = sm_ctxt->get_state (call, arg);
- /* start/unchecked/nonnull -> freed. */
- if (state == m_start)
+ /* start/assumed_non_null/unchecked/nonnull -> freed. */
+ if (state == m_start || assumed_non_null_p (state))
sm_ctxt->set_next_state (call, arg, d->m_freed);
else if (unchecked_p (state) || nonnull_p (state))
{
@@ -1879,11 +2146,11 @@ malloc_state_machine::on_deallocator_call (sm_context *sm_ctxt,
{
/* Wrong allocator. */
tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- pending_diagnostic *pd
- = new mismatching_deallocation (*this, diag_arg,
- astate->m_deallocators,
- d);
- sm_ctxt->warn (node, call, arg, pd);
+ sm_ctxt->warn (node, call, arg,
+ make_unique<mismatching_deallocation>
+ (*this, diag_arg,
+ astate->m_deallocators,
+ d));
}
sm_ctxt->set_next_state (call, arg, d->m_freed);
}
@@ -1895,7 +2162,7 @@ malloc_state_machine::on_deallocator_call (sm_context *sm_ctxt,
/* freed -> stop, with warning. */
tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
sm_ctxt->warn (node, call, arg,
- new double_free (*this, diag_arg, d->m_name));
+ make_unique<double_free> (*this, diag_arg, d->m_name));
sm_ctxt->set_next_state (call, arg, m_stop);
}
else if (state == m_non_heap)
@@ -1909,7 +2176,7 @@ malloc_state_machine::on_deallocator_call (sm_context *sm_ctxt,
Check for free of non-heap or mismatching allocators,
transitioning to the "stop" state for such cases.
- Otherwise, region_model::impl_call_realloc will later
+ Otherwise, kf_realloc::impl_call_post will later
get called (which will handle other sm-state transitions
when the state is bifurcated). */
@@ -1933,11 +2200,10 @@ malloc_state_machine::on_realloc_call (sm_context *sm_ctxt,
{
/* Wrong allocator. */
tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
- pending_diagnostic *pd
- = new mismatching_deallocation (*this, diag_arg,
- astate->m_deallocators,
- d);
- sm_ctxt->warn (node, call, arg, pd);
+ sm_ctxt->warn (node, call, arg,
+ make_unique<mismatching_deallocation>
+ (*this, diag_arg,
+ astate->m_deallocators, d));
sm_ctxt->set_next_state (call, arg, m_stop);
if (path_context *path_ctxt = sm_ctxt->get_path_context ())
path_ctxt->terminate_path ();
@@ -1948,7 +2214,7 @@ malloc_state_machine::on_realloc_call (sm_context *sm_ctxt,
/* freed -> stop, with warning. */
tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
sm_ctxt->warn (node, call, arg,
- new double_free (*this, diag_arg, "free"));
+ make_unique<double_free> (*this, diag_arg, "free"));
sm_ctxt->set_next_state (call, arg, m_stop);
if (path_context *path_ctxt = sm_ctxt->get_path_context ())
path_ctxt->terminate_path ();
@@ -2015,6 +2281,31 @@ malloc_state_machine::on_condition (sm_context *sm_ctxt,
}
}
+/* Implementation of state_machine::on_pop_frame vfunc for malloc_state_machine.
+ Clear any "assumed-non-null" state where the assumption happened in
+ FRAME_REG. */
+
+void
+malloc_state_machine::on_pop_frame (sm_state_map *smap,
+ const frame_region *frame_reg) const
+{
+ hash_set<const svalue *> svals_to_clear;
+ for (auto kv : *smap)
+ {
+ const svalue *sval = kv.first;
+ state_t state = kv.second.m_state;
+ if (assumed_non_null_p (state))
+ {
+ const assumed_non_null_state *assumed_state
+ = (const assumed_non_null_state *)state;
+ if (frame_reg == assumed_state->m_frame)
+ svals_to_clear.add (sval);
+ }
+ }
+ for (auto sval : svals_to_clear)
+ smap->clear_any_state (sval);
+}
+
/* Implementation of state_machine::can_purge_p vfunc for malloc_state_machine.
Don't allow purging of pointers in state 'unchecked' or 'nonnull'
(to avoid false leak reports). */
@@ -2030,10 +2321,10 @@ malloc_state_machine::can_purge_p (state_t s) const
(for complaining about leaks of pointers in state 'unchecked' and
'nonnull'). */
-pending_diagnostic *
+std::unique_ptr<pending_diagnostic>
malloc_state_machine::on_leak (tree var) const
{
- return new malloc_leak (*this, var);
+ return make_unique<malloc_leak> (*this, var);
}
/* Implementation of state_machine::reset_when_passed_to_unknown_fn_p vfunc
@@ -2052,6 +2343,23 @@ malloc_state_machine::reset_when_passed_to_unknown_fn_p (state_t s,
return is_mutable;
}
+/* Implementation of state_machine::maybe_get_merged_states_nonequal vfunc
+ for malloc_state_machine.
+
+ Support discarding "assumed-non-null" states when merging with
+ start state. */
+
+state_machine::state_t
+malloc_state_machine::maybe_get_merged_states_nonequal (state_t state_a,
+ state_t state_b) const
+{
+ if (assumed_non_null_p (state_a) && state_b == m_start)
+ return m_start;
+ if (state_a == m_start && assumed_non_null_p (state_b))
+ return m_start;
+ return NULL;
+}
+
/* Return true if calls to FNDECL are known to not affect this sm-state. */
bool
@@ -2125,7 +2433,7 @@ make_malloc_state_machine (logger *logger)
}
/* Specialcase hook for handling realloc, for use by
- region_model::impl_call_realloc::success_with_move::update_model. */
+ kf_realloc::impl_call_post::success_with_move::update_model. */
void
region_model::on_realloc_with_move (const call_details &cd,
diff --git a/gcc/analyzer/sm-malloc.dot b/gcc/analyzer/sm-malloc.dot
index c8f4f9c..cb1c54a 100644
--- a/gcc/analyzer/sm-malloc.dot
+++ b/gcc/analyzer/sm-malloc.dot
@@ -32,6 +32,9 @@ digraph "malloc" {
It could be a pointer to heap-allocated memory, or could be NULL. */
unchecked;
+ /* State for a pointer that's been unconditionally dereferenced. */
+ assumed_non_null;
+
/* State for a pointer that's known to be NULL. */
null;
@@ -58,6 +61,7 @@ digraph "malloc" {
/* On "free". */
start -> freed [label="on 'free(X);'"];
+ assumed_non_null -> freed [label="on 'free(X);'"];
unchecked -> freed [label="on 'free(X);'"];
nonnull -> freed [label="on 'free(X);'"];
freed -> stop [label="on 'free(X);':\n Warn('double-free')"];
@@ -66,6 +70,7 @@ digraph "malloc" {
/* Handle "__attribute__((nonnull))". */
unchecked -> nonnull [label="on 'FN(X)' with __attribute__((nonnull)):\nWarn('possible NULL arg')"];
null -> stop [label="on 'FN(X)' with __attribute__((nonnull)):\nWarn('NULL arg')"];
+ start -> assumed_non_null [label="on 'FN(X)' with __attribute__((nonnull))"];
/* is_zero_assignment. */
start -> null [label="on 'X = 0;'"];
@@ -76,6 +81,7 @@ digraph "malloc" {
start -> non_heap [label="on 'X = &EXPR;'"];
/* Handle dereferences. */
+ start -> assumed_non_null [label="on '*X'"];
unchecked -> nonnull [label="on '*X':\nWarn('possible NULL deref')"];
null -> stop [label="on '*X':\nWarn('NULL deref')"];
freed -> stop [label="on '*X':\nWarn('use after free')"];
@@ -83,6 +89,7 @@ digraph "malloc" {
/* on_condition. */
unchecked -> nonnull [label="on 'X != 0'"];
unchecked -> null [label="on 'X == 0'"];
+ assumed_non_null -> stop [label="on 'if (X)':\nWarn('deref-before-check')"];
unchecked -> stop [label="on leak:\nWarn('leak')"];
nonnull -> stop [label="on leak:\nWarn('leak')"];
diff --git a/gcc/analyzer/sm-pattern-test.cc b/gcc/analyzer/sm-pattern-test.cc
index 3208132..704f628 100644
--- a/gcc/analyzer/sm-pattern-test.cc
+++ b/gcc/analyzer/sm-pattern-test.cc
@@ -21,8 +21,10 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
+#include "make-unique.h"
#include "tree.h"
#include "function.h"
#include "basic-block.h"
@@ -139,8 +141,8 @@ pattern_test_state_machine::on_condition (sm_context *sm_ctxt,
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);
+ sm_ctxt->warn (node, stmt, lhs_expr,
+ make_unique<pattern_match> (lhs_expr, op, rhs_cst));
}
}
diff --git a/gcc/analyzer/sm-sensitive.cc b/gcc/analyzer/sm-sensitive.cc
index cb5f859..d19765f 100644
--- a/gcc/analyzer/sm-sensitive.cc
+++ b/gcc/analyzer/sm-sensitive.cc
@@ -20,8 +20,10 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
+#include "make-unique.h"
#include "tree.h"
#include "function.h"
#include "basic-block.h"
@@ -181,7 +183,8 @@ sensitive_state_machine::warn_for_any_exposure (sm_context *sm_ctxt,
{
tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
sm_ctxt->warn (node, stmt, arg,
- new exposure_through_output_file (*this, diag_arg));
+ make_unique<exposure_through_output_file> (*this,
+ diag_arg));
}
}
diff --git a/gcc/analyzer/sm-signal.cc b/gcc/analyzer/sm-signal.cc
index e3b08c3..38db6c0 100644
--- a/gcc/analyzer/sm-signal.cc
+++ b/gcc/analyzer/sm-signal.cc
@@ -21,8 +21,10 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
+#include "make-unique.h"
#include "tree.h"
#include "function.h"
#include "basic-block.h"
@@ -232,8 +234,8 @@ public:
const final override
{
emission_path->add_event
- (new precanned_custom_event
- (UNKNOWN_LOCATION, NULL_TREE, 0,
+ (make_unique<precanned_custom_event>
+ (event_loc_info (UNKNOWN_LOCATION, NULL_TREE, 0),
"later on,"
" when the signal is delivered to the process"));
}
@@ -277,7 +279,7 @@ public:
src_enode);
if (dst_enode)
eg->add_edge (src_enode, dst_enode, NULL, /*state_change (),*/
- new signal_delivery_edge_info_t ());
+ make_unique<signal_delivery_edge_info_t> ());
}
const signal_state_machine &m_sm;
@@ -351,8 +353,8 @@ signal_state_machine::on_stmt (sm_context *sm_ctxt,
if (signal_unsafe_p (callee_fndecl))
if (sm_ctxt->get_global_state () == m_in_signal_handler)
sm_ctxt->warn (node, stmt, NULL_TREE,
- new signal_unsafe_call (*this, call,
- callee_fndecl));
+ make_unique<signal_unsafe_call>
+ (*this, call, callee_fndecl));
}
return false;
diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc
index bc27533..a2b442a 100644
--- a/gcc/analyzer/sm-taint.cc
+++ b/gcc/analyzer/sm-taint.cc
@@ -21,8 +21,10 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
+#include "make-unique.h"
#include "tree.h"
#include "function.h"
#include "basic-block.h"
@@ -107,6 +109,10 @@ public:
state_t combine_states (state_t s0, state_t s1) const;
private:
+ void check_control_flow_arg_for_taint (sm_context *sm_ctxt,
+ const gimple *stmt,
+ tree expr) const;
+
void check_for_tainted_size_arg (sm_context *sm_ctxt,
const supernode *node,
const gcall *call,
@@ -128,6 +134,9 @@ public:
/* Stop state, for a value we don't want to track any more. */
state_t m_stop;
+
+ /* Global state, for when the last condition had tainted arguments. */
+ state_t m_tainted_control_flow;
};
/* Class for diagnostics relating to taint_state_machine. */
@@ -147,8 +156,7 @@ public:
&& m_has_bounds == other.m_has_bounds);
}
- label_text describe_state_change (const evdesc::state_change &change)
- final override
+ label_text describe_state_change (const evdesc::state_change &change) override
{
if (change.m_new_state == m_sm.m_tainted)
{
@@ -759,6 +767,100 @@ private:
enum memory_space m_mem_space;
};
+/* Concrete taint_diagnostic subclass for reporting attacker-controlled
+ value being used as part of the condition of an assertion. */
+
+class tainted_assertion : public taint_diagnostic
+{
+public:
+ tainted_assertion (const taint_state_machine &sm, tree arg,
+ tree assert_failure_fndecl)
+ : taint_diagnostic (sm, arg, BOUNDS_NONE),
+ m_assert_failure_fndecl (assert_failure_fndecl)
+ {
+ gcc_assert (m_assert_failure_fndecl);
+ }
+
+ const char *get_kind () const final override
+ {
+ return "tainted_assertion";
+ }
+
+ bool subclass_equal_p (const pending_diagnostic &base_other) const override
+ {
+ if (!taint_diagnostic::subclass_equal_p (base_other))
+ return false;
+ const tainted_assertion &other
+ = (const tainted_assertion &)base_other;
+ return m_assert_failure_fndecl == other.m_assert_failure_fndecl;
+ }
+
+ int get_controlling_option () const final override
+ {
+ return OPT_Wanalyzer_tainted_assertion;
+ }
+
+ bool emit (rich_location *rich_loc) final override
+ {
+ diagnostic_metadata m;
+ /* "CWE-617: Reachable Assertion". */
+ m.add_cwe (617);
+
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "use of attacked-controlled value in"
+ " condition for assertion");
+ }
+
+ location_t fixup_location (location_t loc,
+ bool primary) const final override
+ {
+ if (primary)
+ /* For the primary location we want to avoid being in e.g. the
+ <assert.h> system header, since this would suppress the
+ diagnostic. */
+ return expansion_point_location_if_in_system_header (loc);
+ else if (in_system_header_at (loc))
+ /* For events, we want to show the implemenation of the assert
+ macro when we're describing them. */
+ return linemap_resolve_location (line_table, loc,
+ LRK_SPELLING_LOCATION,
+ NULL);
+ else
+ return pending_diagnostic::fixup_location (loc, primary);
+ }
+
+ label_text describe_state_change (const evdesc::state_change &change) override
+ {
+ if (change.m_new_state == m_sm.m_tainted_control_flow)
+ return change.formatted_print
+ ("use of attacker-controlled value for control flow");
+ return taint_diagnostic::describe_state_change (change);
+ }
+
+ label_text describe_final_event (const evdesc::final_event &ev) final override
+ {
+ if (mention_noreturn_attribute_p ())
+ return ev.formatted_print
+ ("treating %qE as an assertion failure handler"
+ " due to %<__attribute__((__noreturn__))%>",
+ m_assert_failure_fndecl);
+ else
+ return ev.formatted_print
+ ("treating %qE as an assertion failure handler",
+ m_assert_failure_fndecl);
+ }
+
+private:
+ bool mention_noreturn_attribute_p () const
+ {
+ if (fndecl_built_in_p (m_assert_failure_fndecl, BUILT_IN_UNREACHABLE))
+ return false;
+ return true;
+ }
+
+ tree m_assert_failure_fndecl;
+};
+
/* taint_state_machine's ctor. */
taint_state_machine::taint_state_machine (logger *logger)
@@ -768,6 +870,7 @@ taint_state_machine::taint_state_machine (logger *logger)
m_has_lb = add_state ("has_lb");
m_has_ub = add_state ("has_ub");
m_stop = add_state ("stop");
+ m_tainted_control_flow = add_state ("tainted-control-flow");
}
state_machine::state_t
@@ -808,6 +911,15 @@ taint_state_machine::alt_get_inherited_state (const sm_state_map &map,
{
default:
break;
+
+ case EQ_EXPR:
+ case GE_EXPR:
+ case LE_EXPR:
+ case NE_EXPR:
+ case GT_EXPR:
+ case LT_EXPR:
+ case UNORDERED_EXPR:
+ case ORDERED_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
case MULT_EXPR:
@@ -821,17 +933,6 @@ taint_state_machine::alt_get_inherited_state (const sm_state_map &map,
}
break;
- case EQ_EXPR:
- case GE_EXPR:
- case LE_EXPR:
- case NE_EXPR:
- case GT_EXPR:
- case LT_EXPR:
- case UNORDERED_EXPR:
- case ORDERED_EXPR:
- /* Comparisons are just booleans. */
- return m_start;
-
case BIT_AND_EXPR:
case RSHIFT_EXPR:
return NULL;
@@ -842,6 +943,19 @@ taint_state_machine::alt_get_inherited_state (const sm_state_map &map,
return NULL;
}
+/* Return true iff FNDECL should be considered to be an assertion failure
+ handler by -Wanalyzer-tainted-assertion. */
+
+static bool
+is_assertion_failure_handler_p (tree fndecl)
+{
+ // i.e. "noreturn"
+ if (TREE_THIS_VOLATILE (fndecl))
+ return true;
+
+ return false;
+}
+
/* Implementation of state_machine::on_stmt vfunc for taint_state_machine. */
bool
@@ -869,6 +983,14 @@ taint_state_machine::on_stmt (sm_context *sm_ctxt,
/* External function with "access" attribute. */
if (sm_ctxt->unknown_side_effects_p ())
check_for_tainted_size_arg (sm_ctxt, node, call, callee_fndecl);
+
+ if (is_assertion_failure_handler_p (callee_fndecl)
+ && sm_ctxt->get_global_state () == m_tainted_control_flow)
+ {
+ sm_ctxt->warn (node, call, NULL_TREE,
+ make_unique<tainted_assertion> (*this, NULL_TREE,
+ callee_fndecl));
+ }
}
// TODO: ...etc; many other sources of untrusted data
@@ -895,9 +1017,46 @@ taint_state_machine::on_stmt (sm_context *sm_ctxt,
}
}
+ if (const gcond *cond = dyn_cast <const gcond *> (stmt))
+ {
+ /* Reset the state of "tainted-control-flow" before each
+ control flow statement, so that only the last one before
+ an assertion-failure-handler counts. */
+ sm_ctxt->set_global_state (m_start);
+ check_control_flow_arg_for_taint (sm_ctxt, cond, gimple_cond_lhs (cond));
+ check_control_flow_arg_for_taint (sm_ctxt, cond, gimple_cond_rhs (cond));
+ }
+
+ if (const gswitch *switch_ = dyn_cast <const gswitch *> (stmt))
+ {
+ /* Reset the state of "tainted-control-flow" before each
+ control flow statement, so that only the last one before
+ an assertion-failure-handler counts. */
+ sm_ctxt->set_global_state (m_start);
+ check_control_flow_arg_for_taint (sm_ctxt, switch_,
+ gimple_switch_index (switch_));
+ }
+
return false;
}
+/* If EXPR is tainted, mark this execution path with the
+ "tainted-control-flow" global state, in case we're about
+ to call an assertion-failure-handler. */
+
+void
+taint_state_machine::check_control_flow_arg_for_taint (sm_context *sm_ctxt,
+ const gimple *stmt,
+ tree expr) const
+{
+ const region_model *old_model = sm_ctxt->get_old_region_model ();
+ const svalue *sval = old_model->get_rvalue (expr, NULL);
+ state_t state = sm_ctxt->get_state (stmt, sval);
+ enum bounds b;
+ if (get_taint (state, TREE_TYPE (expr), &b))
+ sm_ctxt->set_global_state (m_tainted_control_flow);
+}
+
/* Implementation of state_machine::on_condition vfunc for taint_state_machine.
Potentially transition state 'tainted' to 'has_ub' or 'has_lb',
and states 'has_ub' and 'has_lb' to 'stop'. */
@@ -1163,10 +1322,11 @@ taint_state_machine::check_for_tainted_size_arg (sm_context *sm_ctxt,
TREE_STRING_POINTER (access->to_external_string ());
tree diag_size = sm_ctxt->get_diagnostic_tree (size_arg);
sm_ctxt->warn (node, call, size_arg,
- new tainted_access_attrib_size (*this, diag_size, b,
- callee_fndecl,
- access->sizarg,
- access_str));
+ make_unique<tainted_access_attrib_size>
+ (*this, diag_size, b,
+ callee_fndecl,
+ access->sizarg,
+ access_str));
}
}
}
@@ -1201,7 +1361,7 @@ taint_state_machine::check_for_tainted_divisor (sm_context *sm_ctxt,
tree diag_divisor = sm_ctxt->get_diagnostic_tree (divisor_expr);
sm_ctxt->warn (node, assign, divisor_expr,
- new tainted_divisor (*this, diag_divisor, b));
+ make_unique <tainted_divisor> (*this, diag_divisor, b));
sm_ctxt->set_next_state (assign, divisor_sval, m_stop);
}
}
@@ -1264,7 +1424,7 @@ region_model::check_region_for_taint (const region *reg,
if (taint_sm.get_taint (state, index->get_type (), &b))
{
tree arg = get_representative_tree (index);
- ctxt->warn (new tainted_array_index (taint_sm, arg, b));
+ ctxt->warn (make_unique<tainted_array_index> (taint_sm, arg, b));
}
}
break;
@@ -1286,7 +1446,7 @@ region_model::check_region_for_taint (const region *reg,
if (taint_sm.get_taint (state, effective_type, &b))
{
tree arg = get_representative_tree (offset);
- ctxt->warn (new tainted_offset (taint_sm, arg, b));
+ ctxt->warn (make_unique<tainted_offset> (taint_sm, arg, b));
}
}
break;
@@ -1311,7 +1471,7 @@ region_model::check_region_for_taint (const region *reg,
if (taint_sm.get_taint (state, size_sval->get_type (), &b))
{
tree arg = get_representative_tree (size_sval);
- ctxt->warn (new tainted_size (taint_sm, arg, b));
+ ctxt->warn (make_unique<tainted_size> (taint_sm, arg, b));
}
}
break;
@@ -1357,7 +1517,8 @@ region_model::check_dynamic_size_for_taint (enum memory_space mem_space,
if (taint_sm.get_taint (state, size_in_bytes->get_type (), &b))
{
tree arg = get_representative_tree (size_in_bytes);
- ctxt->warn (new tainted_allocation_size (taint_sm, arg, b, mem_space));
+ ctxt->warn (make_unique<tainted_allocation_size>
+ (taint_sm, arg, b, mem_space));
}
}
diff --git a/gcc/analyzer/sm.cc b/gcc/analyzer/sm.cc
index 1ab4c21..1f329cb 100644
--- a/gcc/analyzer/sm.cc
+++ b/gcc/analyzer/sm.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
@@ -39,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/store.h"
#include "analyzer/svalue.h"
#include "analyzer/program-state.h"
+#include "analyzer/pending-diagnostic.h"
#if ENABLE_ANALYZER
@@ -121,6 +123,14 @@ state_machine::get_state_by_name (const char *name) const
gcc_unreachable ();
}
+/* Base implementation of state_machine::on_leak. */
+
+std::unique_ptr<pending_diagnostic>
+state_machine::on_leak (tree var ATTRIBUTE_UNUSED) const
+{
+ return NULL;
+}
+
/* Dump a multiline representation of this state machine to PP. */
void
diff --git a/gcc/analyzer/sm.h b/gcc/analyzer/sm.h
index 87ab11c..085a3a1 100644
--- a/gcc/analyzer/sm.h
+++ b/gcc/analyzer/sm.h
@@ -117,16 +117,20 @@ public:
{
}
+ virtual void
+ on_pop_frame (sm_state_map *smap ATTRIBUTE_UNUSED,
+ const frame_region *frame_reg ATTRIBUTE_UNUSED) const
+ {
+ }
+
/* Return true if it safe to discard the given state (to help
when simplifying state objects).
States that need leak detection should return false. */
virtual bool can_purge_p (state_t s) const = 0;
/* Called when VAR leaks (and !can_purge_p). */
- virtual pending_diagnostic *on_leak (tree var ATTRIBUTE_UNUSED) const
- {
- return NULL;
- }
+ virtual std::unique_ptr<pending_diagnostic>
+ on_leak (tree var ATTRIBUTE_UNUSED) const;
/* Return true if S should be reset to "start" for values passed (or reachable
from) calls to unknown functions. IS_MUTABLE is true for pointers as
@@ -141,6 +145,31 @@ public:
return is_mutable;
}
+ /* Attempt to get a state for the merger of STATE_A and STATE_B,
+ or return NULL if merging shouldn't occur, so that differences
+ between sm-state will lead to separate exploded nodes.
+
+ Most state machines will only merge equal states, but can
+ override maybe_get_merged_states_nonequal to support mergers
+ of certain non-equal states. */
+ state_t maybe_get_merged_state (state_t state_a,
+ state_t state_b) const
+ {
+ if (state_a == state_b)
+ return state_a;
+ return maybe_get_merged_states_nonequal (state_a, state_b);
+ }
+
+ /* Base implementation of hook for maybe_get_merged_state on non-equal
+ states. */
+ virtual state_t
+ maybe_get_merged_states_nonequal (state_t state_a ATTRIBUTE_UNUSED,
+ state_t state_b ATTRIBUTE_UNUSED) const
+ {
+ /* By default, non-equal sm states should inhibit merger of enodes. */
+ return NULL;
+ }
+
void validate (state_t s) const;
void dump_to_pp (pretty_printer *pp) const;
@@ -250,9 +279,11 @@ public:
/* 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,
- tree var, pending_diagnostic *d) = 0;
+ tree var,
+ std::unique_ptr<pending_diagnostic> d) = 0;
virtual void warn (const supernode *node, const gimple *stmt,
- const svalue *var, pending_diagnostic *d) = 0;
+ const svalue *var,
+ std::unique_ptr<pending_diagnostic> d) = 0;
/* For use when generating trees when creating pending_diagnostics, so that
rather than e.g.
diff --git a/gcc/analyzer/state-purge.cc b/gcc/analyzer/state-purge.cc
index d3f516a..e9bcb4b 100644
--- a/gcc/analyzer/state-purge.cc
+++ b/gcc/analyzer/state-purge.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
@@ -812,7 +813,11 @@ same_binding_p (const region *reg_a, const region *reg_b,
{
if (reg_a->get_base_region () != reg_b->get_base_region ())
return false;
+ if (reg_a->empty_p ())
+ return false;
const binding_key *bind_key_a = binding_key::make (store_mgr, reg_a);
+ if (reg_b->empty_p ())
+ return false;
const binding_key *bind_key_b = binding_key::make (store_mgr, reg_b);
return bind_key_a == bind_key_b;
}
diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index 2631ea2..dd8ebaa 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
@@ -126,8 +127,12 @@ binding_key::make (store_manager *mgr, const region *r)
{
bit_size_t bit_size;
if (r->get_bit_size (&bit_size))
- return mgr->get_concrete_binding (offset.get_bit_offset (),
- bit_size);
+ {
+ /* Must be non-empty. */
+ gcc_assert (bit_size > 0);
+ return mgr->get_concrete_binding (offset.get_bit_offset (),
+ bit_size);
+ }
else
return mgr->get_symbolic_binding (r);
}
@@ -1463,6 +1468,9 @@ binding_cluster::mark_region_as_unknown (store_manager *mgr,
const region *reg_for_overlap,
uncertainty_t *uncertainty)
{
+ if (reg_to_bind->empty_p ())
+ return;
+
remove_overlapping_bindings (mgr, reg_for_overlap, uncertainty);
/* Add a default binding to "unknown". */
@@ -1515,6 +1523,8 @@ const svalue *
binding_cluster::get_binding (store_manager *mgr,
const region *reg) const
{
+ if (reg->empty_p ())
+ return NULL;
const binding_key *reg_binding = binding_key::make (mgr, reg);
const svalue *sval = m_map.get (reg_binding);
if (sval)
@@ -1799,6 +1809,8 @@ binding_cluster::remove_overlapping_bindings (store_manager *mgr,
const region *reg,
uncertainty_t *uncertainty)
{
+ if (reg->empty_p ())
+ return;
const binding_key *reg_binding = binding_key::make (mgr, reg);
const region *cluster_base_reg = get_base_region ();
@@ -2006,11 +2018,14 @@ binding_cluster::on_unknown_fncall (const gcall *call,
{
m_map.empty ();
- /* Bind it to a new "conjured" value using CALL. */
- const svalue *sval
- = mgr->get_svalue_manager ()->get_or_create_conjured_svalue
+ if (!m_base_region->empty_p ())
+ {
+ /* Bind it to a new "conjured" value using CALL. */
+ const svalue *sval
+ = mgr->get_svalue_manager ()->get_or_create_conjured_svalue
(m_base_region->get_type (), call, m_base_region, p);
- bind (mgr, m_base_region, sval);
+ bind (mgr, m_base_region, sval);
+ }
m_touched = true;
}
@@ -2035,6 +2050,17 @@ binding_cluster::on_asm (const gasm *stmt,
m_touched = true;
}
+/* Return true if this cluster has escaped. */
+
+bool
+binding_cluster::escaped_p () const
+{
+ /* Consider the "errno" region to always have escaped. */
+ if (m_base_region->get_kind () == RK_ERRNO)
+ return true;
+ return m_escaped;
+}
+
/* Return true if this binding_cluster has no information
i.e. if there are no bindings, and it hasn't been marked as having
escaped, or touched symbolically. */
@@ -2730,6 +2756,10 @@ store::purge_region (store_manager *mgr, const region *reg)
void
store::fill_region (store_manager *mgr, const region *reg, const svalue *sval)
{
+ /* Filling an empty region is a no-op. */
+ if (reg->empty_p ())
+ return;
+
const region *base_reg = reg->get_base_region ();
if (base_reg->symbolic_for_unknown_ptr_p ()
|| !base_reg->tracked_p ())
@@ -2945,6 +2975,10 @@ store::escaped_p (const region *base_reg) const
gcc_assert (base_reg);
gcc_assert (base_reg->get_base_region () == base_reg);
+ /* "errno" can always be modified by external code. */
+ if (base_reg->get_kind () == RK_ERRNO)
+ return true;
+
if (binding_cluster **cluster_slot
= const_cast <cluster_map_t &>(m_cluster_map).get (base_reg))
return (*cluster_slot)->escaped_p ();
@@ -3053,6 +3087,15 @@ store::canonicalize (store_manager *mgr)
binding_cluster *cluster = (*iter).second;
if (base_reg->get_kind () == RK_HEAP_ALLOCATED)
{
+ /* Don't purge a heap-allocated region that's been marked as
+ escaping, since this could be recording that a ptr to it
+ was written to an unknown symbolic region along this
+ path, and so we don't know whether it's referenced or
+ not, and hence should report it as leaking
+ (PR analyzer/106473). */
+ if (cluster->escaped_p ())
+ continue;
+
if (cluster->empty_p ())
if (!s.m_regs.contains (base_reg))
purgeable_regions.add (base_reg);
@@ -3191,6 +3234,7 @@ store::replay_call_summary_cluster (call_summary_replay &r,
case RK_CODE:
case RK_STACK:
case RK_HEAP:
+ case RK_THREAD_LOCAL:
case RK_ROOT:
/* Child regions. */
case RK_FIELD:
@@ -3241,6 +3285,7 @@ store::replay_call_summary_cluster (call_summary_replay &r,
case RK_HEAP_ALLOCATED:
case RK_DECL:
+ case RK_ERRNO:
{
const region *caller_dest_reg
= r.convert_region_from_summary (summary_base_reg);
diff --git a/gcc/analyzer/store.h b/gcc/analyzer/store.h
index 1087782..30284eb 100644
--- a/gcc/analyzer/store.h
+++ b/gcc/analyzer/store.h
@@ -356,8 +356,8 @@ struct byte_range
byte_size_t m_size_in_bytes;
};
-/* Concrete subclass of binding_key, for describing a concrete range of
- bits within the binding_map (e.g. "bits 8-15"). */
+/* Concrete subclass of binding_key, for describing a non-empty
+ concrete range of bits within the binding_map (e.g. "bits 8-15"). */
class concrete_binding : public binding_key
{
@@ -367,7 +367,9 @@ public:
concrete_binding (bit_offset_t start_bit_offset, bit_size_t size_in_bits)
: m_bit_range (start_bit_offset, size_in_bits)
- {}
+ {
+ gcc_assert (!m_bit_range.empty_p ());
+ }
bool concrete_p () const final override { return true; }
hashval_t hash () const
@@ -644,7 +646,7 @@ public:
void on_asm (const gasm *stmt, store_manager *mgr,
const conjured_purge &p);
- bool escaped_p () const { return m_escaped; }
+ bool escaped_p () const;
bool touched_p () const { return m_touched; }
bool redundant_p () const;
diff --git a/gcc/analyzer/supergraph.cc b/gcc/analyzer/supergraph.cc
index 0e9a325..8195fe8 100644
--- a/gcc/analyzer/supergraph.cc
+++ b/gcc/analyzer/supergraph.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
diff --git a/gcc/analyzer/svalue.cc b/gcc/analyzer/svalue.cc
index 4b00a81..aa03b04 100644
--- a/gcc/analyzer/svalue.cc
+++ b/gcc/analyzer/svalue.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
diff --git a/gcc/analyzer/trimmed-graph.cc b/gcc/analyzer/trimmed-graph.cc
index 9fdb4a9..9a42248 100644
--- a/gcc/analyzer/trimmed-graph.cc
+++ b/gcc/analyzer/trimmed-graph.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
diff --git a/gcc/analyzer/varargs.cc b/gcc/analyzer/varargs.cc
index e4dbad7..1a3bdde 100644
--- a/gcc/analyzer/varargs.cc
+++ b/gcc/analyzer/varargs.cc
@@ -19,8 +19,10 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
+#include "make-unique.h"
#include "tree.h"
#include "function.h"
#include "basic-block.h"
@@ -40,6 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/diagnostic-manager.h"
#include "analyzer/exploded-graph.h"
#include "diagnostic-metadata.h"
+#include "analyzer/call-details.h"
#if ENABLE_ANALYZER
@@ -212,9 +215,9 @@ public:
{
return s != m_started;
}
- pending_diagnostic *on_leak (tree var) const final override;
+ std::unique_ptr<pending_diagnostic> on_leak (tree var) const final override;
- /* State for a va_list that the result of a va_start or va_copy. */
+ /* State for a va_list that is the result of a va_start or va_copy. */
state_t m_started;
/* State for a va_list that has had va_end called on it. */
@@ -553,8 +556,8 @@ va_list_state_machine::check_for_ended_va_list (sm_context *sm_ctxt,
{
if (sm_ctxt->get_state (call, arg) == m_ended)
sm_ctxt->warn (node, call, arg,
- new va_list_use_after_va_end (*this, arg, NULL_TREE,
- usage_fnname));
+ make_unique<va_list_use_after_va_end>
+ (*this, arg, NULL_TREE, usage_fnname));
}
/* Get the svalue with associated va_list_state_machine state for
@@ -629,10 +632,10 @@ va_list_state_machine::on_va_end (sm_context *sm_ctxt,
/* Implementation of state_machine::on_leak vfunc for va_list_state_machine
(for complaining about leaks of values in state 'started'). */
-pending_diagnostic *
+std::unique_ptr<pending_diagnostic>
va_list_state_machine::on_leak (tree var) const
{
- return new va_list_leak (*this, NULL, var);
+ return make_unique<va_list_leak> (*this, NULL, var);
}
} // anonymous namespace
@@ -645,33 +648,45 @@ make_va_list_state_machine (logger *logger)
return new va_list_state_machine (logger);
}
-/* Handle the on_call_pre part of "__builtin_va_start". */
+/* Handler for "__builtin_va_start". */
+
+class kf_va_start : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &) const final override
+ {
+ return true;
+ }
+ void impl_call_pre (const call_details &cd) const final override;
+};
void
-region_model::impl_call_va_start (const call_details &cd)
+kf_va_start::impl_call_pre (const call_details &cd) const
{
+ region_model *model = cd.get_model ();
+ region_model_manager *mgr = cd.get_manager ();
const svalue *out_ptr = cd.get_arg_svalue (0);
const region *out_reg
- = deref_rvalue (out_ptr, cd.get_arg_tree (0), cd.get_ctxt ());
+ = model->deref_rvalue (out_ptr, cd.get_arg_tree (0), cd.get_ctxt ());
+ const frame_region *frame = model->get_current_frame ();
/* "*out_ptr = &IMPL_REGION;". */
- const region *impl_reg = m_mgr->create_region_for_alloca (m_current_frame);
+ const region *impl_reg = mgr->create_region_for_alloca (frame);
/* We abuse the types here, since va_list_type isn't
necessarily anything to do with a pointer. */
- const svalue *ptr_to_impl_reg = m_mgr->get_ptr_svalue (NULL_TREE, impl_reg);
- set_value (out_reg, ptr_to_impl_reg, cd.get_ctxt ());
+ const svalue *ptr_to_impl_reg = mgr->get_ptr_svalue (NULL_TREE, impl_reg);
+ model->set_value (out_reg, ptr_to_impl_reg, cd.get_ctxt ());
- if (get_stack_depth () > 1)
+ if (model->get_stack_depth () > 1)
{
/* The interprocedural case: the frame containing the va_start call
will have been populated with any variadic aruguments.
Initialize IMPL_REGION with a ptr to var_arg_region 0. */
- const region *init_var_arg_reg
- = m_mgr->get_var_arg_region (get_current_frame (), 0);
+ const region *init_var_arg_reg = mgr->get_var_arg_region (frame, 0);
const svalue *ap_sval
- = m_mgr->get_ptr_svalue (NULL_TREE, init_var_arg_reg);
- set_value (impl_reg, ap_sval, cd.get_ctxt ());
+ = mgr->get_ptr_svalue (NULL_TREE, init_var_arg_reg);
+ model->set_value (impl_reg, ap_sval, cd.get_ctxt ());
}
else
{
@@ -680,40 +695,52 @@ region_model::impl_call_va_start (const call_details &cd)
Initialize IMPL_REGION as the UNKNOWN_SVALUE to avoid state
explosions on repeated calls to va_arg. */
const svalue *unknown_sval
- = m_mgr->get_or_create_unknown_svalue (NULL_TREE);
- set_value (impl_reg, unknown_sval, cd.get_ctxt ());
+ = mgr->get_or_create_unknown_svalue (NULL_TREE);
+ model->set_value (impl_reg, unknown_sval, cd.get_ctxt ());
}
}
-/* Handle the on_call_pre part of "__builtin_va_copy". */
+/* Handler for "__builtin_va_copy". */
+
+class kf_va_copy : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &) const final override
+ {
+ return true;
+ }
+ void impl_call_pre (const call_details &cd) const final override;
+};
void
-region_model::impl_call_va_copy (const call_details &cd)
+kf_va_copy::impl_call_pre (const call_details &cd) const
{
+ region_model *model = cd.get_model ();
+ region_model_manager *mgr = cd.get_manager ();
const svalue *out_dst_ptr = cd.get_arg_svalue (0);
const svalue *in_va_list
- = get_va_copy_arg (this, cd.get_ctxt (), cd.get_call_stmt (), 1);
- in_va_list = check_for_poison (in_va_list,
- get_va_list_diag_arg (cd.get_arg_tree (1)),
- cd.get_ctxt ());
+ = get_va_copy_arg (model, cd.get_ctxt (), cd.get_call_stmt (), 1);
+ in_va_list
+ = model->check_for_poison (in_va_list,
+ get_va_list_diag_arg (cd.get_arg_tree (1)),
+ cd.get_ctxt ());
const region *out_dst_reg
- = deref_rvalue (out_dst_ptr, cd.get_arg_tree (0), cd.get_ctxt ());
+ = model->deref_rvalue (out_dst_ptr, cd.get_arg_tree (0), cd.get_ctxt ());
/* "*out_dst_ptr = &NEW_IMPL_REGION;". */
const region *new_impl_reg
- = m_mgr->create_region_for_alloca (m_current_frame);
+ = mgr->create_region_for_alloca (model->get_current_frame ());
const svalue *ptr_to_new_impl_reg
- = m_mgr->get_ptr_svalue (NULL_TREE, new_impl_reg);
- set_value (out_dst_reg, ptr_to_new_impl_reg, cd.get_ctxt ());
+ = mgr->get_ptr_svalue (NULL_TREE, new_impl_reg);
+ model->set_value (out_dst_reg, ptr_to_new_impl_reg, cd.get_ctxt ());
if (const region *old_impl_reg = in_va_list->maybe_get_region ())
{
-
/* "(NEW_IMPL_REGION) = (OLD_IMPL_REGION);". */
const svalue *existing_sval
- = get_store_value (old_impl_reg, cd.get_ctxt ());
- set_value (new_impl_reg, existing_sval, cd.get_ctxt ());
+ = model->get_store_value (old_impl_reg, cd.get_ctxt ());
+ model->set_value (new_impl_reg, existing_sval, cd.get_ctxt ());
}
}
@@ -751,9 +778,9 @@ public:
{
public:
va_arg_call_event (const exploded_edge &eedge,
- location_t loc, tree fndecl, int depth,
+ const event_loc_info &loc_info,
int num_variadic_arguments)
- : call_event (eedge, loc, fndecl, depth),
+ : call_event (eedge, loc_info),
m_num_variadic_arguments (num_variadic_arguments)
{
}
@@ -786,13 +813,12 @@ public:
= get_num_variadic_arguments (dst_node->get_function ()->decl,
call_stmt);
emission_path->add_event
- (new va_arg_call_event (eedge,
- (last_stmt
- ? last_stmt->location
- : UNKNOWN_LOCATION),
- src_point.get_fndecl (),
- src_stack_depth,
- num_variadic_arguments));
+ (make_unique<va_arg_call_event>
+ (eedge,
+ event_loc_info (last_stmt ? last_stmt->location : UNKNOWN_LOCATION,
+ src_point.get_fndecl (),
+ src_stack_depth),
+ num_variadic_arguments));
}
else
pending_diagnostic::add_call_event (eedge, emission_path);
@@ -954,26 +980,35 @@ maybe_get_var_arg_region (const svalue *ap_sval)
return NULL;
}
-/* Handle the on_call_pre part of "__builtin_va_arg". */
+/* Handler for "__builtin_va_arg". */
+
+class kf_va_arg : public internal_known_function
+{
+public:
+ void impl_call_pre (const call_details &cd) const final override;
+};
void
-region_model::impl_call_va_arg (const call_details &cd)
+kf_va_arg::impl_call_pre (const call_details &cd) const
{
region_model_context *ctxt = cd.get_ctxt ();
+ region_model *model = cd.get_model ();
+ region_model_manager *mgr = cd.get_manager ();
const svalue *in_ptr = cd.get_arg_svalue (0);
- const region *ap_reg = deref_rvalue (in_ptr, cd.get_arg_tree (0), ctxt);
+ const region *ap_reg
+ = model->deref_rvalue (in_ptr, cd.get_arg_tree (0), ctxt);
- const svalue *ap_sval = get_store_value (ap_reg, ctxt);
+ const svalue *ap_sval = model->get_store_value (ap_reg, ctxt);
if (const svalue *cast = ap_sval->maybe_undo_cast ())
ap_sval = cast;
tree va_list_tree = get_va_list_diag_arg (cd.get_arg_tree (0));
- ap_sval = check_for_poison (ap_sval, va_list_tree, ctxt);
+ ap_sval = model->check_for_poison (ap_sval, va_list_tree, ctxt);
if (const region *impl_reg = ap_sval->maybe_get_region ())
{
- const svalue *old_impl_sval = get_store_value (impl_reg, ctxt);
+ const svalue *old_impl_sval = model->get_store_value (impl_reg, ctxt);
if (const var_arg_region *arg_reg
= maybe_get_var_arg_region (old_impl_sval))
{
@@ -990,8 +1025,8 @@ region_model::impl_call_va_arg (const call_details &cd)
has a conjured_svalue), or warn if there's a problem
(incompatible types, or if we've run out of args). */
if (const svalue *arg_sval
- = m_store.get_any_binding (m_mgr->get_store_manager (),
- arg_reg))
+ = model->get_store ()->get_any_binding
+ (mgr->get_store_manager (), arg_reg))
{
tree lhs_type = cd.get_lhs_type ();
tree arg_type = arg_sval->get_type ();
@@ -1000,17 +1035,19 @@ region_model::impl_call_va_arg (const call_details &cd)
else
{
if (ctxt)
- ctxt->warn (new va_arg_type_mismatch (va_list_tree,
- arg_reg,
- lhs_type,
- arg_type));
+ ctxt->warn (make_unique <va_arg_type_mismatch>
+ (va_list_tree,
+ arg_reg,
+ lhs_type,
+ arg_type));
saw_problem = true;
}
}
else
{
if (ctxt)
- ctxt->warn (new va_list_exhausted (va_list_tree, arg_reg));
+ ctxt->warn (make_unique <va_list_exhausted> (va_list_tree,
+ arg_reg));
saw_problem = true;
}
}
@@ -1027,28 +1064,42 @@ region_model::impl_call_va_arg (const call_details &cd)
{
/* Set impl_reg to UNKNOWN to suppress further warnings. */
const svalue *new_ap_sval
- = m_mgr->get_or_create_unknown_svalue (impl_reg->get_type ());
- set_value (impl_reg, new_ap_sval, ctxt);
+ = mgr->get_or_create_unknown_svalue (impl_reg->get_type ());
+ model->set_value (impl_reg, new_ap_sval, ctxt);
}
else
{
/* Update impl_reg to advance to the next arg. */
const region *next_var_arg_region
- = m_mgr->get_var_arg_region (frame_reg, next_arg_idx + 1);
+ = mgr->get_var_arg_region (frame_reg, next_arg_idx + 1);
const svalue *new_ap_sval
- = m_mgr->get_ptr_svalue (NULL_TREE, next_var_arg_region);
- set_value (impl_reg, new_ap_sval, ctxt);
+ = mgr->get_ptr_svalue (NULL_TREE, next_var_arg_region);
+ model->set_value (impl_reg, new_ap_sval, ctxt);
}
}
}
}
-/* Handle the on_call_post part of "__builtin_va_end". */
+/* Handler for "__builtin_va_end". */
+
+class kf_va_end : public known_function
+{
+public:
+ bool matches_call_types_p (const call_details &) const
+ {
+ return true;
+ }
+};
+
+/* Populate KFM with instances of known functions relating to varargs. */
void
-region_model::impl_call_va_end (const call_details &)
+register_varargs_builtins (known_function_manager &kfm)
{
- /* No-op. */
+ kfm.add (BUILT_IN_VA_START, make_unique<kf_va_start> ());
+ kfm.add (BUILT_IN_VA_COPY, make_unique<kf_va_copy> ());
+ kfm.add (IFN_VA_ARG, make_unique<kf_va_arg> ());
+ kfm.add (BUILT_IN_VA_END, make_unique<kf_va_end> ());
}
} // namespace ana
diff --git a/gcc/analyzer/varargs.dot b/gcc/analyzer/varargs.dot
new file mode 100644
index 0000000..b456c96
--- /dev/null
+++ b/gcc/analyzer/varargs.dot
@@ -0,0 +1,56 @@
+/* An overview of the state machine from varargs.cc
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* Keep this in-sync with varargs.cc */
+
+digraph "va_list" {
+
+ /* STATES. */
+
+ /* Start state. */
+ start;
+
+ /* State for a va_list that is the result of a va_start or va_copy. */
+ started;
+
+ /* State for a va_list that has had va_end called on it. */
+ ended;
+
+ /* TRANSITIONS. */
+
+ /* on_va_start: */
+ start -> started [label="on 'va_start(X, ...)'"];
+
+ /* on_va_copy: */
+ start -> started [label="on 'va_copy(X, ...)'"];
+ // in check_for_ended_va_list:
+ ended -> ended [label="on 'va_copy(X, ...)':\nWarn('use after va_end')"];
+
+ /* on_va_arg: */
+ started -> started [label="on 'va_arg(X, ...)'"];
+ started -> started [label="on 'va_copy(..., X)'"];
+ // in check_for_ended_va_list:
+ ended -> ended [label="on 'va_arg(X, ...)':\nWarn('use after va_end')"];
+
+ /* on_va_end: */
+ started -> ended [label="on 'va_end(X)'"];
+ // in check_for_ended_va_list:
+ ended -> ended [label="on 'va_end(X)':\nWarn('use after va_end')"];
+}
diff --git a/gcc/asan.cc b/gcc/asan.cc
index 8276f12..dc7b7f4 100644
--- a/gcc/asan.cc
+++ b/gcc/asan.cc
@@ -64,6 +64,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-inline.h"
#include "tree-ssa.h"
#include "tree-eh.h"
+#include "diagnostic-core.h"
/* AddressSanitizer finds out-of-bounds and use-after-free bugs
with <2x slowdown on average.
@@ -1818,6 +1819,11 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
tree str_cst, decl, id;
int use_after_return_class = -1;
+ /* Don't emit anything when doing error recovery, the assertions
+ might fail e.g. if a function had a frame offset overflow. */
+ if (seen_error ())
+ return NULL;
+
if (shadow_ptr_types[0] == NULL_TREE)
asan_init_shadow_ptr_types ();
diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 27dea74..095def4 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -2456,6 +2456,36 @@ init_attr_rdwr_indices (rdwr_map *rwm, tree attrs)
}
}
+/* Get the LEVEL of the strict_flex_array for the ARRAY_FIELD based on the
+ values of attribute strict_flex_array and the flag_strict_flex_arrays. */
+unsigned int
+strict_flex_array_level_of (tree array_field)
+{
+ gcc_assert (TREE_CODE (array_field) == FIELD_DECL);
+ unsigned int strict_flex_array_level = flag_strict_flex_arrays;
+
+ tree attr_strict_flex_array
+ = lookup_attribute ("strict_flex_array", DECL_ATTRIBUTES (array_field));
+ /* If there is a strict_flex_array attribute attached to the field,
+ override the flag_strict_flex_arrays. */
+ if (attr_strict_flex_array)
+ {
+ /* Get the value of the level first from the attribute. */
+ unsigned HOST_WIDE_INT attr_strict_flex_array_level = 0;
+ gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE);
+ attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array);
+ gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE);
+ attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array);
+ gcc_assert (tree_fits_uhwi_p (attr_strict_flex_array));
+ attr_strict_flex_array_level = tree_to_uhwi (attr_strict_flex_array);
+
+ /* The attribute has higher priority than flag_struct_flex_array. */
+ strict_flex_array_level = attr_strict_flex_array_level;
+ }
+ return strict_flex_array_level;
+}
+
+
/* Return the access specification for a function parameter PARM
or null if the current function has no such specification. */
diff --git a/gcc/attribs.h b/gcc/attribs.h
index 1dc16e4..742811e 100644
--- a/gcc/attribs.h
+++ b/gcc/attribs.h
@@ -398,4 +398,6 @@ extern void init_attr_rdwr_indices (rdwr_map *, tree);
extern attr_access *get_parm_access (rdwr_map &, tree,
tree = current_function_decl);
+extern unsigned int strict_flex_array_level_of (tree);
+
#endif // GCC_ATTRIBS_H
diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index b359ce2..02c4fef 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -696,14 +696,14 @@ c_strlen (tree arg, int only_value, c_strlen_data *data, unsigned eltsize)
{
/* Suppress multiple warnings for propagated constant strings. */
if (only_value != 2
- && !warning_suppressed_p (arg, OPT_Warray_bounds)
- && warning_at (loc, OPT_Warray_bounds,
+ && !warning_suppressed_p (arg, OPT_Warray_bounds_)
+ && warning_at (loc, OPT_Warray_bounds_,
"offset %qwi outside bounds of constant string",
eltoff))
{
if (decl)
inform (DECL_SOURCE_LOCATION (decl), "%qE declared here", decl);
- suppress_warning (arg, OPT_Warray_bounds);
+ suppress_warning (arg, OPT_Warray_bounds_);
}
return NULL_TREE;
}
@@ -1931,6 +1931,11 @@ mathfn_built_in_2 (tree type, combined_fn fn)
built_in_function fcodef64x = END_BUILTINS;
built_in_function fcodef128x = END_BUILTINS;
+ /* If <math.h> has been included somehow, HUGE_VAL and NAN definitions
+ break the uses below. */
+#undef HUGE_VAL
+#undef NAN
+
switch (fn)
{
#define SEQ_OF_CASE_MATHFN \
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 32e8fb1..3fb66a7 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,120 @@
+2022-12-02 Andrew MacLeod <amacleod@redhat.com>
+
+ * c-attribs.cc (handle_deprecated_attribute): Use type when
+ using TYPE_NAME.
+
+2022-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/84469
+ * c-omp.cc (c_omp_is_loop_iterator): For range for with structured
+ binding return TREE_VEC_LENGTH (d->declv) even if decl is equal
+ to any of the structured binding decls.
+
+2022-11-30 Iskander Shakirzyanov <iskander@ispras.ru>
+ Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ PR driver/107787
+ * c-common.cc (fold_offsetof,
+ convert_vector_to_array_for_subscript): Use OPT_Warray_bounds_
+ instead of OPT_Warray_bounds.
+
+2022-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ * c.opt (fcontract-role=, fcontract-semantic=): Terminate descriptions
+ with a dot.
+
+2022-11-23 Andrew Pinski <apinski@marvell.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR c/107127
+ * c-gimplify.cc (c_genericize): Use walk_tree_without_duplicates
+ instead of walk_tree for c_genericize_control_r.
+
+2022-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ * c.opt (fcontract-assumption-mode=, fcontract-continuation-mode=,
+ fcontract-role=, fcontract-semantic=): Add RejectNegative.
+ (fcontract-build-level=): Terminate description with dot.
+
+2022-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ * c-cppbuiltin.cc (c_cpp_builtins): Bump __cpp_constexpr
+ value from 202207L to 202211L.
+
+2022-11-19 Jeff Chapman II <jchapman@lock3software.com>
+ Andrew Sutton <asutton@lock3software.com>
+ Andrew Marmaduke <amarmaduke@lock3software.com>
+ Michael Lopez <mlopez@lock3software.com>
+ Jason Merrill <jason@redhat.com>
+
+ * c.opt: Add contracts flags.
+ * c-cppbuiltin.cc (c_cpp_builtins): Add contracts feature-test
+ macros.
+
+2022-11-16 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106649
+ * c-cppbuiltin.cc (c_cpp_builtins): Update value of __cpp_constexpr for
+ C++23.
+ * c-opts.cc (c_common_post_options): Set warn_invalid_constexpr
+ depending on cxx_dialect.
+ * c.opt (Winvalid-constexpr): New option.
+
+2022-11-16 Jakub Jelinek <jakub@redhat.com>
+
+ * c-common.def (CONCEPT_DECL): New tree, moved here from
+ cp-tree.def.
+ * c-common.cc (c_common_init_ts): Handle CONCEPT_DECL.
+ * c-attribs.cc (handle_deprecated_attribute): Allow deprecated
+ attribute on CONCEPT_DECL.
+
+2022-11-15 Lewis Hyatt <lhyatt@gmail.com>
+
+ * c-opts.cc (c_finish_options): Use special_fname_builtin () rather
+ than a hard-coded string.
+
+2022-11-15 Jakub Jelinek <jakub@redhat.com>
+
+ * c-cppbuiltin.cc (c_cpp_builtins): Bump C++23
+ __cpp_multidimensional_subscript macro value to 202211L.
+
+2022-11-15 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/107638
+ * c-lex.cc (c_common_has_attribute): Return 1 for init_priority
+ iff SUPPORTS_INIT_PRIORITY.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * c-target.def: Port to RST.
+
+2022-11-12 Joseph Myers <joseph@codesourcery.com>
+
+ * c-common.cc (c_common_reswords): Use D_C2X instead of D_CXXONLY.
+
+2022-11-11 Jonathan Wakely <jwakely@redhat.com>
+
+ PR c/85487
+ * c-pragma.cc (handle_pragma_ignore): New function.
+ (init_pragma): Register region and endregion pragmas.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * c-target.def: Port to RST.
+
+2022-11-05 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR preprocessor/55971
+ * c-ppoutput.cc (adjust_for_newlines): Update comment.
+
+2022-11-03 Jason Merrill <jason@redhat.com>
+
+ * c-opts.cc (c_common_post_options): -fconcepts no longer implies
+ -fconcepts-ts before C++20.
+
2022-10-28 Joseph Myers <joseph@codesourcery.com>
* c-common.cc (def_fn_type): Call build_function_type for
@@ -1174,8 +1291,8 @@
PR target/102552
* c-common.c (parse_optimize_options): decoded_options[0] is
- used for program name, so merged_decoded_options should also
- respect that.
+ used for program name, so merged_decoded_options should also
+ respect that.
2021-10-01 Jakub Jelinek <jakub@redhat.com>
Richard Biener <rguenther@suse.de>
@@ -1203,7 +1320,7 @@
2021-09-27 Martin Liska <mliska@suse.cz>
* c-opts.c (c_common_init_options_struct): Set also
- x_flag_default_complex_method.
+ x_flag_default_complex_method.
2021-09-22 Jakub Jelinek <jakub@redhat.com>
@@ -1396,8 +1513,8 @@
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.
+ (gcc_cdiag_char_table): Same.
+ (gcc_cxxdiag_char_table): Same.
2021-07-02 Jakub Jelinek <jakub@redhat.com>
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 92ac93b..b36dd97 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -4211,7 +4211,8 @@ handle_deprecated_attribute (tree *node, tree name,
|| VAR_OR_FUNCTION_DECL_P (decl)
|| TREE_CODE (decl) == FIELD_DECL
|| TREE_CODE (decl) == CONST_DECL
- || objc_method_decl (TREE_CODE (decl)))
+ || objc_method_decl (TREE_CODE (decl))
+ || TREE_CODE (decl) == CONCEPT_DECL)
TREE_DEPRECATED (decl) = 1;
else if (TREE_CODE (decl) == LABEL_DECL)
{
@@ -4239,7 +4240,7 @@ handle_deprecated_attribute (tree *node, tree name,
if (type && TYPE_NAME (type))
{
if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
- what = TYPE_NAME (*node);
+ what = TYPE_NAME (type);
else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
&& DECL_NAME (TYPE_NAME (type)))
what = DECL_NAME (TYPE_NAME (type));
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 5890c18..f08c891 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -440,7 +440,7 @@ const struct c_common_resword c_common_reswords[] =
{ "class", RID_CLASS, D_CXX_OBJC | D_CXXWARN },
{ "const", RID_CONST, 0 },
{ "consteval", RID_CONSTEVAL, D_CXXONLY | D_CXX20 | D_CXXWARN },
- { "constexpr", RID_CONSTEXPR, D_CXXONLY | D_CXX11 | D_CXXWARN },
+ { "constexpr", RID_CONSTEXPR, D_C2X | D_CXX11 | D_CXXWARN },
{ "constinit", RID_CONSTINIT, D_CXXONLY | D_CXX20 | D_CXXWARN },
{ "const_cast", RID_CONSTCAST, D_CXXONLY | D_CXXWARN },
{ "continue", RID_CONTINUE, 0 },
@@ -6811,7 +6811,7 @@ fold_offsetof (tree expr, tree type, enum tree_code ctx)
definition thereof. */
if (TREE_CODE (v) == ARRAY_REF
|| TREE_CODE (v) == COMPONENT_REF)
- warning (OPT_Warray_bounds,
+ warning (OPT_Warray_bounds_,
"index %E denotes an offset "
"greater than size of %qT",
t, TREE_TYPE (TREE_OPERAND (expr, 0)));
@@ -8497,6 +8497,8 @@ c_common_init_ts (void)
MARK_TS_EXP (FOR_STMT);
MARK_TS_EXP (SWITCH_STMT);
MARK_TS_EXP (WHILE_STMT);
+
+ MARK_TS_DECL_COMMON (CONCEPT_DECL);
}
/* Build a user-defined numeric literal out of an integer constant type VALUE
@@ -8532,7 +8534,7 @@ convert_vector_to_array_for_subscript (location_t loc,
if (TREE_CODE (index) == INTEGER_CST)
if (!tree_fits_uhwi_p (index)
|| maybe_ge (tree_to_uhwi (index), TYPE_VECTOR_SUBPARTS (type)))
- warning_at (loc, OPT_Warray_bounds, "index value is out of bound");
+ warning_at (loc, OPT_Warray_bounds_, "index value is out of bound");
/* We are building an ARRAY_REF so mark the vector as addressable
to not run into the gimplifiers premature setting of DECL_GIMPLE_REG_P
diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def
index dd8be7f..64956fc 100644
--- a/gcc/c-family/c-common.def
+++ b/gcc/c-family/c-common.def
@@ -81,6 +81,14 @@ DEFTREECODE (CONTINUE_STMT, "continue_stmt", tcc_statement, 0)
SWITCH_STMT_SCOPE, respectively. */
DEFTREECODE (SWITCH_STMT, "switch_stmt", tcc_statement, 4)
+/* Extensions for C++ Concepts. */
+
+/* Concept definition. This is not entirely different than a VAR_DECL
+ except that a) it must be a template, and b) doesn't have the wide
+ range of value and linkage options available to variables. Used
+ by C++ FE and in c-family attribute handling. */
+DEFTREECODE (CONCEPT_DECL, "concept_decl", tcc_declaration, 0)
+
/*
Local variables:
mode:c
diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
index cdb658f..333f3e1 100644
--- a/gcc/c-family/c-cppbuiltin.cc
+++ b/gcc/c-family/c-cppbuiltin.cc
@@ -1074,8 +1074,8 @@ c_cpp_builtins (cpp_reader *pfile)
/* Set feature test macros for C++23. */
cpp_define (pfile, "__cpp_size_t_suffix=202011L");
cpp_define (pfile, "__cpp_if_consteval=202106L");
- cpp_define (pfile, "__cpp_constexpr=202110L");
- cpp_define (pfile, "__cpp_multidimensional_subscript=202110L");
+ cpp_define (pfile, "__cpp_constexpr=202211L");
+ cpp_define (pfile, "__cpp_multidimensional_subscript=202211L");
cpp_define (pfile, "__cpp_named_character_escapes=202207L");
cpp_define (pfile, "__cpp_static_call_operator=202207L");
cpp_define (pfile, "__cpp_implicit_move=202207L");
@@ -1087,6 +1087,12 @@ c_cpp_builtins (cpp_reader *pfile)
else
cpp_define (pfile, "__cpp_concepts=201507L");
}
+ if (flag_contracts)
+ {
+ cpp_define (pfile, "__cpp_contracts=201906L");
+ cpp_define (pfile, "__cpp_contracts_literal_semantics=201906L");
+ cpp_define (pfile, "__cpp_contracts_roles=201906L");
+ }
if (flag_modules)
/* The std-defined value is 201907L, but I don't think we can
claim victory yet. 201810 is the p1103 date. */
diff --git a/gcc/c-family/c-gimplify.cc b/gcc/c-family/c-gimplify.cc
index 039a4b9..0034d41 100644
--- a/gcc/c-family/c-gimplify.cc
+++ b/gcc/c-family/c-gimplify.cc
@@ -572,8 +572,8 @@ c_genericize (tree fndecl)
bc_state_t save_state;
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
save_bc_state (&save_state);
- walk_tree (&DECL_SAVED_TREE (fndecl), c_genericize_control_r,
- NULL, NULL);
+ walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
+ c_genericize_control_r, NULL);
restore_bc_state (&save_state);
pop_cfun ();
}
diff --git a/gcc/c-family/c-lex.cc b/gcc/c-family/c-lex.cc
index 89c65ac..2fe562c 100644
--- a/gcc/c-family/c-lex.cc
+++ b/gcc/c-family/c-lex.cc
@@ -380,6 +380,15 @@ c_common_has_attribute (cpp_reader *pfile, bool std_syntax)
result = 201907;
else if (is_attribute_p ("assume", attr_name))
result = 202207;
+ else if (is_attribute_p ("init_priority", attr_name))
+ {
+ /* The (non-standard) init_priority attribute is always
+ included in the attribute table, but we don't want to
+ advertise the attribute unless the target actually
+ supports init priorities. */
+ result = SUPPORTS_INIT_PRIORITY ? 1 : 0;
+ attr_name = NULL_TREE;
+ }
}
else
{
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index 5bb1035..2ab9911 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -1311,10 +1311,11 @@ c_omp_is_loop_iterator (tree decl, struct c_omp_check_loop_iv_data *d)
else if (TREE_CODE (TREE_VEC_ELT (d->declv, i)) == TREE_LIST
&& TREE_CHAIN (TREE_VEC_ELT (d->declv, i))
&& (TREE_CODE (TREE_CHAIN (TREE_VEC_ELT (d->declv, i)))
- == TREE_VEC)
- && decl == TREE_VEC_ELT (TREE_CHAIN (TREE_VEC_ELT (d->declv,
- i)), 2))
- return TREE_VEC_LENGTH (d->declv);
+ == TREE_VEC))
+ for (int j = 2;
+ j < TREE_VEC_LENGTH (TREE_CHAIN (TREE_VEC_ELT (d->declv, i))); j++)
+ if (decl == TREE_VEC_ELT (TREE_CHAIN (TREE_VEC_ELT (d->declv, i)), j))
+ return TREE_VEC_LENGTH (d->declv);
return -1;
}
diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc
index 32b929e..70745aa 100644
--- a/gcc/c-family/c-opts.cc
+++ b/gcc/c-family/c-opts.cc
@@ -1059,6 +1059,10 @@ c_common_post_options (const char **pfilename)
if (flag_sized_deallocation == -1)
flag_sized_deallocation = (cxx_dialect >= cxx14);
+ /* Pedwarn about invalid constexpr functions before C++23. */
+ if (warn_invalid_constexpr == -1)
+ warn_invalid_constexpr = (cxx_dialect < cxx23);
+
/* char8_t support is implicitly enabled in C++20 and C2X. */
if (flag_char8_t == -1)
flag_char8_t = (cxx_dialect >= cxx20) || flag_isoc2x;
@@ -1090,9 +1094,6 @@ c_common_post_options (const char **pfilename)
work with the standard. */
if (cxx_dialect >= cxx20 || flag_concepts_ts)
flag_concepts = 1;
- else if (flag_concepts)
- /* For -std=c++17 -fconcepts, imply -fconcepts-ts. */
- flag_concepts_ts = 1;
if (num_in_fnames > 1)
error ("too many filenames given; type %<%s %s%> for usage",
@@ -1476,7 +1477,7 @@ c_finish_options (void)
{
const line_map_ordinary *bltin_map
= linemap_check_ordinary (linemap_add (line_table, LC_RENAME, 0,
- _("<built-in>"), 0));
+ special_fname_builtin (), 0));
cb_file_change (parse_in, bltin_map);
linemap_line_start (line_table, 0, 1);
diff --git a/gcc/c-family/c-ppoutput.cc b/gcc/c-family/c-ppoutput.cc
index a99d9e9..6e05435 100644
--- a/gcc/c-family/c-ppoutput.cc
+++ b/gcc/c-family/c-ppoutput.cc
@@ -433,7 +433,15 @@ scan_translation_unit_directives_only (cpp_reader *pfile)
lang_hooks.preprocess_token (pfile, NULL, streamer.filter);
}
-/* Adjust print.src_line for newlines embedded in output. */
+/* Adjust print.src_line for newlines embedded in output. For example, if a raw
+ string literal contains newlines, then we need to increment our notion of the
+ current line to keep in sync and avoid outputting a line marker
+ unnecessarily. If a raw string literal containing newlines is the result of
+ macro expansion, then we have the opposite problem, where the token takes up
+ more lines in the output than it did in the input, and hence a line marker is
+ needed to restore the correct state for subsequent lines. In this case,
+ incrementing print.src_line still does the job, because it will cause us to
+ emit the line marker the next time a token is streamed. */
static void
account_for_newlines (const unsigned char *str, size_t len)
{
diff --git a/gcc/c-family/c-pragma.cc b/gcc/c-family/c-pragma.cc
index b5a4b3c..142a464 100644
--- a/gcc/c-family/c-pragma.cc
+++ b/gcc/c-family/c-pragma.cc
@@ -1403,6 +1403,12 @@ handle_pragma_message (cpp_reader *)
TREE_STRING_POINTER (message));
}
+/* Ignore a no-op pragma that GCC recognizes, but which has no effect. */
+static void
+handle_pragma_ignore (cpp_reader *)
+{
+}
+
/* Mark whether the current location is valid for a STDC pragma. */
static bool valid_location_for_stdc_pragma;
@@ -1870,6 +1876,9 @@ init_pragma (void)
c_register_pragma ("GCC", "pop_options", handle_pragma_pop_options);
c_register_pragma ("GCC", "reset_options", handle_pragma_reset_options);
+ c_register_pragma (0, "region", handle_pragma_ignore);
+ c_register_pragma (0, "endregion", handle_pragma_ignore);
+
c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64",
handle_pragma_float_const_decimal64);
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 63a300e..0d0ad0a 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -817,6 +817,10 @@ Wint-to-pointer-cast
C ObjC C++ ObjC++ Var(warn_int_to_pointer_cast) Init(1) Warning
Warn when there is a cast to a pointer from an integer of a different size.
+Winvalid-constexpr
+C++ ObjC++ Var(warn_invalid_constexpr) Init(-1) Warning
+Warn when a function never produces a constant expression.
+
Winvalid-offsetof
C++ ObjC++ Var(warn_invalid_offsetof) Init(1) Warning
Warn about invalid uses of the \"offsetof\" macro.
@@ -1674,6 +1678,47 @@ fconstexpr-ops-limit=
C++ ObjC++ Joined RejectNegative Host_Wide_Int Var(constexpr_ops_limit) Init(33554432)
-fconstexpr-ops-limit=<number> Specify maximum number of constexpr operations during a single constexpr evaluation.
+fcontracts
+C++ ObjC++ Var(flag_contracts) Init(0)
+Enable certain features present drafts of C++ Contracts.
+
+Enum
+Name(on_off) Type(int) UnknownError(argument %qs must be either %<on%> or %<off%>)
+
+EnumValue
+Enum(on_off) String(off) Value(0)
+
+EnumValue
+Enum(on_off) String(on) Value(1)
+
+fcontract-assumption-mode=
+C++ Joined RejectNegative
+-fcontract-assumption-mode=[on|off] Enable or disable treating axiom level contracts as assumptions (default on).
+
+fcontract-build-level=
+C++ Joined RejectNegative
+-fcontract-build-level=[off|default|audit] Specify max contract level to generate runtime checks for.
+
+fcontract-strict-declarations=
+C++ Var(flag_contract_strict_declarations) Enum(on_off) Joined Init(0) RejectNegative
+-fcontract-strict-declarations=[on|off] Enable or disable warnings on generalized redeclaration of functions with contracts (default off).
+
+fcontract-mode=
+C++ Var(flag_contract_mode) Enum(on_off) Joined Init(1) RejectNegative
+-fcontract-mode=[on|off] Enable or disable all contract facilities (default on).
+
+fcontract-continuation-mode=
+C++ Joined RejectNegative
+-fcontract-continuation-mode=[on|off] Enable or disable contract continuation mode (default off).
+
+fcontract-role=
+C++ Joined RejectNegative
+-fcontract-role=<name>:<semantics> Specify the semantics for all levels in a role (default, review), or a custom contract role with given semantics (ex: opt:assume,assume,assume).
+
+fcontract-semantic=
+C++ Joined RejectNegative
+-fcontract-semantic=<level>:<semantic> Specify the concrete semantics for level.
+
fcoroutines
C++ LTO Var(flag_coroutines)
Enable C++ coroutines (experimental).
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 4e71198..20dbbe3 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,112 @@
+2022-12-07 Joseph Myers <joseph@codesourcery.com>
+
+ * c-decl.cc (declspecs_add_type, declspecs_add_scspec): Check for
+ auto, constexpr and a type used together.
+
+2022-12-06 Qing Zhao <qing.zhao@oracle.com>
+
+ * c-decl.cc (is_flexible_array_member_p): Call new function
+ strict_flex_array_level_of.
+
+2022-11-24 Florian Weimer <fweimer@redhat.com>
+
+ PR c/107805
+ * c-decl.cc (declspecs_add_type): Propagate error_mark_bode
+ from type to specs.
+
+2022-11-17 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
+
+ * c-decl.cc (start_function): Set the result decl source
+ location to the location of the typespec.
+
+2022-11-17 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107711
+ * c-parser.cc (ana::c_translation_unit::consider_macro): Pass NULL
+ to cpp_create_reader, rather than ident_hash, so that the new
+ reader gets its own hash table.
+
+2022-11-15 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106302
+ * c-parser.cc: Include "analyzer/analyzer-language.h" and "toplev.h".
+ (class ana::c_translation_unit): New.
+ (c_parser_translation_unit): Call ana::on_finish_translation_unit.
+
+2022-11-12 Joseph Myers <joseph@codesourcery.com>
+
+ * c-decl.cc (start_underspecified_init)
+ (finish_underspecified_init): Handle name == NULL_TREE for
+ compound literals.
+ (merge_decls): Merge C_DECL_DECLARED_CONSTEXPR.
+ (shadow_tag_warned): Check for constexpr.
+ (start_decl): Add parameter do_push.
+ (build_compound_literal): Set C_DECL_DECLARED_CONSTEXPR.
+ (grokdeclarator): Handle constexpr.
+ (finish_struct): Set C_TYPE_FIELDS_NON_CONSTEXPR.
+ (declspecs_add_scspec): Handle constexpr.
+ * c-parser.cc (c_token_starts_compound_literal)
+ (c_token_starts_declspecs, c_parser_declaration_or_fndef)
+ (c_parser_declspecs, c_parser_gnu_attribute_any_word)
+ (c_parser_compound_literal_scspecs)
+ (c_parser_postfix_expression_after_paren_type): Handle constexpr.
+ Update calls to start_init.
+ (c_parser_declaration_or_fndef, c_parser_initializer)
+ (c_parser_initval): Pass true for new argument of
+ convert_lvalue_to_rvalue. Call convert_lvalue_to_rvalue for
+ constexpr compound literals.
+ (c_parser_static_assert_declaration_no_semi)
+ (c_parser_enum_specifier, c_parser_struct_declaration)
+ (c_parser_alignas_specifier, c_parser_initelt, c_parser_label):
+ Call convert_lvalue_to_rvalue on expressions required to be
+ integer constant expressions.
+ (c_parser_omp_declare_reduction): Update call to start_init.
+ * c-tree.h (C_TYPE_FIELDS_NON_CONSTEXPR)
+ (C_DECL_DECLARED_CONSTEXPR): New macros.
+ (struct c_declspecs): Add constexpr_p.
+ (start_decl, convert_lvalue_to_rvalue, start_init): Update
+ prototypes.
+ * c-typeck.cc (require_constant_value, require_constant_elements):
+ Change to bool.
+ (require_constexpr_value, maybe_get_constexpr_init)
+ (constexpr_init_fits_real_type, check_constexpr_init): New.
+ (convert_lvalue_to_rvalue): Add new parameter for_init. Call
+ maybe_get_constexpr_init.
+ (store_init_value): Update call to digest_init.
+ (digest_init): Add parameters int_const_expr, arith_const_expr and
+ require_constexpr. Check constexpr initializers.
+ (constructor_top_level): Remove.
+ (struct initializer_stack): Remove top_level. Add
+ require_constexpr_value.
+ (start_init): Remove parameter top_level. Add parameters
+ init_require_constant and init_require_constexpr. Save
+ require_constexpr_value on stack.
+ (pop_init_level): Use a null pointer constant for zero initializer
+ of pointer initialized with {}.
+ (output_init_element): Update call to digest_init. Avoid passing
+ null pointer constants of pointer type through digest_init a
+ second time when initializing a constexpr object.
+
+2022-11-03 Joseph Myers <joseph@codesourcery.com>
+
+ * c-decl.cc (in_underspecified_init, start_underspecified_init)
+ (finish_underspecified_init): New.
+ (shadow_tag_warned, parser_xref_tag, start_struct, start_enum):
+ Give errors inside initializers of underspecified declarations.
+ (grokdeclarator): Handle (erroneous) case of C2X auto on a
+ parameter.
+ (declspecs_add_type): Handle c2x_auto_p case.
+ (declspecs_add_scspec): Handle auto possibly setting c2x_auto_p in
+ C2X mode.
+ (finish_declspecs): Handle c2x_auto_p.
+ * c-parser.cc (c_parser_declaration_or_fndef): Handle C2X auto.
+ * c-tree.h (C_DECL_UNDERSPECIFIED): New macro.
+ (struct c_declspecs): Add c2x_auto_p.
+ (start_underspecified_init, finish_underspecified_init): New
+ prototypes.
+ * c-typeck.cc (build_external_ref): Give error for underspecified
+ declaration referenced in its initializer.
+
2022-10-28 Joseph Myers <joseph@codesourcery.com>
* c-decl.cc (grokdeclarator): Pass
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 795c971..e47ca67 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -1472,6 +1472,76 @@ pop_file_scope (void)
maybe_apply_pending_pragma_weaks ();
}
+/* Whether we are curently inside the initializer for an
+ underspecified object definition (C2x auto or constexpr). */
+static bool in_underspecified_init;
+
+/* Start an underspecified object definition for NAME at LOC. This
+ means that NAME is shadowed inside its initializer, so neither the
+ definition being initialized, nor any definition from an outer
+ scope, may be referenced during that initializer. Return state to
+ be passed to finish_underspecified_init. If NAME is NULL_TREE, the
+ underspecified object is a (constexpr) compound literal; there is
+ no shadowing in that case, but all the other restrictions on
+ underspecified object definitions still apply. */
+unsigned int
+start_underspecified_init (location_t loc, tree name)
+{
+ bool prev = in_underspecified_init;
+ bool ok;
+ if (name == NULL_TREE)
+ ok = true;
+ else
+ {
+ tree decl = build_decl (loc, VAR_DECL, name, error_mark_node);
+ C_DECL_UNDERSPECIFIED (decl) = 1;
+ struct c_scope *scope = current_scope;
+ struct c_binding *b = I_SYMBOL_BINDING (name);
+ if (b && B_IN_SCOPE (b, scope))
+ {
+ error_at (loc, "underspecified declaration of %qE, which is already "
+ "declared in this scope", name);
+ ok = false;
+ }
+ else
+ {
+ bind (name, decl, scope, false, false, loc);
+ ok = true;
+ }
+ }
+ in_underspecified_init = true;
+ return ok | (prev << 1);
+}
+
+/* Finish an underspecified object definition for NAME, before that
+ name is bound to the real declaration instead of a placeholder.
+ PREV_STATE is the value returned by the call to
+ start_underspecified_init. If NAME is NULL_TREE, this means a
+ compound literal, as for start_underspecified_init. */
+void
+finish_underspecified_init (tree name, unsigned int prev_state)
+{
+ if (name != NULL_TREE && (prev_state & 1))
+ {
+ /* A VAR_DECL was bound to the name to shadow any previous
+ declarations for the name; remove that binding now. */
+ struct c_scope *scope = current_scope;
+ struct c_binding *b = I_SYMBOL_BINDING (name);
+ gcc_assert (b);
+ gcc_assert (B_IN_SCOPE (b, scope));
+ gcc_assert (VAR_P (b->decl));
+ gcc_assert (C_DECL_UNDERSPECIFIED (b->decl));
+ I_SYMBOL_BINDING (name) = b->shadowed;
+ /* In erroneous cases there may be other bindings added to this
+ scope during the initializer. */
+ struct c_binding **p = &scope->bindings;
+ while (*p != b)
+ p = &((*p)->prev);
+ *p = free_binding_and_advance (*p);
+ }
+ in_underspecified_init = (prev_state & (1u << 1)) >> 1;
+}
+
/* Adjust the bindings for the start of a statement expression. */
void
@@ -2684,6 +2754,15 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
if (DECL_INITIAL (newdecl) == NULL_TREE)
DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
+ /* Merge 'constexpr' information. */
+ if (VAR_P (olddecl) && VAR_P (newdecl))
+ {
+ if (C_DECL_DECLARED_CONSTEXPR (olddecl))
+ C_DECL_DECLARED_CONSTEXPR (newdecl) = 1;
+ else if (C_DECL_DECLARED_CONSTEXPR (newdecl))
+ C_DECL_DECLARED_CONSTEXPR (olddecl) = 1;
+ }
+
/* Merge the threadprivate attribute. */
if (VAR_P (olddecl) && C_DECL_THREADPRIVATE_P (olddecl))
C_DECL_THREADPRIVATE_P (newdecl) = 1;
@@ -4764,6 +4843,17 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
warned = 1;
}
+ if (in_underspecified_init)
+ {
+ /* This can only occur with extensions such as statement
+ expressions, but is still appropriate as an error to
+ avoid types declared in such a context escaping to
+ the type of an auto variable. */
+ error ("%qT declared in underspecified object initializer",
+ value);
+ warned = 1;
+ }
+
if (name == NULL_TREE)
{
if (warned != 1 && code != ENUMERAL_TYPE)
@@ -4872,6 +4962,12 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
warned = 1;
}
+ if (declspecs->constexpr_p)
+ {
+ error ("%<constexpr%> in empty declaration");
+ warned = 1;
+ }
+
if (current_scope == file_scope && declspecs->storage_class == csc_auto)
{
error ("%<auto%> in file-scope empty declaration");
@@ -5229,7 +5325,7 @@ c_decl_attributes (tree *node, tree attributes, int flags)
This is called as soon as the type information and variable name
have been parsed, before parsing the initializer if any.
Here we create the ..._DECL node, fill in its type,
- and put it on the list of decls for the current context.
+ and (if DO_PUSH) put it on the list of decls for the current context.
When nonnull, set *LASTLOC to the location of the prior declaration
of the same entity if one exists.
The ..._DECL node is returned as the value.
@@ -5244,7 +5340,8 @@ c_decl_attributes (tree *node, tree attributes, int flags)
tree
start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
- bool initialized, tree attributes, location_t *lastloc /* = NULL */)
+ bool initialized, tree attributes, bool do_push /* = true */,
+ location_t *lastloc /* = NULL */)
{
tree decl;
tree tem;
@@ -5417,15 +5514,20 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
/* Add this decl to the current scope.
TEM may equal DECL or it may be a previous decl of the same name. */
- tem = pushdecl (decl);
-
- if (initialized && DECL_EXTERNAL (tem))
+ if (do_push)
{
- DECL_EXTERNAL (tem) = 0;
- TREE_STATIC (tem) = 1;
- }
+ tem = pushdecl (decl);
+
+ if (initialized && DECL_EXTERNAL (tem))
+ {
+ DECL_EXTERNAL (tem) = 0;
+ TREE_STATIC (tem) = 1;
+ }
- return tem;
+ return tem;
+ }
+ else
+ return decl;
}
/* Subroutine of finish_decl. TYPE is the type of an uninitialized object
@@ -6142,6 +6244,7 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const,
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
C_DECL_COMPOUND_LITERAL_P (decl) = 1;
+ C_DECL_DECLARED_CONSTEXPR (decl) = scspecs && scspecs->constexpr_p;
TREE_TYPE (decl) = type;
if (threadp)
set_decl_tls_model (decl, decl_default_tls_model (decl));
@@ -6429,6 +6532,7 @@ grokdeclarator (const struct c_declarator *declarator,
{
tree type = declspecs->type;
bool threadp = declspecs->thread_p;
+ bool constexprp = declspecs->constexpr_p;
enum c_storage_class storage_class = declspecs->storage_class;
int constp;
int restrictp;
@@ -6458,6 +6562,15 @@ grokdeclarator (const struct c_declarator *declarator,
enum c_declarator_kind first_non_attr_kind;
unsigned int alignas_align = 0;
+ if (type == NULL_TREE)
+ {
+ /* This can occur for auto on a parameter in C2X mode. Set a
+ dummy type here so subsequent code can give diagnostics for
+ this case. */
+ gcc_assert (declspecs->c2x_auto_p);
+ gcc_assert (decl_context == PARM);
+ type = declspecs->type = integer_type_node;
+ }
if (TREE_CODE (type) == ERROR_MARK)
return error_mark_node;
if (expr == NULL)
@@ -6662,6 +6775,7 @@ grokdeclarator (const struct c_declarator *declarator,
if (funcdef_flag
&& (threadp
+ || constexprp
|| storage_class == csc_auto
|| storage_class == csc_register
|| storage_class == csc_typedef))
@@ -6678,14 +6792,23 @@ grokdeclarator (const struct c_declarator *declarator,
error_at (loc, "function definition declared %qs",
declspecs->thread_gnu_p ? "__thread" : "_Thread_local");
threadp = false;
+ /* The parser ensures a constexpr function definition never
+ reaches here. */
+ gcc_assert (!constexprp);
if (storage_class == csc_auto
|| storage_class == csc_register
|| storage_class == csc_typedef)
storage_class = csc_none;
}
- else if (decl_context != NORMAL && (storage_class != csc_none || threadp))
+ else if (decl_context != NORMAL && (storage_class != csc_none
+ || threadp
+ || constexprp
+ || declspecs->c2x_auto_p))
{
- if (decl_context == PARM && storage_class == csc_register)
+ if (decl_context == PARM
+ && storage_class == csc_register
+ && !constexprp
+ && !declspecs->c2x_auto_p)
;
else
{
@@ -6711,6 +6834,7 @@ grokdeclarator (const struct c_declarator *declarator,
}
storage_class = csc_none;
threadp = false;
+ constexprp = false;
}
}
else if (storage_class == csc_extern
@@ -7758,7 +7882,7 @@ grokdeclarator (const struct c_declarator *declarator,
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
- if (storage_class == csc_register || threadp)
+ if (storage_class == csc_register || threadp || constexprp)
{
error_at (loc, "invalid storage class for function %qE", name);
}
@@ -7858,6 +7982,32 @@ grokdeclarator (const struct c_declarator *declarator,
/* An uninitialized decl with `extern' is a reference. */
int extern_ref = !initialized && storage_class == csc_extern;
+ if (constexprp)
+ {
+ /* The type of a constexpr variable must not be variably
+ modified, volatile, atomic or restrict qualified or
+ have a member with such a qualifier. const
+ qualification is implicitly added, and, at file scope,
+ has internal linkage. */
+ if (variably_modified_type_p (type, NULL_TREE))
+ error_at (loc, "%<constexpr%> object has variably modified "
+ "type");
+ if (type_quals
+ & (TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC))
+ error_at (loc, "invalid qualifiers for %<constexpr%> object");
+ else
+ {
+ tree type_no_array = strip_array_types (type);
+ if (RECORD_OR_UNION_TYPE_P (type_no_array)
+ && C_TYPE_FIELDS_NON_CONSTEXPR (type_no_array))
+ error_at (loc, "invalid qualifiers for field of "
+ "%<constexpr%> object");
+ }
+ type_quals |= TYPE_QUAL_CONST;
+ if (current_scope == file_scope)
+ storage_class = csc_static;
+ }
+
type = c_build_qualified_type (type, type_quals, orig_qual_type,
orig_qual_indirect);
@@ -7884,6 +8034,8 @@ grokdeclarator (const struct c_declarator *declarator,
VAR_DECL, declarator->u.id.id, type);
if (size_varies)
C_DECL_VARIABLE_SIZE (decl) = 1;
+ if (constexprp)
+ C_DECL_DECLARED_CONSTEXPR (decl) = 1;
if (declspecs->inline_p)
pedwarn (loc, 0, "variable %q+D declared %<inline%>", decl);
@@ -8428,6 +8580,9 @@ parser_xref_tag (location_t loc, enum tree_code code, tree name,
pushtag (loc, name, ref);
decl_attributes (&ref, attrs, (int) ATTR_FLAG_TYPE_IN_PLACE);
+ if (in_underspecified_init)
+ error_at (loc, "%qT declared in underspecified object initializer",
+ ref);
ret.spec = ref;
return ret;
@@ -8523,6 +8678,9 @@ start_struct (location_t loc, enum tree_code code, tree name,
? "sizeof"
: (in_typeof ? "typeof" : "alignof")));
+ if (in_underspecified_init)
+ error_at (loc, "%qT defined in underspecified object initializer", ref);
+
return ref;
}
@@ -8909,26 +9067,7 @@ is_flexible_array_member_p (bool is_last_field,
bool is_one_element_array = one_element_array_type_p (TREE_TYPE (x));
bool is_flexible_array = flexible_array_member_type_p (TREE_TYPE (x));
- unsigned int strict_flex_array_level = flag_strict_flex_arrays;
-
- tree attr_strict_flex_array = lookup_attribute ("strict_flex_array",
- DECL_ATTRIBUTES (x));
- /* If there is a strict_flex_array attribute attached to the field,
- override the flag_strict_flex_arrays. */
- if (attr_strict_flex_array)
- {
- /* Get the value of the level first from the attribute. */
- unsigned HOST_WIDE_INT attr_strict_flex_array_level = 0;
- gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE);
- attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array);
- gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE);
- attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array);
- gcc_assert (tree_fits_uhwi_p (attr_strict_flex_array));
- attr_strict_flex_array_level = tree_to_uhwi (attr_strict_flex_array);
-
- /* The attribute has higher priority than flag_struct_flex_array. */
- strict_flex_array_level = attr_strict_flex_array_level;
- }
+ unsigned int strict_flex_array_level = strict_flex_array_level_of (x);
switch (strict_flex_array_level)
{
@@ -9028,13 +9167,13 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
DECL_CONTEXT (x) = t;
+ tree t1 = strip_array_types (TREE_TYPE (x));
/* If any field is const, the structure type is pseudo-const. */
if (TREE_READONLY (x))
C_TYPE_FIELDS_READONLY (t) = 1;
else
{
/* A field that is pseudo-const makes the structure likewise. */
- tree t1 = strip_array_types (TREE_TYPE (x));
if (RECORD_OR_UNION_TYPE_P (t1) && C_TYPE_FIELDS_READONLY (t1))
C_TYPE_FIELDS_READONLY (t) = 1;
}
@@ -9042,7 +9181,18 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
/* Any field that is volatile means variables of this type must be
treated in some ways as volatile. */
if (TREE_THIS_VOLATILE (x))
- C_TYPE_FIELDS_VOLATILE (t) = 1;
+ {
+ C_TYPE_FIELDS_VOLATILE (t) = 1;
+ C_TYPE_FIELDS_NON_CONSTEXPR (t) = 1;
+ }
+
+ /* Any field that is volatile, restrict-qualified or atomic
+ means the type cannot be used for a constexpr object. */
+ if (TYPE_QUALS (t1)
+ & (TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC))
+ C_TYPE_FIELDS_NON_CONSTEXPR (t) = 1;
+ else if (RECORD_OR_UNION_TYPE_P (t1) && C_TYPE_FIELDS_NON_CONSTEXPR (t1))
+ C_TYPE_FIELDS_NON_CONSTEXPR (t) = 1;
/* Any field of nominal variable size implies structure is too. */
if (C_DECL_VARIABLE_SIZE (x))
@@ -9244,6 +9394,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
TYPE_TRANSPARENT_AGGR (x) = TYPE_TRANSPARENT_AGGR (t);
C_TYPE_FIELDS_READONLY (x) = C_TYPE_FIELDS_READONLY (t);
C_TYPE_FIELDS_VOLATILE (x) = C_TYPE_FIELDS_VOLATILE (t);
+ C_TYPE_FIELDS_NON_CONSTEXPR (x) = C_TYPE_FIELDS_NON_CONSTEXPR (t);
C_TYPE_VARIABLE_SIZE (x) = C_TYPE_VARIABLE_SIZE (t);
C_TYPE_INCOMPLETE_VARS (x) = NULL_TREE;
}
@@ -9433,6 +9584,10 @@ start_enum (location_t loc, struct c_enum_contents *the_enum, tree name,
? "sizeof"
: (in_typeof ? "typeof" : "alignof")));
+ if (in_underspecified_init)
+ error_at (loc, "%qT defined in underspecified object initializer",
+ enumtype);
+
return enumtype;
}
@@ -9885,6 +10040,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
tree decl1, old_decl;
tree restype, resdecl;
location_t loc;
+ location_t result_loc;
current_function_returns_value = 0; /* Assume, until we see it does. */
current_function_returns_null = 0;
@@ -10111,8 +10267,11 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
push_scope ();
declare_parm_level ();
+ /* Set the result decl source location to the location of the typespec. */
+ result_loc = (declspecs->locations[cdw_typespec] == UNKNOWN_LOCATION
+ ? loc : declspecs->locations[cdw_typespec]);
restype = TREE_TYPE (TREE_TYPE (current_function_decl));
- resdecl = build_decl (loc, RESULT_DECL, NULL_TREE, restype);
+ resdecl = build_decl (result_loc, RESULT_DECL, NULL_TREE, restype);
DECL_ARTIFICIAL (resdecl) = 1;
DECL_IGNORED_P (resdecl) = 1;
DECL_RESULT (current_function_decl) = resdecl;
@@ -11261,6 +11420,24 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
if (TREE_UNAVAILABLE (type))
specs->unavailable_p = true;
+ /* As a type specifier is present, "auto" must be used as a storage
+ class specifier, not for type deduction. */
+ if (specs->c2x_auto_p)
+ {
+ specs->c2x_auto_p = false;
+ if (specs->storage_class != csc_none)
+ error ("multiple storage classes in declaration specifiers");
+ else if (specs->thread_p)
+ error ("%qs used with %<auto%>",
+ specs->thread_gnu_p ? "__thread" : "_Thread_local");
+ else if (specs->constexpr_p)
+ /* auto may only be used with another storage class specifier,
+ such as constexpr, if the type is inferred. */
+ error ("%<auto%> used with %<constexpr%>");
+ else
+ specs->storage_class = csc_auto;
+ }
+
/* Handle type specifier keywords. */
if (TREE_CODE (type) == IDENTIFIER_NODE
&& C_IS_RESERVED_WORD (type)
@@ -12051,11 +12228,9 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc, "two or more data types in declaration specifiers");
else if (TREE_CODE (type) == TYPE_DECL)
{
- if (TREE_TYPE (type) == error_mark_node)
- ; /* Allow the type to default to int to avoid cascading errors. */
- else
+ specs->type = TREE_TYPE (type);
+ if (TREE_TYPE (type) != error_mark_node)
{
- specs->type = TREE_TYPE (type);
specs->decl_attr = DECL_ATTRIBUTES (type);
specs->typedef_p = true;
specs->explicit_signed_p = C_TYPEDEF_EXPLICITLY_SIGNED (type);
@@ -12157,6 +12332,8 @@ declspecs_add_scspec (location_t loc,
error ("%qE used with %<register%>", scspec);
else if (specs->storage_class == csc_typedef)
error ("%qE used with %<typedef%>", scspec);
+ else if (specs->constexpr_p)
+ error ("%qE used with %<constexpr%>", scspec);
else
{
specs->thread_p = true;
@@ -12179,7 +12356,21 @@ declspecs_add_scspec (location_t loc,
}
break;
case RID_AUTO:
+ if (flag_isoc2x
+ && specs->typespec_kind == ctsk_none
+ && specs->storage_class != csc_typedef)
+ {
+ /* "auto" potentially used for type deduction. */
+ if (specs->c2x_auto_p)
+ error ("duplicate %qE", scspec);
+ specs->c2x_auto_p = true;
+ return specs;
+ }
n = csc_auto;
+ /* auto may only be used with another storage class specifier,
+ such as constexpr, if the type is inferred. */
+ if (specs->constexpr_p)
+ error ("%qE used with %<constexpr%>", scspec);
break;
case RID_EXTERN:
n = csc_extern;
@@ -12198,6 +12389,27 @@ declspecs_add_scspec (location_t loc,
break;
case RID_TYPEDEF:
n = csc_typedef;
+ if (specs->c2x_auto_p)
+ {
+ error ("%<typedef%> used with %<auto%>");
+ specs->c2x_auto_p = false;
+ }
+ break;
+ case RID_CONSTEXPR:
+ dupe = specs->constexpr_p;
+ if (specs->storage_class == csc_extern)
+ error ("%qE used with %<extern%>", scspec);
+ else if (specs->storage_class == csc_typedef)
+ error ("%qE used with %<typedef%>", scspec);
+ else if (specs->storage_class == csc_auto)
+ /* auto may only be used with another storage class specifier,
+ such as constexpr, if the type is inferred. */
+ error ("%qE used with %<auto%>", scspec);
+ else if (specs->thread_p)
+ error ("%qE used with %qs", scspec,
+ specs->thread_gnu_p ? "__thread" : "_Thread_local");
+ else
+ specs->constexpr_p = true;
break;
default:
gcc_unreachable ();
@@ -12228,6 +12440,12 @@ declspecs_add_scspec (location_t loc,
scspec);
specs->thread_p = false;
}
+ if (n != csc_auto && n != csc_register && n != csc_static
+ && specs->constexpr_p)
+ {
+ error ("%<constexpr%> used with %qE", scspec);
+ specs->constexpr_p = false;
+ }
}
}
return specs;
@@ -12284,7 +12502,7 @@ finish_declspecs (struct c_declspecs *specs)
{
gcc_assert (!specs->long_p && !specs->long_long_p && !specs->short_p
&& !specs->signed_p && !specs->unsigned_p
- && !specs->complex_p);
+ && !specs->complex_p && !specs->c2x_auto_p);
/* Set a dummy type. */
if (TREE_CODE (specs->type) == ERROR_MARK)
@@ -12320,6 +12538,18 @@ finish_declspecs (struct c_declspecs *specs)
"ISO C does not support plain %<complex%> meaning "
"%<double complex%>");
}
+ else if (specs->c2x_auto_p)
+ {
+ /* Type to be filled in later, including applying postfix
+ attributes. This warning only actually appears for
+ -Wc11-c2x-compat in C2X mode; in older modes, there may
+ be a warning or pedwarn for implicit "int" instead, or
+ other errors for use of auto at file scope. */
+ pedwarn_c11 (input_location, OPT_Wpedantic,
+ "ISO C does not support %<auto%> type deduction "
+ "before C2X");
+ return specs;
+ }
else
{
specs->typespec_word = cts_int;
@@ -12336,6 +12566,7 @@ finish_declspecs (struct c_declspecs *specs)
specs->explicit_signed_p = specs->signed_p;
/* Now compute the actual type. */
+ gcc_assert (!specs->c2x_auto_p);
switch (specs->typespec_word)
{
case cts_auto_type:
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index ca533c9..1bbb39f 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -72,6 +72,8 @@ along with GCC; see the file COPYING3. If not see
#include "memmodel.h"
#include "c-family/known-headers.h"
#include "bitmap.h"
+#include "analyzer/analyzer-language.h"
+#include "toplev.h"
/* We need to walk over decls with incomplete struct/union/enum types
after parsing the whole translation unit.
@@ -677,6 +679,7 @@ c_token_starts_compound_literal (c_token *token)
case CPP_KEYWORD:
switch (token->keyword)
{
+ case RID_CONSTEXPR:
case RID_REGISTER:
case RID_STATIC:
case RID_THREAD:
@@ -795,6 +798,7 @@ c_token_starts_declspecs (c_token *token)
case RID_ALIGNAS:
case RID_ATOMIC:
case RID_AUTO_TYPE:
+ case RID_CONSTEXPR:
return true;
default:
if (token->keyword >= RID_FIRST_INT_N
@@ -1662,6 +1666,86 @@ static bool c_parser_objc_diagnose_bad_element_prefix
(c_parser *, struct c_declspecs *);
static location_t c_parser_parse_rtl_body (c_parser *, char *);
+#if ENABLE_ANALYZER
+
+namespace ana {
+
+/* Concrete implementation of ana::translation_unit for the C frontend. */
+
+class c_translation_unit : public translation_unit
+{
+public:
+ /* Implementation of translation_unit::lookup_constant_by_id for use by the
+ analyzer to look up named constants in the user's source code. */
+ tree lookup_constant_by_id (tree id) const final override
+ {
+ /* Consider decls. */
+ if (tree decl = lookup_name (id))
+ if (TREE_CODE (decl) == CONST_DECL)
+ if (tree value = DECL_INITIAL (decl))
+ if (TREE_CODE (value) == INTEGER_CST)
+ return value;
+
+ /* Consider macros. */
+ cpp_hashnode *hashnode = C_CPP_HASHNODE (id);
+ if (cpp_macro_p (hashnode))
+ if (tree value = consider_macro (hashnode->value.macro))
+ return value;
+
+ return NULL_TREE;
+ }
+
+private:
+ /* Attempt to get an INTEGER_CST from MACRO.
+ Only handle the simplest cases: where MACRO's definition is a single
+ token containing a number, by lexing the number again.
+ This will handle e.g.
+ #define NAME 42
+ and other bases but not negative numbers, parentheses or e.g.
+ #define NAME 1 << 7
+ as doing so would require a parser. */
+ tree consider_macro (cpp_macro *macro) const
+ {
+ if (macro->paramc > 0)
+ return NULL_TREE;
+ if (macro->kind != cmk_macro)
+ return NULL_TREE;
+ if (macro->count != 1)
+ return NULL_TREE;
+ const cpp_token &tok = macro->exp.tokens[0];
+ if (tok.type != CPP_NUMBER)
+ return NULL_TREE;
+
+ cpp_reader *old_parse_in = parse_in;
+ parse_in = cpp_create_reader (CLK_GNUC89, NULL, line_table);
+
+ pretty_printer pp;
+ pp_string (&pp, (const char *) tok.val.str.text);
+ pp_newline (&pp);
+ cpp_push_buffer (parse_in,
+ (const unsigned char *) pp_formatted_text (&pp),
+ strlen (pp_formatted_text (&pp)),
+ 0);
+
+ tree value;
+ location_t loc;
+ unsigned char cpp_flags;
+ c_lex_with_flags (&value, &loc, &cpp_flags, 0);
+
+ cpp_destroy (parse_in);
+ parse_in = old_parse_in;
+
+ if (value && TREE_CODE (value) == INTEGER_CST)
+ return value;
+
+ return NULL_TREE;
+ }
+};
+
+} // namespace ana
+
+#endif /* #if ENABLE_ANALYZER */
+
/* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
translation-unit:
@@ -1722,6 +1806,14 @@ c_parser_translation_unit (c_parser *parser)
"#pragma omp begin assumes", "#pragma omp end assumes");
current_omp_begin_assumes = 0;
}
+
+#if ENABLE_ANALYZER
+ if (flag_analyzer)
+ {
+ ana::c_translation_unit tu;
+ ana::on_finish_translation_unit (tu);
+ }
+#endif
}
/* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
@@ -2103,7 +2195,37 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
}
finish_declspecs (specs);
- bool auto_type_p = specs->typespec_word == cts_auto_type;
+ bool gnu_auto_type_p = specs->typespec_word == cts_auto_type;
+ bool std_auto_type_p = specs->c2x_auto_p;
+ bool any_auto_type_p = gnu_auto_type_p || std_auto_type_p;
+ gcc_assert (!(gnu_auto_type_p && std_auto_type_p));
+ const char *auto_type_keyword = gnu_auto_type_p ? "__auto_type" : "auto";
+ if (specs->constexpr_p)
+ {
+ /* An underspecified declaration may not declare tags or members
+ or structures or unions; it is undefined behavior to declare
+ the members of an enumeration. Where the structure, union or
+ enumeration type is declared within an initializer, this is
+ diagnosed elsewhere. Diagnose here the case of declaring
+ such a type in the type specifiers of a constexpr
+ declaration. */
+ switch (specs->typespec_kind)
+ {
+ case ctsk_tagfirstref:
+ case ctsk_tagfirstref_attrs:
+ error_at (here, "%qT declared in underspecified object declaration",
+ specs->type);
+ break;
+
+ case ctsk_tagdef:
+ error_at (here, "%qT defined in underspecified object declaration",
+ specs->type);
+ break;
+
+ default:
+ break;
+ }
+ }
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
bool handled_assume = false;
@@ -2114,8 +2236,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
specs->attrs
= handle_assume_attribute (here, specs->attrs, nested);
}
- if (auto_type_p)
- error_at (here, "%<__auto_type%> in empty declaration");
+ if (any_auto_type_p)
+ error_at (here, "%qs in empty declaration", auto_type_keyword);
else if (specs->typespec_kind == ctsk_none
&& attribute_fallthrough_p (specs->attrs))
{
@@ -2159,7 +2281,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
shadow_tag_warned (specs, 1);
return;
}
- else if (c_dialect_objc () && !auto_type_p)
+ else if (c_dialect_objc () && !any_auto_type_p)
{
/* Prefix attributes are an error on method decls. */
switch (c_parser_peek_token (parser)->type)
@@ -2253,6 +2375,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
bool dummy = false;
timevar_id_t tv;
tree fnbody = NULL_TREE;
+ tree underspec_name = NULL_TREE;
/* Declaring either one or more declarators (in which case we
should diagnose if there were no declaration specifiers) or a
function definition (in which case the diagnostic for
@@ -2270,7 +2393,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
c_parser_skip_to_end_of_block_or_statement (parser);
return;
}
- if (auto_type_p && declarator->kind != cdk_id)
+ if (gnu_auto_type_p && declarator->kind != cdk_id)
{
error_at (here,
"%<__auto_type%> requires a plain identifier"
@@ -2278,6 +2401,28 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
c_parser_skip_to_end_of_block_or_statement (parser);
return;
}
+ if (std_auto_type_p)
+ {
+ struct c_declarator *d = declarator;
+ while (d->kind == cdk_attrs)
+ d = d->declarator;
+ if (d->kind != cdk_id)
+ {
+ error_at (here,
+ "%<auto%> requires a plain identifier, possibly with"
+ " attributes, as declarator");
+ c_parser_skip_to_end_of_block_or_statement (parser);
+ return;
+ }
+ underspec_name = d->u.id.id;
+ }
+ else if (specs->constexpr_p)
+ {
+ struct c_declarator *d = declarator;
+ while (d->kind != cdk_id)
+ d = d->declarator;
+ underspec_name = d->u.id.id;
+ }
if (c_parser_next_token_is (parser, CPP_EQ)
|| c_parser_next_token_is (parser, CPP_COMMA)
|| c_parser_next_token_is (parser, CPP_SEMICOLON)
@@ -2317,24 +2462,48 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
struct c_expr init;
location_t init_loc;
c_parser_consume_token (parser);
- if (auto_type_p)
+ if (any_auto_type_p)
{
init_loc = c_parser_peek_token (parser)->location;
rich_location richloc (line_table, init_loc);
- start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
+ unsigned int underspec_state = 0;
+ if (std_auto_type_p)
+ underspec_state =
+ start_underspecified_init (init_loc, underspec_name);
+ start_init (NULL_TREE, asm_name,
+ (global_bindings_p ()
+ || specs->storage_class == csc_static
+ || specs->constexpr_p),
+ specs->constexpr_p, &richloc);
/* A parameter is initialized, which is invalid. Don't
attempt to instrument the initializer. */
int flag_sanitize_save = flag_sanitize;
if (nested && !empty_ok)
flag_sanitize = 0;
- init = c_parser_expr_no_commas (parser, NULL);
+ if (std_auto_type_p
+ && c_parser_next_token_is (parser, CPP_OPEN_BRACE))
+ {
+ matching_braces braces;
+ braces.consume_open (parser);
+ init = c_parser_expr_no_commas (parser, NULL);
+ if (c_parser_next_token_is (parser, CPP_COMMA))
+ c_parser_consume_token (parser);
+ braces.skip_until_found_close (parser);
+ }
+ else
+ init = c_parser_expr_no_commas (parser, NULL);
+ if (std_auto_type_p)
+ finish_underspecified_init (underspec_name,
+ underspec_state);
flag_sanitize = flag_sanitize_save;
- if (TREE_CODE (init.value) == COMPONENT_REF
+ if (gnu_auto_type_p
+ && TREE_CODE (init.value) == COMPONENT_REF
&& DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
error_at (here,
"%<__auto_type%> used with a bit-field"
" initializer");
- init = convert_lvalue_to_rvalue (init_loc, init, true, true);
+ init = convert_lvalue_to_rvalue (init_loc, init, true, true,
+ true);
tree init_type = TREE_TYPE (init.value);
bool vm_type = variably_modified_type_p (init_type,
NULL_TREE);
@@ -2345,6 +2514,16 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
specs->locations[cdw_typedef] = init_loc;
specs->typedef_p = true;
specs->type = init_type;
+ if (specs->postfix_attrs)
+ {
+ /* Postfix [[]] attributes are valid with C2X
+ auto, although not with __auto_type, and
+ modify the type given by the initializer. */
+ specs->postfix_attrs =
+ c_warn_type_attributes (specs->postfix_attrs);
+ decl_attributes (&specs->type, specs->postfix_attrs, 0);
+ specs->postfix_attrs = NULL_TREE;
+ }
if (vm_type)
{
bool maybe_const = true;
@@ -2369,17 +2548,26 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
else
{
/* The declaration of the variable is in effect while
- its initializer is parsed. */
+ its initializer is parsed, except for a constexpr
+ variable. */
+ init_loc = c_parser_peek_token (parser)->location;
+ rich_location richloc (line_table, init_loc);
+ unsigned int underspec_state = 0;
+ if (specs->constexpr_p)
+ underspec_state =
+ start_underspecified_init (init_loc, underspec_name);
d = start_decl (declarator, specs, true,
- chainon (postfix_attrs, all_prefix_attrs));
+ chainon (postfix_attrs,
+ all_prefix_attrs),
+ !specs->constexpr_p);
if (!d)
d = error_mark_node;
- if (omp_declare_simd_clauses)
+ if (!specs->constexpr_p && omp_declare_simd_clauses)
c_finish_omp_declare_simd (parser, d, NULL_TREE,
omp_declare_simd_clauses);
- init_loc = c_parser_peek_token (parser)->location;
- rich_location richloc (line_table, init_loc);
- start_init (d, asm_name, global_bindings_p (), &richloc);
+ start_init (d, asm_name,
+ TREE_STATIC (d) || specs->constexpr_p,
+ specs->constexpr_p, &richloc);
/* A parameter is initialized, which is invalid. Don't
attempt to instrument the initializer. */
int flag_sanitize_save = flag_sanitize;
@@ -2387,6 +2575,15 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
flag_sanitize = 0;
init = c_parser_initializer (parser, d);
flag_sanitize = flag_sanitize_save;
+ if (specs->constexpr_p)
+ {
+ finish_underspecified_init (underspec_name,
+ underspec_state);
+ d = pushdecl (d);
+ if (omp_declare_simd_clauses)
+ c_finish_omp_declare_simd (parser, d, NULL_TREE,
+ omp_declare_simd_clauses);
+ }
finish_init ();
}
if (oacc_routine_data)
@@ -2400,18 +2597,19 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
}
else
{
- if (auto_type_p)
+ if (any_auto_type_p || specs->constexpr_p)
{
error_at (here,
- "%<__auto_type%> requires an initialized "
- "data declaration");
+ "%qs requires an initialized data declaration",
+ any_auto_type_p ? auto_type_keyword : "constexpr");
c_parser_skip_to_end_of_block_or_statement (parser);
return;
}
location_t lastloc = UNKNOWN_LOCATION;
tree attrs = chainon (postfix_attrs, all_prefix_attrs);
- tree d = start_decl (declarator, specs, false, attrs, &lastloc);
+ tree d = start_decl (declarator, specs, false, attrs, true,
+ &lastloc);
if (d && TREE_CODE (d) == FUNCTION_DECL)
{
/* Find the innermost declarator that is neither cdk_id
@@ -2492,11 +2690,11 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
}
if (c_parser_next_token_is (parser, CPP_COMMA))
{
- if (auto_type_p)
+ if (any_auto_type_p || specs->constexpr_p)
{
error_at (here,
- "%<__auto_type%> may only be used with"
- " a single declarator");
+ "%qs may only be used with a single declarator",
+ any_auto_type_p ? auto_type_keyword : "constexpr");
c_parser_skip_to_end_of_block_or_statement (parser);
return;
}
@@ -2529,10 +2727,11 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
return;
}
}
- else if (auto_type_p)
+ else if (any_auto_type_p || specs->constexpr_p)
{
error_at (here,
- "%<__auto_type%> requires an initialized data declaration");
+ "%qs requires an initialized data declaration",
+ any_auto_type_p ? auto_type_keyword : "constexpr");
c_parser_skip_to_end_of_block_or_statement (parser);
return;
}
@@ -2740,7 +2939,9 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser)
if (!parens.require_open (parser))
return;
location_t value_tok_loc = c_parser_peek_token (parser)->location;
- value = c_parser_expr_no_commas (parser, NULL).value;
+ value = convert_lvalue_to_rvalue (value_tok_loc,
+ c_parser_expr_no_commas (parser, NULL),
+ true, true).value;
value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
if (c_parser_next_token_is (parser, CPP_COMMA))
{
@@ -3043,6 +3244,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
case RID_NORETURN:
case RID_AUTO:
case RID_THREAD:
+ case RID_CONSTEXPR:
if (!scspec_ok)
goto out;
attrs_ok = true;
@@ -3413,7 +3615,10 @@ c_parser_enum_specifier (c_parser *parser)
{
c_parser_consume_token (parser);
value_loc = c_parser_peek_token (parser)->location;
- enum_value = c_parser_expr_no_commas (parser, NULL).value;
+ enum_value = convert_lvalue_to_rvalue (value_loc,
+ (c_parser_expr_no_commas
+ (parser, NULL)),
+ true, true).value;
}
else
enum_value = NULL_TREE;
@@ -3851,7 +4056,11 @@ c_parser_struct_declaration (c_parser *parser)
if (c_parser_next_token_is (parser, CPP_COLON))
{
c_parser_consume_token (parser);
- width = c_parser_expr_no_commas (parser, NULL).value;
+ location_t loc = c_parser_peek_token (parser)->location;
+ width = convert_lvalue_to_rvalue (loc,
+ (c_parser_expr_no_commas
+ (parser, NULL)),
+ true, true).value;
}
if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
postfix_attrs = c_parser_gnu_attributes (parser);
@@ -4020,7 +4229,9 @@ c_parser_alignas_specifier (c_parser * parser)
false, true, 1);
}
else
- ret = c_parser_expr_no_commas (parser, NULL).value;
+ ret = convert_lvalue_to_rvalue (loc,
+ c_parser_expr_no_commas (parser, NULL),
+ true, true).value;
parens.skip_until_found_close (parser);
return ret;
}
@@ -4768,6 +4979,7 @@ c_parser_gnu_attribute_any_word (c_parser *parser)
case RID_TRANSACTION_CANCEL:
case RID_ATOMIC:
case RID_AUTO_TYPE:
+ case RID_CONSTEXPR:
case RID_INT_N_0:
case RID_INT_N_1:
case RID_INT_N_2:
@@ -5489,8 +5701,10 @@ c_parser_initializer (c_parser *parser, tree decl)
&& !warn_init_self)
suppress_warning (decl, OPT_Winit_self);
if (TREE_CODE (ret.value) != STRING_CST
- && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
- ret = convert_lvalue_to_rvalue (loc, ret, true, true);
+ && (TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR
+ || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
+ (ret.value))))
+ ret = convert_lvalue_to_rvalue (loc, ret, true, true, true);
return ret;
}
}
@@ -5636,6 +5850,7 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
}
else
{
+ struct c_expr first_expr;
tree first, second;
location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
location_t array_index_loc = UNKNOWN_LOCATION;
@@ -5679,11 +5894,13 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
rec = objc_get_class_reference (id);
goto parse_message_args;
}
- first = c_parser_expr_no_commas (parser, NULL).value;
- mark_exp_read (first);
+ array_index_loc = c_parser_peek_token (parser)->location;
+ first_expr = c_parser_expr_no_commas (parser, NULL);
+ mark_exp_read (first_expr.value);
if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
|| c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
goto array_desig_after_first;
+ first = first_expr.value;
/* Expression receiver. So far only one part
without commas has been parsed; there might be
more of the expression. */
@@ -5718,14 +5935,21 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
}
c_parser_consume_token (parser);
array_index_loc = c_parser_peek_token (parser)->location;
- first = c_parser_expr_no_commas (parser, NULL).value;
- mark_exp_read (first);
+ first_expr = c_parser_expr_no_commas (parser, NULL);
+ mark_exp_read (first_expr.value);
array_desig_after_first:
+ first_expr = convert_lvalue_to_rvalue (array_index_loc,
+ first_expr,
+ true, true);
+ first = first_expr.value;
if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
{
ellipsis_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
- second = c_parser_expr_no_commas (parser, NULL).value;
+ second = convert_lvalue_to_rvalue (ellipsis_loc,
+ (c_parser_expr_no_commas
+ (parser, NULL)),
+ true, true).value;
mark_exp_read (second);
}
else
@@ -5798,8 +6022,10 @@ c_parser_initval (c_parser *parser, struct c_expr *after,
init = c_parser_expr_no_commas (parser, after);
if (init.value != NULL_TREE
&& TREE_CODE (init.value) != STRING_CST
- && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
- init = convert_lvalue_to_rvalue (loc, init, true, true);
+ && (TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR
+ || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
+ (init.value))))
+ init = convert_lvalue_to_rvalue (loc, init, true, true, true);
}
process_init_element (loc, init, false, braced_init_obstack);
}
@@ -6156,7 +6382,9 @@ c_parser_label (c_parser *parser, tree std_attrs)
{
tree exp1, exp2;
c_parser_consume_token (parser);
- exp1 = c_parser_expr_no_commas (parser, NULL).value;
+ exp1 = convert_lvalue_to_rvalue (loc1,
+ c_parser_expr_no_commas (parser, NULL),
+ true, true).value;
if (c_parser_next_token_is (parser, CPP_COLON))
{
c_parser_consume_token (parser);
@@ -6165,7 +6393,10 @@ c_parser_label (c_parser *parser, tree std_attrs)
else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
{
c_parser_consume_token (parser);
- exp2 = c_parser_expr_no_commas (parser, NULL).value;
+ exp2 = convert_lvalue_to_rvalue (loc1,
+ c_parser_expr_no_commas (parser,
+ NULL),
+ true, true).value;
if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
label = do_case (loc1, exp1, exp2, std_attrs);
}
@@ -8362,6 +8593,7 @@ c_parser_compound_literal_scspecs (c_parser *parser)
{
switch (c_parser_peek_token (parser)->keyword)
{
+ case RID_CONSTEXPR:
case RID_REGISTER:
case RID_STATIC:
case RID_THREAD:
@@ -10648,17 +10880,71 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
location_t start_loc;
tree type_expr = NULL_TREE;
bool type_expr_const = true;
+ bool constexpr_p = scspecs ? scspecs->constexpr_p : false;
+ unsigned int underspec_state = 0;
check_compound_literal_type (type_loc, type_name);
rich_location richloc (line_table, type_loc);
- start_init (NULL_TREE, NULL, 0, &richloc);
- type = groktypename (type_name, &type_expr, &type_expr_const);
start_loc = c_parser_peek_token (parser)->location;
+ if (constexpr_p)
+ {
+ underspec_state = start_underspecified_init (start_loc, NULL_TREE);
+ /* A constexpr compound literal is subject to the constraints on
+ underspecified declarations, which may not declare tags or
+ members or structures or unions; it is undefined behavior to
+ declare the members of an enumeration. Where the structure,
+ union or enumeration type is declared within the compound
+ literal initializer, this is diagnosed elsewhere as a result
+ of the above call to start_underspecified_init. Diagnose
+ here the case of declaring such a type in the type specifiers
+ of the compound literal. */
+ switch (type_name->specs->typespec_kind)
+ {
+ case ctsk_tagfirstref:
+ case ctsk_tagfirstref_attrs:
+ error_at (type_loc, "%qT declared in %<constexpr%> compound literal",
+ type_name->specs->type);
+ break;
+
+ case ctsk_tagdef:
+ error_at (type_loc, "%qT defined in %<constexpr%> compound literal",
+ type_name->specs->type);
+ break;
+
+ default:
+ break;
+ }
+ }
+ start_init (NULL_TREE, NULL,
+ (global_bindings_p ()
+ || (scspecs && scspecs->storage_class == csc_static)
+ || constexpr_p), constexpr_p, &richloc);
+ type = groktypename (type_name, &type_expr, &type_expr_const);
if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
{
error_at (type_loc, "compound literal has variable size");
type = error_mark_node;
}
+ if (constexpr_p && type != error_mark_node)
+ {
+ tree type_no_array = strip_array_types (type);
+ /* The type of a constexpr object must not be variably modified
+ (which applies to all compound literals), volatile, atomic or
+ restrict qualified or have a member with such a qualifier.
+ const qualification is implicitly added. */
+ if (TYPE_QUALS (type_no_array)
+ & (TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC))
+ error_at (type_loc, "invalid qualifiers for %<constexpr%> object");
+ else if (RECORD_OR_UNION_TYPE_P (type_no_array)
+ && C_TYPE_FIELDS_NON_CONSTEXPR (type_no_array))
+ error_at (type_loc, "invalid qualifiers for field of "
+ "%<constexpr%> object");
+ type = c_build_qualified_type (type,
+ (TYPE_QUALS (type_no_array)
+ | TYPE_QUAL_CONST));
+ }
init = c_parser_braced_init (parser, type, false, NULL, NULL_TREE);
+ if (constexpr_p)
+ finish_underspecified_init (NULL_TREE, underspec_state);
finish_init ();
maybe_warn_string_init (type_loc, type, init);
@@ -23145,7 +23431,7 @@ c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
tree st = push_stmt_list ();
location_t loc = c_parser_peek_token (parser)->location;
rich_location richloc (line_table, loc);
- start_init (omp_priv, NULL_TREE, 0, &richloc);
+ start_init (omp_priv, NULL_TREE, false, false, &richloc);
struct c_expr init = c_parser_initializer (parser, omp_priv);
finish_init ();
finish_decl (omp_priv, loc, init.value,
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index facfc12..c287124 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -34,6 +34,11 @@ along with GCC; see the file COPYING3. If not see
/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is volatile. */
#define C_TYPE_FIELDS_VOLATILE(TYPE) TREE_LANG_FLAG_2 (TYPE)
+/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is
+ volatile, restrict-qualified or atomic; that is, has a type not
+ permitted for a constexpr object. */
+#define C_TYPE_FIELDS_NON_CONSTEXPR(TYPE) TREE_LANG_FLAG_4 (TYPE)
+
/* In a RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE
nonzero if the definition of the type has already started. */
#define C_TYPE_BEING_DEFINED(TYPE) TYPE_LANG_FLAG_0 (TYPE)
@@ -100,6 +105,14 @@ along with GCC; see the file COPYING3. If not see
#define C_DECL_COMPOUND_LITERAL_P(DECL) \
DECL_LANG_FLAG_5 (VAR_DECL_CHECK (DECL))
+/* Set on decls used as placeholders for a C2x underspecified object
+ definition. */
+#define C_DECL_UNDERSPECIFIED(DECL) DECL_LANG_FLAG_7 (DECL)
+
+/* Set on VAR_DECLs declared as 'constexpr'. */
+#define C_DECL_DECLARED_CONSTEXPR(DECL) \
+ DECL_LANG_FLAG_8 (VAR_DECL_CHECK (DECL))
+
/* Nonzero for a decl which either doesn't exist or isn't a prototype.
N.B. Could be simplified if all built-in decls had complete prototypes
(but this is presently difficult because some of them need FILE*). */
@@ -430,6 +443,13 @@ struct c_declspecs {
enum-type-specifier;", but such an empty declaration is valid in
C2x when "enum identifier;" would not be). */
BOOL_BITFIELD enum_type_specifier_ref_p : 1;
+ /* Whether "auto" was specified in C2X (or later) mode and means the
+ type is to be deduced from an initializer, or would mean that if
+ no type specifier appears later in these declaration
+ specifiers. */
+ BOOL_BITFIELD c2x_auto_p : 1;
+ /* Whether "constexpr" was specified. */
+ BOOL_BITFIELD constexpr_p : 1;
/* The address space that the declaration belongs to. */
addr_space_t address_space;
};
@@ -592,6 +612,8 @@ extern bool switch_statement_break_seen_p;
extern bool global_bindings_p (void);
extern tree pushdecl (tree);
+extern unsigned int start_underspecified_init (location_t, tree);
+extern void finish_underspecified_init (tree, unsigned int);
extern void push_scope (void);
extern tree pop_scope (void);
extern void c_bindings_start_stmt_expr (struct c_spot_bindings *);
@@ -651,7 +673,7 @@ extern void shadow_tag_warned (const struct c_declspecs *, int);
extern tree start_enum (location_t, struct c_enum_contents *, tree, tree);
extern bool start_function (struct c_declspecs *, struct c_declarator *, tree);
extern tree start_decl (struct c_declarator *, struct c_declspecs *, bool,
- tree, location_t * = NULL);
+ tree, bool = true, location_t * = NULL);
extern tree start_struct (location_t, enum tree_code, tree,
class c_struct_parse_info **);
extern void store_parm_decls (void);
@@ -722,7 +744,7 @@ extern struct c_expr default_function_array_conversion (location_t,
extern struct c_expr default_function_array_read_conversion (location_t,
struct c_expr);
extern struct c_expr convert_lvalue_to_rvalue (location_t, struct c_expr,
- bool, bool);
+ bool, bool, bool = false);
extern tree decl_constant_value_1 (tree, bool);
extern void mark_exp_read (tree);
extern tree composite_type (tree, tree);
@@ -745,7 +767,7 @@ extern tree c_cast_expr (location_t, struct c_type_name *, tree);
extern tree build_c_cast (location_t, tree, tree);
extern void store_init_value (location_t, tree, tree, tree);
extern void maybe_warn_string_init (location_t, tree, struct c_expr);
-extern void start_init (tree, tree, int, rich_location *);
+extern void start_init (tree, tree, bool, bool, rich_location *);
extern void finish_init (void);
extern void really_start_incremental_init (tree);
extern void finish_implicit_inits (location_t, struct obstack *);
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 052ae6d..e06f052 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -84,8 +84,9 @@ location_t c_last_sizeof_loc;
initializer" message within this initializer. */
static int found_missing_braces;
-static int require_constant_value;
-static int require_constant_elements;
+static bool require_constant_value;
+static bool require_constant_elements;
+static bool require_constexpr_value;
static bool null_pointer_constant_p (const_tree);
static tree qualify_type (tree, tree);
@@ -109,7 +110,8 @@ static void push_member_name (tree);
static int spelling_length (void);
static char *print_spelling (char *);
static void warning_init (location_t, int, const char *);
-static tree digest_init (location_t, tree, tree, tree, bool, bool, int);
+static tree digest_init (location_t, tree, tree, tree, bool, bool, bool, bool,
+ bool, bool);
static void output_init_element (location_t, tree, tree, bool, tree, tree, bool,
bool, struct obstack *);
static void output_pending_init_elements (int, struct obstack *);
@@ -2133,20 +2135,91 @@ really_atomic_lvalue (tree expr)
return true;
}
+/* If EXPR is a named constant (C2x) derived from a constexpr variable
+ - that is, a reference to such a variable, or a member extracted by
+ a sequence of structure and union (but not array) member accesses
+ (where union member accesses must access the same member as
+ initialized) - then return the corresponding initializer;
+ otherwise, return NULL_TREE. */
+
+static tree
+maybe_get_constexpr_init (tree expr)
+{
+ tree decl = NULL_TREE;
+ if (TREE_CODE (expr) == VAR_DECL)
+ decl = expr;
+ else if (TREE_CODE (expr) == COMPOUND_LITERAL_EXPR)
+ decl = COMPOUND_LITERAL_EXPR_DECL (expr);
+ if (decl
+ && C_DECL_DECLARED_CONSTEXPR (decl)
+ && DECL_INITIAL (decl) != NULL_TREE
+ && !error_operand_p (DECL_INITIAL (decl)))
+ return DECL_INITIAL (decl);
+ if (TREE_CODE (expr) != COMPONENT_REF)
+ return NULL_TREE;
+ tree inner = maybe_get_constexpr_init (TREE_OPERAND (expr, 0));
+ if (inner == NULL_TREE)
+ return NULL_TREE;
+ while ((CONVERT_EXPR_P (inner) || TREE_CODE (inner) == NON_LVALUE_EXPR)
+ && !error_operand_p (inner)
+ && (TYPE_MAIN_VARIANT (TREE_TYPE (inner))
+ == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (inner, 0)))))
+ inner = TREE_OPERAND (inner, 0);
+ if (TREE_CODE (inner) != CONSTRUCTOR)
+ return NULL_TREE;
+ tree field = TREE_OPERAND (expr, 1);
+ unsigned HOST_WIDE_INT cidx;
+ tree cfield, cvalue;
+ bool have_other_init = false;
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (inner), cidx, cfield, cvalue)
+ {
+ if (cfield == field)
+ return cvalue;
+ have_other_init = true;
+ }
+ if (TREE_CODE (TREE_TYPE (inner)) == UNION_TYPE
+ && (have_other_init || field != TYPE_FIELDS (TREE_TYPE (inner))))
+ return NULL_TREE;
+ /* Return a default initializer. */
+ if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (expr)))
+ return build_constructor (TREE_TYPE (expr), NULL);
+ return build_zero_cst (TREE_TYPE (expr));
+}
+
/* Convert expression EXP (location LOC) from lvalue to rvalue,
including converting functions and arrays to pointers if CONVERT_P.
- If READ_P, also mark the expression as having been read. */
+ If READ_P, also mark the expression as having been read. If
+ FOR_INIT, constexpr expressions of structure and union type should
+ be replaced by the corresponding CONSTRUCTOR; otherwise, only
+ constexpr scalars (including elements of structures and unions) are
+ replaced by their initializers. */
struct c_expr
convert_lvalue_to_rvalue (location_t loc, struct c_expr exp,
- bool convert_p, bool read_p)
+ bool convert_p, bool read_p, bool for_init)
{
+ bool force_non_npc = false;
if (read_p)
mark_exp_read (exp.value);
if (convert_p)
exp = default_function_array_conversion (loc, exp);
if (!VOID_TYPE_P (TREE_TYPE (exp.value)))
exp.value = require_complete_type (loc, exp.value);
+ if (for_init || !RECORD_OR_UNION_TYPE_P (TREE_TYPE (exp.value)))
+ {
+ tree init = maybe_get_constexpr_init (exp.value);
+ if (init != NULL_TREE)
+ {
+ /* A named constant of pointer type or type nullptr_t is not
+ a null pointer constant even if the initializer is
+ one. */
+ if (TREE_CODE (init) == INTEGER_CST
+ && !INTEGRAL_TYPE_P (TREE_TYPE (init))
+ && integer_zerop (init))
+ force_non_npc = true;
+ exp.value = init;
+ }
+ }
if (really_atomic_lvalue (exp.value))
{
vec<tree, va_gc> *params;
@@ -2187,6 +2260,8 @@ convert_lvalue_to_rvalue (location_t loc, struct c_expr exp,
if (convert_p && !error_operand_p (exp.value)
&& (TREE_CODE (TREE_TYPE (exp.value)) != ARRAY_TYPE))
exp.value = convert (build_qualified_type (TREE_TYPE (exp.value), TYPE_UNQUALIFIED), exp.value);
+ if (force_non_npc)
+ exp.value = build1 (NOP_EXPR, TREE_TYPE (exp.value), exp.value);
return exp;
}
@@ -2861,6 +2936,9 @@ build_external_ref (location_t loc, tree id, bool fun, tree *type)
{
ref = decl;
*type = TREE_TYPE (ref);
+ if (DECL_P (decl) && C_DECL_UNDERSPECIFIED (decl))
+ error_at (loc, "underspecified %qD referenced in its initializer",
+ decl);
}
else if (fun)
/* Implicit function declaration. */
@@ -6047,7 +6125,7 @@ build_c_cast (location_t loc, tree type, tree expr)
if (!maybe_const)
t = c_wrap_maybe_const (t, true);
t = digest_init (loc, type, t,
- NULL_TREE, false, true, 0);
+ NULL_TREE, false, false, false, true, false, false);
TREE_CONSTANT (t) = TREE_CONSTANT (value);
return t;
}
@@ -7848,6 +7926,8 @@ store_init_value (location_t init_loc, tree decl, tree init, tree origtype)
{
tree value, type;
bool npc = false;
+ bool int_const_expr = false;
+ bool arith_const_expr = false;
/* If variable's type was invalidly declared, just ignore it. */
@@ -7858,9 +7938,19 @@ store_init_value (location_t init_loc, tree decl, tree init, tree origtype)
/* Digest the specified initializer into an expression. */
if (init)
- npc = null_pointer_constant_p (init);
- value = digest_init (init_loc, type, init, origtype, npc,
- true, TREE_STATIC (decl));
+ {
+ npc = null_pointer_constant_p (init);
+ int_const_expr = (TREE_CODE (init) == INTEGER_CST
+ && !TREE_OVERFLOW (init)
+ && INTEGRAL_TYPE_P (TREE_TYPE (init)));
+ /* Not fully determined before folding. */
+ arith_const_expr = true;
+ }
+ bool constexpr_p = (TREE_CODE (decl) == VAR_DECL
+ && C_DECL_DECLARED_CONSTEXPR (decl));
+ value = digest_init (init_loc, type, init, origtype, npc, int_const_expr,
+ arith_const_expr, true,
+ TREE_STATIC (decl) || constexpr_p, constexpr_p);
/* Store the expression if valid; else report error. */
@@ -8030,12 +8120,151 @@ print_spelling (char *buffer)
return buffer;
}
+/* Check whether INIT, a floating or integer constant, is
+ representable in TYPE, a real floating type with the same radix.
+ Return true if OK, false if not. */
+static bool
+constexpr_init_fits_real_type (tree type, tree init)
+{
+ gcc_assert (TREE_CODE (type) == REAL_TYPE);
+ gcc_assert (TREE_CODE (init) == INTEGER_CST || TREE_CODE (init) == REAL_CST);
+ if (TREE_CODE (init) == REAL_CST
+ && TYPE_MODE (TREE_TYPE (init)) == TYPE_MODE (type))
+ /* Same mode, no conversion required. */
+ return true;
+ if (TREE_CODE (init) == INTEGER_CST)
+ {
+ tree converted = build_real_from_int_cst (type, init);
+ bool fail = false;
+ wide_int w = real_to_integer (&TREE_REAL_CST (converted), &fail,
+ TYPE_PRECISION (TREE_TYPE (init)));
+ return !fail && wi::eq_p (w, wi::to_wide (init));
+ }
+ /* exact_real_truncate is not quite right here, since it doesn't
+ allow even an exact conversion to subnormal values. */
+ REAL_VALUE_TYPE t;
+ real_convert (&t, TYPE_MODE (type), &TREE_REAL_CST (init));
+ return real_identical (&t, &TREE_REAL_CST (init));
+}
+
+/* Check whether INIT (location LOC) is valid as a 'constexpr'
+ initializer for type TYPE, and give an error if not. INIT has
+ already been folded and verified to be constant.
+ NULL_POINTER_CONSTANT, INT_CONST_EXPR and ARITH_CONST_EXPR say
+ whether it is a null pointer constant, integer constant expression
+ or arithmetic constant expression, respectively. If TYPE is not a
+ scalar type, this function does nothing. */
+
+static void
+check_constexpr_init (location_t loc, tree type, tree init,
+ bool null_pointer_constant, bool int_const_expr,
+ bool arith_const_expr)
+{
+ if (POINTER_TYPE_P (type))
+ {
+ /* The initializer must be a null pointer constant. */
+ if (!null_pointer_constant)
+ error_at (loc, "%<constexpr%> pointer initializer is not a "
+ "null pointer constant");
+ return;
+ }
+ if (INTEGRAL_TYPE_P (type))
+ {
+ /* The initializer must be an integer constant expression,
+ representable in the target type. */
+ if (!int_const_expr)
+ error_at (loc, "%<constexpr%> integer initializer is not an "
+ "integer constant expression");
+ if (!int_fits_type_p (init, type))
+ error_at (loc, "%<constexpr%> initializer not representable in "
+ "type of object");
+ return;
+ }
+ /* We don't apply any extra checks to extension types such as vector
+ or fixed-point types. */
+ if (TREE_CODE (type) != REAL_TYPE && TREE_CODE (type) != COMPLEX_TYPE)
+ return;
+ if (!arith_const_expr)
+ {
+ error_at (loc, "%<constexpr%> initializer is not an arithmetic "
+ "constant expression");
+ return;
+ }
+ /* We don't apply any extra checks to complex integers. */
+ if (TREE_CODE (type) == COMPLEX_TYPE
+ && TREE_CODE (TREE_TYPE (type)) != REAL_TYPE)
+ return;
+ /* Both the normative text and the relevant footnote are unclear, as
+ of the C2x CD, about what exactly counts as a change of value in
+ floating-point cases. Here, we consider all conversions between
+ binary and decimal types (even of infinities and NaNs, where
+ quantum exponents are not involved) as involving a change of
+ value, and likewise for conversions between real and complex
+ types (even when the complex constant has imaginary part positive
+ zero), and conversions of signaling NaN to a different machine
+ mode. But we allow exact conversions of integers to binary or
+ decimal floating types, and exact conversions between different
+ binary types or different decimal types, where "exact" in the
+ decimal case requires the quantum exponent to be preserved. */
+ if (TREE_CODE (TREE_TYPE (init)) == COMPLEX_TYPE
+ && TREE_CODE (type) == REAL_TYPE)
+ {
+ error_at (loc, "%<constexpr%> initializer for a real type is of "
+ "complex type");
+ return;
+ }
+ if (TREE_CODE (type) == COMPLEX_TYPE
+ && TREE_CODE (TREE_TYPE (init)) != COMPLEX_TYPE)
+ {
+ error_at (loc, "%<constexpr%> initializer for a complex type is of "
+ "real type");
+ return;
+ }
+ if (TREE_CODE (type) == REAL_TYPE
+ && TREE_CODE (TREE_TYPE (init)) == REAL_TYPE)
+ {
+ if (DECIMAL_FLOAT_TYPE_P (type)
+ && !DECIMAL_FLOAT_TYPE_P (TREE_TYPE (init)))
+ {
+ error_at (loc, "%<constexpr%> initializer for a decimal "
+ "floating-point type is of binary type");
+ return;
+ }
+ else if (DECIMAL_FLOAT_TYPE_P (TREE_TYPE (init))
+ && !DECIMAL_FLOAT_TYPE_P (type))
+ {
+ error_at (loc, "%<constexpr%> initializer for a binary "
+ "floating-point type is of decimal type");
+ return;
+ }
+ }
+ bool fits;
+ if (TREE_CODE (type) == COMPLEX_TYPE)
+ {
+ gcc_assert (TREE_CODE (init) == COMPLEX_CST);
+ fits = (constexpr_init_fits_real_type (TREE_TYPE (type),
+ TREE_REALPART (init))
+ && constexpr_init_fits_real_type (TREE_TYPE (type),
+ TREE_IMAGPART (init)));
+ }
+ else
+ fits = constexpr_init_fits_real_type (type, init);
+ if (!fits)
+ error_at (loc, "%<constexpr%> initializer not representable in "
+ "type of object");
+}
+
/* Digest the parser output INIT as an initializer for type TYPE.
Return a C expression of type TYPE to represent the initial value.
If ORIGTYPE is not NULL_TREE, it is the original type of INIT.
- NULL_POINTER_CONSTANT is true if INIT is a null pointer constant.
+ NULL_POINTER_CONSTANT is true if INIT is a null pointer constant,
+ INT_CONST_EXPR is true if INIT is an integer constant expression,
+ and ARITH_CONST_EXPR is true if INIT is, or might be, an arithmetic
+ constant expression, false if it has already been determined in the
+ caller that it is not (but folding may have made the value passed here
+ indistinguishable from an arithmetic constant expression).
If INIT is a string constant, STRICT_STRING is true if it is
unparenthesized or we should not warn here for it being parenthesized.
@@ -8044,12 +8273,14 @@ print_spelling (char *buffer)
INIT_LOC is the location of the INIT.
REQUIRE_CONSTANT requests an error if non-constant initializers or
- elements are seen. */
+ elements are seen. REQUIRE_CONSTEXPR means the stricter requirements
+ on initializers for 'constexpr' objects apply. */
static tree
digest_init (location_t init_loc, tree type, tree init, tree origtype,
- bool null_pointer_constant, bool strict_string,
- int require_constant)
+ bool null_pointer_constant, bool int_const_expr,
+ bool arith_const_expr, bool strict_string,
+ bool require_constant, bool require_constexpr)
{
enum tree_code code = TREE_CODE (type);
tree inside_init = init;
@@ -8072,6 +8303,20 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
}
inside_init = c_fully_fold (inside_init, require_constant, &maybe_const);
}
+ /* TODO: this may not detect all cases of expressions folding to
+ constants that are not arithmetic constant expressions. */
+ if (!maybe_const)
+ arith_const_expr = false;
+ else if (!INTEGRAL_TYPE_P (TREE_TYPE (inside_init))
+ && TREE_CODE (TREE_TYPE (inside_init)) != REAL_TYPE
+ && TREE_CODE (TREE_TYPE (inside_init)) != COMPLEX_TYPE)
+ arith_const_expr = false;
+ else if (TREE_CODE (inside_init) != INTEGER_CST
+ && TREE_CODE (inside_init) != REAL_CST
+ && TREE_CODE (inside_init) != COMPLEX_CST)
+ arith_const_expr = false;
+ else if (TREE_OVERFLOW (inside_init))
+ arith_const_expr = false;
/* Initialization of an array of chars from a string constant
optionally enclosed in braces. */
@@ -8129,6 +8374,25 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
return error_mark_node;
}
+ if (require_constexpr
+ && TYPE_UNSIGNED (typ1) != TYPE_UNSIGNED (typ2))
+ {
+ /* Check if all characters of the string can be
+ represented in the type of the constexpr object being
+ initialized. */
+ unsigned HOST_WIDE_INT len = TREE_STRING_LENGTH (inside_init);
+ const unsigned char *p =
+ (const unsigned char *) TREE_STRING_POINTER (inside_init);
+ gcc_assert (CHAR_TYPE_SIZE == 8 && CHAR_BIT == 8);
+ for (unsigned i = 0; i < len; i++)
+ if (p[i] > 127)
+ {
+ error_init (init_loc, "%<constexpr%> initializer not "
+ "representable in type of object");
+ break;
+ }
+ }
+
if (TYPE_DOMAIN (type) != NULL_TREE
&& TYPE_SIZE (type) != NULL_TREE
&& TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
@@ -8291,6 +8555,10 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
else if (require_constant && !maybe_const)
pedwarn_init (init_loc, OPT_Wpedantic,
"initializer element is not a constant expression");
+ else if (require_constexpr)
+ check_constexpr_init (init_loc, type, inside_init,
+ null_pointer_constant, int_const_expr,
+ arith_const_expr);
/* Added to enable additional -Wsuggest-attribute=format warnings. */
if (TREE_CODE (TREE_TYPE (inside_init)) == POINTER_TYPE)
@@ -8309,6 +8577,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
|| code == POINTER_TYPE || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE
|| code == COMPLEX_TYPE || code == VECTOR_TYPE)
{
+ tree unconverted_init = inside_init;
if (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE
&& (TREE_CODE (init) == STRING_CST
|| TREE_CODE (init) == COMPOUND_LITERAL_EXPR))
@@ -8342,6 +8611,10 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
else if (require_constant && !maybe_const)
pedwarn_init (init_loc, OPT_Wpedantic,
"initializer element is not a constant expression");
+ else if (require_constexpr)
+ check_constexpr_init (init_loc, type, unconverted_init,
+ null_pointer_constant, int_const_expr,
+ arith_const_expr);
return inside_init;
}
@@ -8441,9 +8714,6 @@ static int constructor_depth;
such as (struct foo) {...}. */
static tree constructor_decl;
-/* Nonzero if this is an initializer for a top-level decl. */
-static int constructor_top_level;
-
/* Nonzero if there were any member designators in this initializer. */
static int constructor_designated;
@@ -8520,9 +8790,9 @@ struct initializer_stack
struct spelling *spelling;
struct spelling *spelling_base;
int spelling_size;
- char top_level;
char require_constant_value;
char require_constant_elements;
+ char require_constexpr_value;
char designated;
rich_location *missing_brace_richloc;
};
@@ -8532,7 +8802,8 @@ static struct initializer_stack *initializer_stack;
/* Prepare to parse and output the initializer for variable DECL. */
void
-start_init (tree decl, tree asmspec_tree ATTRIBUTE_UNUSED, int top_level,
+start_init (tree decl, tree asmspec_tree ATTRIBUTE_UNUSED,
+ bool init_require_constant, bool init_require_constexpr,
rich_location *richloc)
{
const char *locus;
@@ -8541,13 +8812,13 @@ start_init (tree decl, tree asmspec_tree ATTRIBUTE_UNUSED, int top_level,
p->decl = constructor_decl;
p->require_constant_value = require_constant_value;
p->require_constant_elements = require_constant_elements;
+ p->require_constexpr_value = require_constexpr_value;
p->constructor_stack = constructor_stack;
p->constructor_range_stack = constructor_range_stack;
p->elements = constructor_elements;
p->spelling = spelling;
p->spelling_base = spelling_base;
p->spelling_size = spelling_size;
- p->top_level = constructor_top_level;
p->next = initializer_stack;
p->missing_brace_richloc = richloc;
p->designated = constructor_designated;
@@ -8555,13 +8826,13 @@ start_init (tree decl, tree asmspec_tree ATTRIBUTE_UNUSED, int top_level,
constructor_decl = decl;
constructor_designated = 0;
- constructor_top_level = top_level;
+ require_constant_value = init_require_constant;
+ require_constexpr_value = init_require_constexpr;
if (decl != NULL_TREE && decl != error_mark_node)
{
- require_constant_value = TREE_STATIC (decl);
require_constant_elements
- = ((TREE_STATIC (decl) || (pedantic && !flag_isoc99))
+ = ((init_require_constant || (pedantic && !flag_isoc99))
/* For a scalar, you can always use any value to initialize,
even within braces. */
&& AGGREGATE_TYPE_P (TREE_TYPE (decl)));
@@ -8569,8 +8840,7 @@ start_init (tree decl, tree asmspec_tree ATTRIBUTE_UNUSED, int top_level,
}
else
{
- require_constant_value = 0;
- require_constant_elements = 0;
+ require_constant_elements = false;
locus = _("(anonymous)");
}
@@ -8608,6 +8878,7 @@ finish_init (void)
constructor_decl = p->decl;
require_constant_value = p->require_constant_value;
require_constant_elements = p->require_constant_elements;
+ require_constexpr_value = p->require_constexpr_value;
constructor_stack = p->constructor_stack;
constructor_designated = p->designated;
constructor_range_stack = p->constructor_range_stack;
@@ -8615,7 +8886,6 @@ finish_init (void)
spelling = p->spelling;
spelling_base = p->spelling_base;
spelling_size = p->spelling_size;
- constructor_top_level = p->top_level;
initializer_stack = p->next;
XDELETE (p);
}
@@ -9093,6 +9363,10 @@ pop_init_level (location_t loc, int implicit,
{
if (constructor_erroneous || constructor_type == error_mark_node)
ret.value = error_mark_node;
+ else if (TREE_CODE (constructor_type) == POINTER_TYPE)
+ /* Ensure this is a null pointer constant in the case of a
+ 'constexpr' object initialized with {}. */
+ ret.value = build_zero_cst (ptr_type_node);
else
ret.value = build_zero_cst (constructor_type);
}
@@ -9841,7 +10115,7 @@ output_init_element (location_t loc, tree value, tree origtype,
{
tree semantic_type = NULL_TREE;
bool maybe_const = true;
- bool npc;
+ bool npc, int_const_expr, arith_const_expr;
if (type == error_mark_node || value == error_mark_node)
{
@@ -9872,12 +10146,31 @@ output_init_element (location_t loc, tree value, tree origtype,
}
npc = null_pointer_constant_p (value);
+ int_const_expr = (TREE_CODE (value) == INTEGER_CST
+ && !TREE_OVERFLOW (value)
+ && INTEGRAL_TYPE_P (TREE_TYPE (value)));
+ /* Not fully determined before folding. */
+ arith_const_expr = true;
if (TREE_CODE (value) == EXCESS_PRECISION_EXPR)
{
semantic_type = TREE_TYPE (value);
value = TREE_OPERAND (value, 0);
}
value = c_fully_fold (value, require_constant_value, &maybe_const);
+ /* TODO: this may not detect all cases of expressions folding to
+ constants that are not arithmetic constant expressions. */
+ if (!maybe_const)
+ arith_const_expr = false;
+ else if (!INTEGRAL_TYPE_P (TREE_TYPE (value))
+ && TREE_CODE (TREE_TYPE (value)) != REAL_TYPE
+ && TREE_CODE (TREE_TYPE (value)) != COMPLEX_TYPE)
+ arith_const_expr = false;
+ else if (TREE_CODE (value) != INTEGER_CST
+ && TREE_CODE (value) != REAL_CST
+ && TREE_CODE (value) != COMPLEX_CST)
+ arith_const_expr = false;
+ else if (TREE_OVERFLOW (value))
+ arith_const_expr = false;
if (value == error_mark_node)
constructor_erroneous = 1;
@@ -9900,8 +10193,18 @@ output_init_element (location_t loc, tree value, tree origtype,
tree new_value = value;
if (semantic_type)
new_value = build1 (EXCESS_PRECISION_EXPR, semantic_type, value);
- new_value = digest_init (loc, type, new_value, origtype, npc, strict_string,
- require_constant_value);
+ /* In the case of braces around a scalar initializer, the result of
+ this initializer processing goes through digest_init again at the
+ outer level. In the case of a constexpr initializer for a
+ pointer, avoid converting a null pointer constant to something
+ that is not a null pointer constant to avoid a spurious error
+ from that second processing. */
+ if (!require_constexpr_value
+ || !npc
+ || TREE_CODE (constructor_type) != POINTER_TYPE)
+ new_value = digest_init (loc, type, new_value, origtype, npc,
+ int_const_expr, arith_const_expr, strict_string,
+ require_constant_value, require_constexpr_value);
if (new_value == error_mark_node)
{
constructor_erroneous = 1;
@@ -9926,6 +10229,11 @@ output_init_element (location_t loc, tree value, tree origtype,
&& (require_constant_value || require_constant_elements))
pedwarn_init (loc, OPT_Wpedantic,
"initializer element is not a constant expression");
+ /* digest_init has already carried out the additional checks
+ required for 'constexpr' initializers (using the information
+ passed to it about whether the original initializer was certain
+ kinds of constant expression), so that check does not need to be
+ repeated here. */
/* Issue -Wc++-compat warnings about initializing a bitfield with
enum type. */
diff --git a/gcc/cfgbuild.cc b/gcc/cfgbuild.cc
index bec9245..646a066 100644
--- a/gcc/cfgbuild.cc
+++ b/gcc/cfgbuild.cc
@@ -445,6 +445,7 @@ find_bb_boundaries (basic_block bb)
rtx_insn *debug_insn = NULL;
edge fallthru = NULL;
bool skip_purge;
+ bool seen_note_after_debug = false;
if (insn == end)
return;
@@ -492,7 +493,10 @@ find_bb_boundaries (basic_block bb)
if (code == DEBUG_INSN)
{
if (flow_transfer_insn && !debug_insn)
- debug_insn = insn;
+ {
+ debug_insn = insn;
+ seen_note_after_debug = false;
+ }
}
/* In case we've previously seen an insn that effects a control
flow transfer, split the block. */
@@ -506,7 +510,40 @@ find_bb_boundaries (basic_block bb)
insn instead of before the non-debug insn, so that the debug
insns are not lost. */
if (debug_insn && code != CODE_LABEL && code != BARRIER)
- prev = PREV_INSN (debug_insn);
+ {
+ prev = PREV_INSN (debug_insn);
+ if (seen_note_after_debug)
+ {
+ /* Though, if there are NOTEs intermixed with DEBUG_INSNs,
+ move the NOTEs before the DEBUG_INSNs and split after
+ the last NOTE. */
+ rtx_insn *first = NULL, *last = NULL;
+ for (x = debug_insn; x != insn; x = NEXT_INSN (x))
+ {
+ if (NOTE_P (x))
+ {
+ if (first == NULL)
+ first = x;
+ last = x;
+ }
+ else
+ {
+ gcc_assert (DEBUG_INSN_P (x));
+ if (first)
+ {
+ reorder_insns_nobb (first, last, prev);
+ prev = last;
+ first = last = NULL;
+ }
+ }
+ }
+ if (first)
+ {
+ reorder_insns_nobb (first, last, prev);
+ prev = last;
+ }
+ }
+ }
fallthru = split_block (bb, prev);
if (flow_transfer_insn)
{
@@ -547,6 +584,14 @@ find_bb_boundaries (basic_block bb)
flow_transfer_insn = prev_nonnote_nondebug_insn_bb (insn);
debug_insn = NULL;
}
+ else if (debug_insn)
+ {
+ if (code == NOTE)
+ seen_note_after_debug = true;
+ else
+ /* Jump tables. */
+ debug_insn = NULL;
+ }
if (control_flow_insn_p (insn))
flow_transfer_insn = insn;
diff --git a/gcc/cfghooks.cc b/gcc/cfghooks.cc
index 29ded57..f8fa13c 100644
--- a/gcc/cfghooks.cc
+++ b/gcc/cfghooks.cc
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-core.h"
#include "dumpfile.h"
#include "cfganal.h"
+#include "tree.h"
#include "tree-ssa.h"
#include "cfgloop.h"
#include "sreal.h"
diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 5851b2f..f15cb47 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -2490,7 +2490,6 @@ cgraph_node::make_local (cgraph_node *node, void *)
node->externally_visible = false;
node->forced_by_abi = false;
node->local = true;
- node->set_section (NULL);
node->unique_name = ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
|| node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
&& !flag_incremental_link);
diff --git a/gcc/common.opt b/gcc/common.opt
index bce3e51..562d73d 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -539,8 +539,7 @@ Common Var(warn_aggressive_loop_optimizations) Init(1) Warning
Warn if a loop with constant number of iterations triggers undefined behavior.
Warray-bounds
-Common Var(warn_array_bounds) Warning
-Warn if an array is accessed out of bounds.
+Common Alias(Warray-bounds=, 1, 0) Warning
Warray-bounds=
Common Joined RejectNegative UInteger Var(warn_array_bounds) Warning IntegerRange(0, 2)
@@ -2174,6 +2173,10 @@ fmove-loop-stores
Common Var(flag_move_loop_stores) Optimization
Move stores out of loops.
+fmultiflags
+Common Driver
+Building block for specs-based multilib-aware TFLAGS.
+
fdce
Common Var(flag_dce) Init(1) Optimization
Use the RTL dead code elimination pass.
@@ -2214,6 +2217,28 @@ fomit-frame-pointer
Common Var(flag_omit_frame_pointer) Optimization
When possible do not generate stack frames.
+fopenmp-target-simd-clone
+Common Alias(fopenmp-target-simd-clone=,any,none)
+
+fopenmp-target-simd-clone=
+Common Joined RejectNegative Enum(target_simd_clone_device) Var(flag_openmp_target_simd_clone) Init(OMP_TARGET_SIMD_CLONE_NONE) Optimization
+Generate SIMD clones for functions with the OpenMP declare target directive.
+
+Enum
+Name(target_simd_clone_device) Type(int)
+
+EnumValue
+Enum(target_simd_clone_device) String(none) Value(OMP_TARGET_SIMD_CLONE_NONE)
+
+EnumValue
+Enum(target_simd_clone_device) String(host) Value(OMP_TARGET_SIMD_CLONE_HOST)
+
+EnumValue
+Enum(target_simd_clone_device) String(nohost) Value(OMP_TARGET_SIMD_CLONE_NOHOST)
+
+EnumValue
+Enum(target_simd_clone_device) String(any) Value(OMP_TARGET_SIMD_CLONE_ANY)
+
fopt-info
Common Var(flag_opt_info) Optimization
Enable all optimization info dumps on stderr.
diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
index 62c3d1b..4d1bcff 100644
--- a/gcc/common/config/i386/cpuinfo.h
+++ b/gcc/common/config/i386/cpuinfo.h
@@ -558,6 +558,27 @@ get_intel_cpu (struct __processor_model *cpu_model,
cpu_model->__cpu_type = INTEL_COREI7;
cpu_model->__cpu_subtype = INTEL_COREI7_SAPPHIRERAPIDS;
break;
+ case 0xaf:
+ /* Sierra Forest. */
+ cpu = "sierraforest";
+ CHECK___builtin_cpu_is ("sierraforest");
+ cpu_model->__cpu_type = INTEL_SIERRAFOREST;
+ break;
+ case 0xad:
+ case 0xae:
+ /* Granite Rapids. */
+ cpu = "graniterapids";
+ CHECK___builtin_cpu_is ("corei7");
+ CHECK___builtin_cpu_is ("graniterapids");
+ cpu_model->__cpu_type = INTEL_COREI7;
+ cpu_model->__cpu_subtype = INTEL_COREI7_GRANITERAPIDS;
+ break;
+ case 0xb6:
+ /* Grand Ridge. */
+ cpu = "grandridge";
+ CHECK___builtin_cpu_is ("grandridge");
+ cpu_model->__cpu_type = INTEL_GRANDRIDGE;
+ break;
case 0x17:
case 0x1d:
/* Penryn. */
@@ -831,6 +852,12 @@ get_available_features (struct __processor_model *cpu_model,
__cpuid_count (7, 1, eax, ebx, ecx, edx);
if (eax & bit_HRESET)
set_feature (FEATURE_HRESET);
+ if (eax & bit_CMPCCXADD)
+ set_feature(FEATURE_CMPCCXADD);
+ if (edx & bit_PREFETCHI)
+ set_feature (FEATURE_PREFETCHI);
+ if (eax & bit_RAOINT)
+ set_feature (FEATURE_RAOINT);
if (avx_usable)
{
if (eax & bit_AVXVNNI)
@@ -847,6 +874,11 @@ get_available_features (struct __processor_model *cpu_model,
if (eax & bit_AVX512BF16)
set_feature (FEATURE_AVX512BF16);
}
+ if (amx_usable)
+ {
+ if (eax & bit_AMX_FP16)
+ set_feature (FEATURE_AMX_FP16);
+ }
}
/* Get Advanced Features at level 0xd (eax = 0xd, ecx = 1). */
diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc
index cd6ad2c..660a977 100644
--- a/gcc/common/config/i386/i386-common.cc
+++ b/gcc/common/config/i386/i386-common.cc
@@ -106,10 +106,17 @@ along with GCC; see the file COPYING3. If not see
#define OPTION_MASK_ISA_CLWB_SET OPTION_MASK_ISA_CLWB
#define OPTION_MASK_ISA2_AVX512VP2INTERSECT_SET OPTION_MASK_ISA2_AVX512VP2INTERSECT
#define OPTION_MASK_ISA2_AMX_TILE_SET OPTION_MASK_ISA2_AMX_TILE
-#define OPTION_MASK_ISA2_AMX_INT8_SET OPTION_MASK_ISA2_AMX_INT8
-#define OPTION_MASK_ISA2_AMX_BF16_SET OPTION_MASK_ISA2_AMX_BF16
+#define OPTION_MASK_ISA2_AMX_INT8_SET \
+ (OPTION_MASK_ISA2_AMX_TILE | OPTION_MASK_ISA2_AMX_INT8)
+#define OPTION_MASK_ISA2_AMX_BF16_SET \
+ (OPTION_MASK_ISA2_AMX_TILE | OPTION_MASK_ISA2_AMX_BF16)
#define OPTION_MASK_ISA2_AVXVNNIINT8_SET OPTION_MASK_ISA2_AVXVNNIINT8
#define OPTION_MASK_ISA2_AVXNECONVERT_SET OPTION_MASK_ISA2_AVXNECONVERT
+#define OPTION_MASK_ISA2_CMPCCXADD_SET OPTION_MASK_ISA2_CMPCCXADD
+#define OPTION_MASK_ISA2_AMX_FP16_SET \
+ (OPTION_MASK_ISA2_AMX_TILE | OPTION_MASK_ISA2_AMX_FP16)
+#define OPTION_MASK_ISA2_PREFETCHI_SET OPTION_MASK_ISA2_PREFETCHI
+#define OPTION_MASK_ISA2_RAOINT_SET OPTION_MASK_ISA2_RAOINT
/* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same
as -msse4.2. */
@@ -273,7 +280,9 @@ along with GCC; see the file COPYING3. If not see
#define OPTION_MASK_ISA2_SERIALIZE_UNSET OPTION_MASK_ISA2_SERIALIZE
#define OPTION_MASK_ISA2_AVX512VP2INTERSECT_UNSET OPTION_MASK_ISA2_AVX512VP2INTERSECT
#define OPTION_MASK_ISA2_TSXLDTRK_UNSET OPTION_MASK_ISA2_TSXLDTRK
-#define OPTION_MASK_ISA2_AMX_TILE_UNSET OPTION_MASK_ISA2_AMX_TILE
+#define OPTION_MASK_ISA2_AMX_TILE_UNSET \
+ (OPTION_MASK_ISA2_AMX_TILE | OPTION_MASK_ISA2_AMX_INT8_UNSET \
+ | OPTION_MASK_ISA2_AMX_BF16_UNSET | OPTION_MASK_ISA2_AMX_FP16_UNSET)
#define OPTION_MASK_ISA2_AMX_INT8_UNSET OPTION_MASK_ISA2_AMX_INT8
#define OPTION_MASK_ISA2_AMX_BF16_UNSET OPTION_MASK_ISA2_AMX_BF16
#define OPTION_MASK_ISA2_UINTR_UNSET OPTION_MASK_ISA2_UINTR
@@ -283,6 +292,10 @@ along with GCC; see the file COPYING3. If not see
#define OPTION_MASK_ISA2_WIDEKL_UNSET OPTION_MASK_ISA2_WIDEKL
#define OPTION_MASK_ISA2_AVXVNNIINT8_UNSET OPTION_MASK_ISA2_AVXVNNIINT8
#define OPTION_MASK_ISA2_AVXNECONVERT_UNSET OPTION_MASK_ISA2_AVXNECONVERT
+#define OPTION_MASK_ISA2_CMPCCXADD_UNSET OPTION_MASK_ISA2_CMPCCXADD
+#define OPTION_MASK_ISA2_AMX_FP16_UNSET OPTION_MASK_ISA2_AMX_FP16
+#define OPTION_MASK_ISA2_PREFETCHI_UNSET OPTION_MASK_ISA2_PREFETCHI
+#define OPTION_MASK_ISA2_RAOINT_UNSET OPTION_MASK_ISA2_RAOINT
/* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same
as -mno-sse4.1. */
@@ -1181,6 +1194,58 @@ ix86_handle_option (struct gcc_options *opts,
}
return true;
+ case OPT_mcmpccxadd:
+ if (value)
+ {
+ opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_CMPCCXADD_SET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_CMPCCXADD_SET;
+ }
+ else
+ {
+ opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_CMPCCXADD_UNSET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_CMPCCXADD_UNSET;
+ }
+ return true;
+
+ case OPT_mamx_fp16:
+ if (value)
+ {
+ opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_AMX_FP16_SET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AMX_FP16_SET;
+ }
+ else
+ {
+ opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AMX_FP16_UNSET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AMX_FP16_UNSET;
+ }
+ return true;
+
+ case OPT_mprefetchi:
+ if (value)
+ {
+ opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_PREFETCHI_SET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_PREFETCHI_SET;
+ }
+ else
+ {
+ opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_PREFETCHI_UNSET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_PREFETCHI_UNSET;
+ }
+ return true;
+
+ case OPT_mraoint:
+ if (value)
+ {
+ opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_RAOINT_SET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_RAOINT_SET;
+ }
+ else
+ {
+ opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_RAOINT_UNSET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_RAOINT_UNSET;
+ }
+ return true;
+
case OPT_mfma:
if (value)
{
@@ -1743,6 +1808,15 @@ static const struct default_options ix86_option_optimization_table[] =
/* The STC algorithm produces the smallest code at -Os, for x86. */
{ OPT_LEVELS_2_PLUS, OPT_freorder_blocks_algorithm_, NULL,
REORDER_BLOCKS_ALGORITHM_STC },
+
+ /* Turn on -funroll-loops with -munroll-only-small-loops to enable small
+ loop unrolling at -O2. */
+ { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_funroll_loops, NULL, 1 },
+ { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_munroll_only_small_loops, NULL, 1 },
+ /* Turns off -frename-registers and -fweb which are enabled by
+ funroll-loops. */
+ { OPT_LEVELS_ALL, OPT_frename_registers, NULL, 0 },
+ { OPT_LEVELS_ALL, OPT_fweb, NULL, 0 },
/* Turn off -fschedule-insns by default. It tends to make the
problem with not enough registers even worse. */
{ OPT_LEVELS_ALL, OPT_fschedule_insns, NULL, 0 },
@@ -1859,6 +1933,8 @@ const char *const processor_names[] =
"goldmont",
"goldmont-plus",
"tremont",
+ "sierraforest",
+ "grandridge",
"knl",
"knm",
"skylake",
@@ -1872,6 +1948,7 @@ const char *const processor_names[] =
"sapphirerapids",
"alderlake",
"rocketlake",
+ "graniterapids",
"intel",
"lujiazui",
"geode",
@@ -1991,6 +2068,8 @@ const pta processor_alias_table[] =
M_CPU_SUBTYPE (INTEL_COREI7_ALDERLAKE), P_PROC_AVX2},
{"meteorlake", PROCESSOR_ALDERLAKE, CPU_HASWELL, PTA_ALDERLAKE,
M_CPU_SUBTYPE (INTEL_COREI7_ALDERLAKE), P_PROC_AVX2},
+ {"graniterapids", PROCESSOR_GRANITERAPIDS, CPU_HASWELL, PTA_GRANITERAPIDS,
+ M_CPU_SUBTYPE (INTEL_COREI7_GRANITERAPIDS), P_PROC_AVX512F},
{"bonnell", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL,
M_CPU_TYPE (INTEL_BONNELL), P_PROC_SSSE3},
{"atom", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL,
@@ -2005,6 +2084,10 @@ const pta processor_alias_table[] =
M_CPU_TYPE (INTEL_GOLDMONT_PLUS), P_PROC_SSE4_2},
{"tremont", PROCESSOR_TREMONT, CPU_HASWELL, PTA_TREMONT,
M_CPU_TYPE (INTEL_TREMONT), P_PROC_SSE4_2},
+ {"sierraforest", PROCESSOR_SIERRAFOREST, CPU_HASWELL, PTA_SIERRAFOREST,
+ M_CPU_SUBTYPE (INTEL_SIERRAFOREST), P_PROC_AVX2},
+ {"grandridge", PROCESSOR_GRANDRIDGE, CPU_HASWELL, PTA_GRANDRIDGE,
+ M_CPU_TYPE (INTEL_GRANDRIDGE), P_PROC_AVX2},
{"knl", PROCESSOR_KNL, CPU_SLM, PTA_KNL,
M_CPU_TYPE (INTEL_KNL), P_PROC_AVX512F},
{"knm", PROCESSOR_KNM, CPU_SLM, PTA_KNM,
diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h
index 4fbbfa5..fe2e9e2 100644
--- a/gcc/common/config/i386/i386-cpuinfo.h
+++ b/gcc/common/config/i386/i386-cpuinfo.h
@@ -60,6 +60,8 @@ enum processor_types
INTEL_TREMONT,
AMDFAM19H,
ZHAOXIN_FAM7H,
+ INTEL_SIERRAFOREST,
+ INTEL_GRANDRIDGE,
CPU_TYPE_MAX,
BUILTIN_CPU_TYPE_MAX = CPU_TYPE_MAX
};
@@ -95,6 +97,7 @@ enum processor_subtypes
INTEL_COREI7_ROCKETLAKE,
ZHAOXIN_FAM7H_LUJIAZUI,
AMDFAM19H_ZNVER4,
+ INTEL_COREI7_GRANITERAPIDS,
CPU_SUBTYPE_MAX
};
@@ -246,6 +249,10 @@ enum processor_features
FEATURE_AVXIFMA,
FEATURE_AVXVNNIINT8,
FEATURE_AVXNECONVERT,
+ FEATURE_CMPCCXADD,
+ FEATURE_AMX_FP16,
+ FEATURE_PREFETCHI,
+ FEATURE_RAOINT,
CPU_FEATURE_MAX
};
diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h
index bceaee5..ba2c2d9 100644
--- a/gcc/common/config/i386/i386-isas.h
+++ b/gcc/common/config/i386/i386-isas.h
@@ -180,4 +180,8 @@ ISA_NAMES_TABLE_START
P_NONE, "-mavxvnniint8")
ISA_NAMES_TABLE_ENTRY("avxneconvert", FEATURE_AVXNECONVERT,
P_NONE, "-mavxneconvert")
+ ISA_NAMES_TABLE_ENTRY("cmpccxadd", FEATURE_CMPCCXADD, P_NONE, "-mcmpccxadd")
+ ISA_NAMES_TABLE_ENTRY("amx-fp16", FEATURE_AMX_FP16, P_NONE, "-mamx-fp16")
+ ISA_NAMES_TABLE_ENTRY("prefetchi", FEATURE_PREFETCHI, P_NONE, "-mprefetchi")
+ ISA_NAMES_TABLE_ENTRY("raoint", FEATURE_RAOINT, P_NONE, "-mraoint")
ISA_NAMES_TABLE_END
diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index d6404a0..4b7f777 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -163,6 +163,8 @@ static const struct riscv_ext_version riscv_ext_version_table[] =
{"zifencei", ISA_SPEC_CLASS_20191213, 2, 0},
{"zifencei", ISA_SPEC_CLASS_20190608, 2, 0},
+ {"zawrs", ISA_SPEC_CLASS_NONE, 1, 0},
+
{"zba", ISA_SPEC_CLASS_NONE, 1, 0},
{"zbb", ISA_SPEC_CLASS_NONE, 1, 0},
{"zbc", ISA_SPEC_CLASS_NONE, 1, 0},
@@ -1180,6 +1182,8 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
{"zicsr", &gcc_options::x_riscv_zi_subext, MASK_ZICSR},
{"zifencei", &gcc_options::x_riscv_zi_subext, MASK_ZIFENCEI},
+ {"zawrs", &gcc_options::x_riscv_za_subext, MASK_ZAWRS},
+
{"zba", &gcc_options::x_riscv_zb_subext, MASK_ZBA},
{"zbb", &gcc_options::x_riscv_zb_subext, MASK_ZBB},
{"zbc", &gcc_options::x_riscv_zb_subext, MASK_ZBC},
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 98a905e..531592c 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -433,7 +433,9 @@ i[34567]86-*-* | x86_64-*-*)
amxbf16intrin.h x86gprintrin.h uintrintrin.h
hresetintrin.h keylockerintrin.h avxvnniintrin.h
mwaitintrin.h avx512fp16intrin.h avx512fp16vlintrin.h
- avxifmaintrin.h avxvnniint8intrin.h avxneconvertintrin.h"
+ avxifmaintrin.h avxvnniint8intrin.h avxneconvertintrin.h
+ cmpccxaddintrin.h amxfp16intrin.h prfchiintrin.h
+ raointintrin.h"
;;
ia64-*-*)
extra_headers=ia64intrin.h
@@ -570,6 +572,7 @@ tic6x-*-*)
;;
xtensa*-*-*)
extra_options="${extra_options} fused-madd.opt"
+ extra_objs="xtensa-dynconfig.o"
;;
esac
@@ -687,7 +690,8 @@ slm nehalem westmere sandybridge ivybridge haswell broadwell bonnell \
silvermont knl knm skylake-avx512 cannonlake icelake-client icelake-server \
skylake goldmont goldmont-plus tremont cascadelake tigerlake cooperlake \
sapphirerapids alderlake rocketlake eden-x2 nano nano-1000 nano-2000 nano-3000 \
-nano-x2 eden-x4 nano-x4 lujiazui x86-64 x86-64-v2 x86-64-v3 x86-64-v4 native"
+nano-x2 eden-x4 nano-x4 lujiazui x86-64 x86-64-v2 x86-64-v3 x86-64-v4 \
+sierraforest graniterapids grandridge native"
# Additional x86 processors supported by --with-cpu=. Each processor
# MUST be separated by exactly one space.
@@ -3593,14 +3597,6 @@ case ${target} in
;;
esac
-# Build mkoffload tool
-case ${target} in
-*-intelmic-* | *-intelmicemul-*)
- tmake_file="${tmake_file} i386/t-intelmic"
- tm_file="${tm_file} i386/intelmic-offload.h"
- ;;
-esac
-
if [ "$target_has_targetcm" = "no" ]; then
c_target_objs="$c_target_objs default-c.o"
cxx_target_objs="$cxx_target_objs default-c.o"
diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc
index e296c73..e47b6a8 100644
--- a/gcc/config/aarch64/aarch64-c.cc
+++ b/gcc/config/aarch64/aarch64-c.cc
@@ -195,6 +195,8 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
builtin_define_with_int_value ("__ARM_FEATURE_PAC_DEFAULT", v);
}
+ aarch64_def_or_undef (TARGET_PAUTH, "__ARM_FEATURE_PAUTH", pfile);
+ aarch64_def_or_undef (TARGET_BTI, "__ARM_FEATURE_BTI", pfile);
aarch64_def_or_undef (TARGET_I8MM, "__ARM_FEATURE_MATMUL_INT8", pfile);
aarch64_def_or_undef (TARGET_BF16_SIMD,
"__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", pfile);
diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def
index e9a4b62..8140115 100644
--- a/gcc/config/aarch64/aarch64-cores.def
+++ b/gcc/config/aarch64/aarch64-cores.def
@@ -70,6 +70,7 @@ AARCH64_CORE("thunderxt83", thunderxt83, thunderx, V8A, (CRC, CRYPTO), thu
/* Ampere Computing ('\xC0') cores. */
AARCH64_CORE("ampere1", ampere1, cortexa57, V8_6A, (F16, RNG, AES, SHA3), ampere1, 0xC0, 0xac3, -1)
+AARCH64_CORE("ampere1a", ampere1a, cortexa57, V8_6A, (F16, RNG, AES, SHA3, MEMTAG), ampere1a, 0xC0, 0xac4, -1)
/* Do not swap around "emag" and "xgene1",
this order is required to handle variant correctly. */
AARCH64_CORE("emag", emag, xgene1, V8A, (CRC, CRYPTO), emag, 0x50, 0x000, 3)
@@ -110,6 +111,7 @@ AARCH64_CORE("cortex-a78c", cortexa78c, cortexa57, V8_2A, (F16, RCPC, DOTPROD,
AARCH64_CORE("cortex-a65", cortexa65, cortexa53, V8_2A, (F16, RCPC, DOTPROD, SSBS), cortexa73, 0x41, 0xd06, -1)
AARCH64_CORE("cortex-a65ae", cortexa65ae, cortexa53, V8_2A, (F16, RCPC, DOTPROD, SSBS), cortexa73, 0x41, 0xd43, -1)
AARCH64_CORE("cortex-x1", cortexx1, cortexa57, V8_2A, (F16, RCPC, DOTPROD, SSBS, PROFILE), neoversen1, 0x41, 0xd44, -1)
+AARCH64_CORE("cortex-x1c", cortexx1c, cortexa57, V8_2A, (F16, RCPC, DOTPROD, SSBS, PROFILE, PAUTH), neoversen1, 0x41, 0xd4c, -1)
AARCH64_CORE("ares", ares, cortexa57, V8_2A, (F16, RCPC, DOTPROD, PROFILE), neoversen1, 0x41, 0xd0c, -1)
AARCH64_CORE("neoverse-n1", neoversen1, cortexa57, V8_2A, (F16, RCPC, DOTPROD, PROFILE), neoversen1, 0x41, 0xd0c, -1)
AARCH64_CORE("neoverse-e1", neoversee1, cortexa53, V8_2A, (F16, RCPC, DOTPROD, SSBS), cortexa73, 0x41, 0xd4a, -1)
@@ -167,8 +169,12 @@ AARCH64_CORE("cortex-a510", cortexa510, cortexa55, V9A, (SVE2_BITPERM, MEMTAG,
AARCH64_CORE("cortex-a710", cortexa710, cortexa57, V9A, (SVE2_BITPERM, MEMTAG, I8MM, BF16), neoversen2, 0x41, 0xd47, -1)
+AARCH64_CORE("cortex-a715", cortexa715, cortexa57, V9A, (SVE2_BITPERM, MEMTAG, I8MM, BF16), neoversen2, 0x41, 0xd4d, -1)
+
AARCH64_CORE("cortex-x2", cortexx2, cortexa57, V9A, (SVE2_BITPERM, MEMTAG, I8MM, BF16), neoversen2, 0x41, 0xd48, -1)
+AARCH64_CORE("cortex-x3", cortexx3, cortexa57, V9A, (SVE2_BITPERM, MEMTAG, I8MM, BF16), neoversen2, 0x41, 0xd4e, -1)
+
AARCH64_CORE("neoverse-n2", neoversen2, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversen2, 0x41, 0xd49, -1)
AARCH64_CORE("demeter", demeter, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1)
diff --git a/gcc/config/aarch64/aarch64-cost-tables.h b/gcc/config/aarch64/aarch64-cost-tables.h
index 760d7b3..4852260 100644
--- a/gcc/config/aarch64/aarch64-cost-tables.h
+++ b/gcc/config/aarch64/aarch64-cost-tables.h
@@ -775,4 +775,111 @@ const struct cpu_cost_table ampere1_extra_costs =
}
};
+const struct cpu_cost_table ampere1a_extra_costs =
+{
+ /* ALU */
+ {
+ 0, /* arith. */
+ 0, /* logical. */
+ 0, /* shift. */
+ COSTS_N_INSNS (1), /* shift_reg. */
+ 0, /* arith_shift. */
+ COSTS_N_INSNS (1), /* arith_shift_reg. */
+ 0, /* log_shift. */
+ COSTS_N_INSNS (1), /* log_shift_reg. */
+ 0, /* extend. */
+ COSTS_N_INSNS (1), /* extend_arith. */
+ 0, /* bfi. */
+ 0, /* bfx. */
+ 0, /* clz. */
+ 0, /* rev. */
+ 0, /* non_exec. */
+ true /* non_exec_costs_exec. */
+ },
+ {
+ /* MULT SImode */
+ {
+ COSTS_N_INSNS (3), /* simple. */
+ COSTS_N_INSNS (3), /* flag_setting. */
+ COSTS_N_INSNS (3), /* extend. */
+ COSTS_N_INSNS (4), /* add. */
+ COSTS_N_INSNS (4), /* extend_add. */
+ COSTS_N_INSNS (19) /* idiv. */
+ },
+ /* MULT DImode */
+ {
+ COSTS_N_INSNS (3), /* simple. */
+ 0, /* flag_setting (N/A). */
+ COSTS_N_INSNS (3), /* extend. */
+ COSTS_N_INSNS (4), /* add. */
+ COSTS_N_INSNS (4), /* extend_add. */
+ COSTS_N_INSNS (35) /* idiv. */
+ }
+ },
+ /* LD/ST */
+ {
+ COSTS_N_INSNS (4), /* load. */
+ COSTS_N_INSNS (4), /* load_sign_extend. */
+ 0, /* ldrd (n/a). */
+ 0, /* ldm_1st. */
+ 0, /* ldm_regs_per_insn_1st. */
+ 0, /* ldm_regs_per_insn_subsequent. */
+ COSTS_N_INSNS (5), /* loadf. */
+ COSTS_N_INSNS (5), /* loadd. */
+ COSTS_N_INSNS (5), /* load_unaligned. */
+ 0, /* store. */
+ 0, /* strd. */
+ 0, /* stm_1st. */
+ 0, /* stm_regs_per_insn_1st. */
+ 0, /* stm_regs_per_insn_subsequent. */
+ COSTS_N_INSNS (2), /* storef. */
+ COSTS_N_INSNS (2), /* stored. */
+ COSTS_N_INSNS (2), /* store_unaligned. */
+ COSTS_N_INSNS (3), /* loadv. */
+ COSTS_N_INSNS (3) /* storev. */
+ },
+ {
+ /* FP SFmode */
+ {
+ COSTS_N_INSNS (25), /* div. */
+ COSTS_N_INSNS (4), /* mult. */
+ COSTS_N_INSNS (4), /* mult_addsub. */
+ COSTS_N_INSNS (4), /* fma. */
+ COSTS_N_INSNS (4), /* addsub. */
+ COSTS_N_INSNS (2), /* fpconst. */
+ COSTS_N_INSNS (4), /* neg. */
+ COSTS_N_INSNS (4), /* compare. */
+ COSTS_N_INSNS (4), /* widen. */
+ COSTS_N_INSNS (4), /* narrow. */
+ COSTS_N_INSNS (4), /* toint. */
+ COSTS_N_INSNS (4), /* fromint. */
+ COSTS_N_INSNS (4) /* roundint. */
+ },
+ /* FP DFmode */
+ {
+ COSTS_N_INSNS (34), /* div. */
+ COSTS_N_INSNS (5), /* mult. */
+ COSTS_N_INSNS (5), /* mult_addsub. */
+ COSTS_N_INSNS (5), /* fma. */
+ COSTS_N_INSNS (5), /* addsub. */
+ COSTS_N_INSNS (2), /* fpconst. */
+ COSTS_N_INSNS (5), /* neg. */
+ COSTS_N_INSNS (5), /* compare. */
+ COSTS_N_INSNS (5), /* widen. */
+ COSTS_N_INSNS (5), /* narrow. */
+ COSTS_N_INSNS (6), /* toint. */
+ COSTS_N_INSNS (6), /* fromint. */
+ COSTS_N_INSNS (5) /* roundint. */
+ }
+ },
+ /* Vector */
+ {
+ COSTS_N_INSNS (3), /* alu. */
+ COSTS_N_INSNS (3), /* mult. */
+ COSTS_N_INSNS (2), /* movi. */
+ COSTS_N_INSNS (2), /* dup. */
+ COSTS_N_INSNS (2) /* extract. */
+ }
+};
+
#endif
diff --git a/gcc/config/aarch64/aarch64-fusion-pairs.def b/gcc/config/aarch64/aarch64-fusion-pairs.def
index c064fb9..d91f8a2 100644
--- a/gcc/config/aarch64/aarch64-fusion-pairs.def
+++ b/gcc/config/aarch64/aarch64-fusion-pairs.def
@@ -36,5 +36,6 @@ AARCH64_FUSION_PAIR ("cmp+branch", CMP_BRANCH)
AARCH64_FUSION_PAIR ("aes+aesmc", AES_AESMC)
AARCH64_FUSION_PAIR ("alu+branch", ALU_BRANCH)
AARCH64_FUSION_PAIR ("alu+cbz", ALU_CBZ)
+AARCH64_FUSION_PAIR ("addsub_2reg_const1", ADDSUB_2REG_CONST1)
#undef AARCH64_FUSION_PAIR
diff --git a/gcc/config/aarch64/aarch64-option-extensions.def b/gcc/config/aarch64/aarch64-option-extensions.def
index bdf4baf..8d1a703 100644
--- a/gcc/config/aarch64/aarch64-option-extensions.def
+++ b/gcc/config/aarch64/aarch64-option-extensions.def
@@ -149,4 +149,6 @@ AARCH64_OPT_EXTENSION("ls64", LS64, (), (), (), "")
AARCH64_OPT_EXTENSION("mops", MOPS, (), (), (), "")
+AARCH64_OPT_EXTENSION("cssc", CSSC, (), (), (), "")
+
#undef AARCH64_OPT_EXTENSION
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 2388205..fcc3a66 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -540,6 +540,7 @@ struct tune_params
const char *loop_align;
int int_reassoc_width;
int fp_reassoc_width;
+ int fma_reassoc_width;
int vec_reassoc_width;
int min_div_recip_mul_sf;
int min_div_recip_mul_df;
@@ -755,7 +756,7 @@ void aarch64_post_cfi_startproc (void);
poly_int64 aarch64_initial_elimination_offset (unsigned, unsigned);
int aarch64_get_condition_code (rtx);
bool aarch64_address_valid_for_prefetch_p (rtx, bool);
-bool aarch64_bitmask_imm (HOST_WIDE_INT val, machine_mode);
+bool aarch64_bitmask_imm (unsigned HOST_WIDE_INT val, machine_mode);
unsigned HOST_WIDE_INT aarch64_and_split_imm1 (HOST_WIDE_INT val_in);
unsigned HOST_WIDE_INT aarch64_and_split_imm2 (HOST_WIDE_INT val_in);
bool aarch64_and_bitmask_imm (unsigned HOST_WIDE_INT val_in, machine_mode mode);
@@ -792,7 +793,7 @@ bool aarch64_masks_and_shift_for_bfi_p (scalar_int_mode, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT);
bool aarch64_zero_extend_const_eq (machine_mode, rtx, machine_mode, rtx);
-bool aarch64_move_imm (HOST_WIDE_INT, machine_mode);
+bool aarch64_move_imm (unsigned HOST_WIDE_INT, machine_mode);
machine_mode aarch64_sve_int_mode (machine_mode);
opt_machine_mode aarch64_sve_pred_mode (unsigned int);
machine_mode aarch64_sve_pred_mode (machine_mode);
@@ -842,8 +843,9 @@ bool aarch64_sve_float_arith_immediate_p (rtx, bool);
bool aarch64_sve_float_mul_immediate_p (rtx);
bool aarch64_split_dimode_const_store (rtx, rtx);
bool aarch64_symbolic_address_p (rtx);
-bool aarch64_uimm12_shift (HOST_WIDE_INT);
+bool aarch64_uimm12_shift (unsigned HOST_WIDE_INT);
int aarch64_movk_shift (const wide_int_ref &, const wide_int_ref &);
+bool aarch64_is_mov_xn_imm (unsigned HOST_WIDE_INT);
bool aarch64_use_return_insn_p (void);
const char *aarch64_output_casesi (rtx *);
@@ -1073,4 +1075,6 @@ const char *aarch64_indirect_call_asm (rtx);
extern bool aarch64_harden_sls_retbr_p (void);
extern bool aarch64_harden_sls_blr_p (void);
+extern void aarch64_output_patchable_area (unsigned int, bool);
+
#endif /* GCC_AARCH64_PROTOS_H */
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 5386043..c0e6164 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -19,10 +19,10 @@
;; <http://www.gnu.org/licenses/>.
(define_expand "mov<mode>"
- [(set (match_operand:VALL_F16 0 "nonimmediate_operand")
- (match_operand:VALL_F16 1 "general_operand"))]
+ [(set (match_operand:VMOVE 0 "nonimmediate_operand")
+ (match_operand:VMOVE 1 "general_operand"))]
"TARGET_FLOAT"
- "
+{
/* Force the operand into a register if it is not an
immediate whose use can be replaced with xzr.
If the mode is 16 bytes wide, then we will be doing
@@ -46,12 +46,11 @@
aarch64_expand_vector_init (operands[0], operands[1]);
DONE;
}
- "
-)
+})
(define_expand "movmisalign<mode>"
- [(set (match_operand:VALL_F16 0 "nonimmediate_operand")
- (match_operand:VALL_F16 1 "general_operand"))]
+ [(set (match_operand:VMOVE 0 "nonimmediate_operand")
+ (match_operand:VMOVE 1 "general_operand"))]
"TARGET_FLOAT && !STRICT_ALIGNMENT"
{
/* This pattern is not permitted to fail during expansion: if both arguments
@@ -73,6 +72,16 @@
[(set_attr "type" "neon_dup<q>, neon_from_gp<q>")]
)
+(define_insn "aarch64_simd_dupv2hf"
+ [(set (match_operand:V2HF 0 "register_operand" "=w")
+ (vec_duplicate:V2HF
+ (match_operand:HF 1 "register_operand" "0")))]
+ "TARGET_SIMD"
+ "@
+ sli\\t%d0, %d0, 16"
+ [(set_attr "type" "neon_shift_imm")]
+)
+
(define_insn "aarch64_simd_dup<mode>"
[(set (match_operand:VDQF_F16 0 "register_operand" "=w,w")
(vec_duplicate:VDQF_F16
@@ -85,10 +94,10 @@
)
(define_insn "aarch64_dup_lane<mode>"
- [(set (match_operand:VALL_F16 0 "register_operand" "=w")
- (vec_duplicate:VALL_F16
+ [(set (match_operand:VMOVE 0 "register_operand" "=w")
+ (vec_duplicate:VMOVE
(vec_select:<VEL>
- (match_operand:VALL_F16 1 "register_operand" "w")
+ (match_operand:VMOVE 1 "register_operand" "w")
(parallel [(match_operand:SI 2 "immediate_operand" "i")])
)))]
"TARGET_SIMD"
@@ -150,6 +159,29 @@
(set_attr "arch" "*,*,*,*,*,*,*,simd,*")]
)
+(define_insn "*aarch64_simd_movv2hf"
+ [(set (match_operand:V2HF 0 "nonimmediate_operand"
+ "=w, m, m, w, ?r, ?w, ?r, w, w")
+ (match_operand:V2HF 1 "general_operand"
+ "m, Dz, w, w, w, r, r, Dz, Dn"))]
+ "TARGET_SIMD_F16INST
+ && (register_operand (operands[0], V2HFmode)
+ || aarch64_simd_reg_or_zero (operands[1], V2HFmode))"
+ "@
+ ldr\\t%s0, %1
+ str\\twzr, %0
+ str\\t%s1, %0
+ mov\\t%0.2s[0], %1.2s[0]
+ umov\\t%w0, %1.s[0]
+ fmov\\t%s0, %w1
+ mov\\t%w0, %w1
+ movi\\t%d0, 0
+ * return aarch64_output_simd_mov_immediate (operands[1], 32);"
+ [(set_attr "type" "neon_load1_1reg, store_8, neon_store1_1reg,\
+ neon_logic, neon_to_gp, f_mcr,\
+ mov_reg, neon_move, neon_move")]
+)
+
(define_insn "*aarch64_simd_mov<VQMOV:mode>"
[(set (match_operand:VQMOV 0 "nonimmediate_operand"
"=w, Umn, m, w, ?r, ?w, ?r, w, w")
@@ -193,7 +225,7 @@
(define_insn "aarch64_store_lane0<mode>"
[(set (match_operand:<VEL> 0 "memory_operand" "=m")
- (vec_select:<VEL> (match_operand:VALL_F16 1 "register_operand" "w")
+ (vec_select:<VEL> (match_operand:VMOVE 1 "register_operand" "w")
(parallel [(match_operand 2 "const_int_operand" "n")])))]
"TARGET_SIMD
&& ENDIAN_LANE_N (<nunits>, INTVAL (operands[2])) == 0"
@@ -1058,11 +1090,11 @@
)
(define_insn "aarch64_simd_vec_set<mode>"
- [(set (match_operand:VALL_F16 0 "register_operand" "=w,w,w")
- (vec_merge:VALL_F16
- (vec_duplicate:VALL_F16
+ [(set (match_operand:VMOVE 0 "register_operand" "=w,w,w")
+ (vec_merge:VMOVE
+ (vec_duplicate:VMOVE
(match_operand:<VEL> 1 "aarch64_simd_nonimmediate_operand" "w,?r,Utv"))
- (match_operand:VALL_F16 3 "register_operand" "0,0,0")
+ (match_operand:VMOVE 3 "register_operand" "0,0,0")
(match_operand:SI 2 "immediate_operand" "i,i,i")))]
"TARGET_SIMD"
{
@@ -1084,14 +1116,14 @@
)
(define_insn "@aarch64_simd_vec_copy_lane<mode>"
- [(set (match_operand:VALL_F16 0 "register_operand" "=w")
- (vec_merge:VALL_F16
- (vec_duplicate:VALL_F16
+ [(set (match_operand:VMOVE 0 "register_operand" "=w")
+ (vec_merge:VMOVE
+ (vec_duplicate:VMOVE
(vec_select:<VEL>
- (match_operand:VALL_F16 3 "register_operand" "w")
+ (match_operand:VMOVE 3 "register_operand" "w")
(parallel
[(match_operand:SI 4 "immediate_operand" "i")])))
- (match_operand:VALL_F16 1 "register_operand" "0")
+ (match_operand:VMOVE 1 "register_operand" "0")
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_SIMD"
{
@@ -1399,7 +1431,7 @@
)
(define_expand "vec_set<mode>"
- [(match_operand:VALL_F16 0 "register_operand")
+ [(match_operand:VMOVE 0 "register_operand")
(match_operand:<VEL> 1 "aarch64_simd_nonimmediate_operand")
(match_operand:SI 2 "immediate_operand")]
"TARGET_SIMD"
@@ -3518,7 +3550,7 @@
;; gimple_fold'd to the IFN_REDUC_(MAX|MIN) function. (This is FP smax/smin).
(define_expand "reduc_<optab>_scal_<mode>"
[(match_operand:<VEL> 0 "register_operand")
- (unspec:<VEL> [(match_operand:VHSDF 1 "register_operand")]
+ (unspec:<VEL> [(match_operand:VHSDF_P 1 "register_operand")]
FMAXMINV)]
"TARGET_SIMD"
{
@@ -3533,7 +3565,7 @@
(define_expand "reduc_<fmaxmin>_scal_<mode>"
[(match_operand:<VEL> 0 "register_operand")
- (unspec:<VEL> [(match_operand:VHSDF 1 "register_operand")]
+ (unspec:<VEL> [(match_operand:VHSDF_P 1 "register_operand")]
FMAXMINNMV)]
"TARGET_SIMD"
{
@@ -3577,8 +3609,8 @@
)
(define_insn "aarch64_reduc_<optab>_internal<mode>"
- [(set (match_operand:VHSDF 0 "register_operand" "=w")
- (unspec:VHSDF [(match_operand:VHSDF 1 "register_operand" "w")]
+ [(set (match_operand:VHSDF_P 0 "register_operand" "=w")
+ (unspec:VHSDF_P [(match_operand:VHSDF_P 1 "register_operand" "w")]
FMAXMINV))]
"TARGET_SIMD"
"<maxmin_uns_op><vp>\\t%<Vetype>0, %1.<Vtype>"
@@ -4223,7 +4255,7 @@
(define_insn_and_split "aarch64_get_lane<mode>"
[(set (match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "=?r, w, Utv")
(vec_select:<VEL>
- (match_operand:VALL_F16 1 "register_operand" "w, w, w")
+ (match_operand:VMOVE 1 "register_operand" "w, w, w")
(parallel [(match_operand:SI 2 "immediate_operand" "i, i, i")])))]
"TARGET_SIMD"
{
@@ -4867,6 +4899,63 @@
}
)
+;; div optimizations using narrowings
+;; we can do the division e.g. shorts by 255 faster by calculating it as
+;; (x + ((x + 257) >> 8)) >> 8 assuming the operation is done in
+;; double the precision of x.
+;;
+;; If we imagine a short as being composed of two blocks of bytes then
+;; adding 257 or 0b0000_0001_0000_0001 to the number is equivalent to
+;; adding 1 to each sub component:
+;;
+;; short value of 16-bits
+;; ┌──────────────┬────────────────┐
+;; │ │ │
+;; └──────────────┴────────────────┘
+;; 8-bit part1 ▲ 8-bit part2 ▲
+;; │ │
+;; │ │
+;; +1 +1
+;;
+;; after the first addition, we have to shift right by 8, and narrow the
+;; results back to a byte. Remember that the addition must be done in
+;; double the precision of the input. Since 8 is half the size of a short
+;; we can use a narrowing halfing instruction in AArch64, addhn which also
+;; does the addition in a wider precision and narrows back to a byte. The
+;; shift itself is implicit in the operation as it writes back only the top
+;; half of the result. i.e. bits 2*esize-1:esize.
+;;
+;; Since we have narrowed the result of the first part back to a byte, for
+;; the second addition we can use a widening addition, uaddw.
+;;
+;; For the final shift, since it's unsigned arithmetic we emit an ushr by 8.
+;;
+;; The shift is later optimized by combine to a uzp2 with movi #0.
+(define_expand "@aarch64_bitmask_udiv<mode>3"
+ [(match_operand:VQN 0 "register_operand")
+ (match_operand:VQN 1 "register_operand")
+ (match_operand:VQN 2 "immediate_operand")]
+ "TARGET_SIMD"
+{
+ unsigned HOST_WIDE_INT size
+ = (1ULL << GET_MODE_UNIT_BITSIZE (<VNARROWQ>mode)) - 1;
+ rtx elt = unwrap_const_vec_duplicate (operands[2]);
+ if (!CONST_INT_P (elt) || UINTVAL (elt) != size)
+ FAIL;
+
+ rtx addend = gen_reg_rtx (<MODE>mode);
+ rtx val = aarch64_simd_gen_const_vector_dup (<VNARROWQ2>mode, 1);
+ emit_move_insn (addend, lowpart_subreg (<MODE>mode, val, <VNARROWQ2>mode));
+ rtx tmp1 = gen_reg_rtx (<VNARROWQ>mode);
+ rtx tmp2 = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_aarch64_addhn<mode> (tmp1, operands[1], addend));
+ unsigned bitsize = GET_MODE_UNIT_BITSIZE (<VNARROWQ>mode);
+ rtx shift_vector = aarch64_simd_gen_const_vector_dup (<MODE>mode, bitsize);
+ emit_insn (gen_aarch64_uaddw<Vnarrowq> (tmp2, operands[1], tmp1));
+ emit_insn (gen_aarch64_simd_lshr<mode> (operands[0], tmp2, shift_vector));
+ DONE;
+})
+
;; pmul.
(define_insn "aarch64_pmul<mode>"
@@ -7971,7 +8060,7 @@
;; Standard pattern name vec_init<mode><Vel>.
(define_expand "vec_init<mode><Vel>"
- [(match_operand:VALL_F16 0 "register_operand")
+ [(match_operand:VMOVE 0 "register_operand")
(match_operand 1 "" "")]
"TARGET_SIMD"
{
@@ -8050,7 +8139,7 @@
(define_expand "vec_extract<mode><Vel>"
[(match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand")
- (match_operand:VALL_F16 1 "register_operand")
+ (match_operand:VMOVE 1 "register_operand")
(match_operand:SI 2 "immediate_operand")]
"TARGET_SIMD"
{
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
index 6347407..d52ec08 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
@@ -45,6 +45,7 @@
#include "aarch64-sve-builtins-base.h"
#include "aarch64-sve-builtins-functions.h"
#include "ssa.h"
+#include "gimple-fold.h"
using namespace aarch64_sve;
@@ -1209,7 +1210,8 @@ public:
vectype is the corresponding ADVSIMD type. */
if (!BYTES_BIG_ENDIAN
- && integer_all_onesp (arg0))
+ && integer_all_onesp (arg0)
+ && !flag_non_call_exceptions)
{
tree lhs = gimple_call_lhs (f.call);
tree lhs_type = TREE_TYPE (lhs);
@@ -1232,7 +1234,9 @@ public:
tree mem_ref_op = fold_build2 (MEM_REF, access_type, arg1, zero);
gimple *mem_ref_stmt
= gimple_build_assign (mem_ref_lhs, mem_ref_op);
- gsi_insert_before (f.gsi, mem_ref_stmt, GSI_SAME_STMT);
+
+ gimple_seq stmts = NULL;
+ gimple_seq_add_stmt_without_update (&stmts, mem_ref_stmt);
int source_nelts = TYPE_VECTOR_SUBPARTS (access_type).to_constant ();
vec_perm_builder sel (lhs_len, source_nelts, 1);
@@ -1245,8 +1249,11 @@ public:
indices));
tree mask_type = build_vector_type (ssizetype, lhs_len);
tree mask = vec_perm_indices_to_tree (mask_type, indices);
- return gimple_build_assign (lhs, VEC_PERM_EXPR,
- mem_ref_lhs, mem_ref_lhs, mask);
+ gimple *g2 = gimple_build_assign (lhs, VEC_PERM_EXPR,
+ mem_ref_lhs, mem_ref_lhs, mask);
+ gimple_seq_add_stmt_without_update (&stmts, g2);
+ gsi_replace_with_seq_vops (f.gsi, stmts);
+ return g2;
}
return NULL;
diff --git a/gcc/config/aarch64/aarch64-sve2.md b/gcc/config/aarch64/aarch64-sve2.md
index f138f4b..dadd046 100644
--- a/gcc/config/aarch64/aarch64-sve2.md
+++ b/gcc/config/aarch64/aarch64-sve2.md
@@ -71,6 +71,7 @@
;; ---- [INT] Reciprocal approximation
;; ---- [INT<-FP] Base-2 logarithm
;; ---- [INT] Polynomial multiplication
+;; ---- [INT] Misc optab implementations
;;
;; == Permutation
;; ---- [INT,FP] General permutes
@@ -81,7 +82,7 @@
;; ---- Histogram processing
;; ---- String matching
;;
-;; == Crypotographic extensions
+;; == Cryptographic extensions
;; ---- Optional AES extensions
;; ---- Optional SHA-3 extensions
;; ---- Optional SM4 extensions
@@ -2312,6 +2313,46 @@
"<sve_int_op>\t%0.<Vewtype>, %1.<Vetype>, %2.<Vetype>"
)
+;; -------------------------------------------------------------------------
+;; ---- [INT] Misc optab implementations
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - aarch64_bitmask_udiv
+;; -------------------------------------------------------------------------
+
+;; div optimizations using narrowings
+;; we can do the division e.g. shorts by 255 faster by calculating it as
+;; (x + ((x + 257) >> 8)) >> 8 assuming the operation is done in
+;; double the precision of x.
+;;
+;; See aarch64-simd.md for bigger explanation.
+(define_expand "@aarch64_bitmask_udiv<mode>3"
+ [(match_operand:SVE_FULL_HSDI 0 "register_operand")
+ (match_operand:SVE_FULL_HSDI 1 "register_operand")
+ (match_operand:SVE_FULL_HSDI 2 "immediate_operand")]
+ "TARGET_SVE2"
+{
+ unsigned HOST_WIDE_INT size
+ = (1ULL << GET_MODE_UNIT_BITSIZE (<VNARROW>mode)) - 1;
+ rtx elt = unwrap_const_vec_duplicate (operands[2]);
+ if (!CONST_INT_P (elt) || UINTVAL (elt) != size)
+ FAIL;
+
+ rtx addend = gen_reg_rtx (<MODE>mode);
+ rtx tmp1 = gen_reg_rtx (<VNARROW>mode);
+ rtx tmp2 = gen_reg_rtx (<VNARROW>mode);
+ rtx val = aarch64_simd_gen_const_vector_dup (<VNARROW>mode, 1);
+ emit_move_insn (addend, lowpart_subreg (<MODE>mode, val, <VNARROW>mode));
+ emit_insn (gen_aarch64_sve (UNSPEC_ADDHNB, <MODE>mode, tmp1, operands[1],
+ addend));
+ emit_insn (gen_aarch64_sve (UNSPEC_ADDHNB, <MODE>mode, tmp2, operands[1],
+ lowpart_subreg (<MODE>mode, tmp1,
+ <VNARROW>mode)));
+ emit_move_insn (operands[0],
+ lowpart_subreg (<MODE>mode, tmp2, <VNARROW>mode));
+ DONE;
+})
+
;; =========================================================================
;; == Permutation
;; =========================================================================
@@ -2528,7 +2569,7 @@
)
;; =========================================================================
-;; == Crypotographic extensions
+;; == Cryptographic extensions
;; =========================================================================
;; -------------------------------------------------------------------------
diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md
index 84e9bbf..4fd35fa 100644
--- a/gcc/config/aarch64/aarch64-tune.md
+++ b/gcc/config/aarch64/aarch64-tune.md
@@ -1,5 +1,5 @@
;; -*- buffer-read-only: t -*-
;; Generated automatically by gentune.sh from aarch64-cores.def
(define_attr "tune"
- "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,ares,neoversen1,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,thunderx3t110,zeus,neoversev1,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexa510,cortexa710,cortexx2,neoversen2,demeter,neoversev2"
+ "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,ares,neoversen1,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,thunderx3t110,zeus,neoversev1,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexa510,cortexa710,cortexa715,cortexx2,cortexx3,neoversen2,demeter,neoversev2"
(const (symbol_ref "((enum attr_tune) aarch64_tune)")))
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index d1f979eb..73515c1 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -1346,6 +1346,7 @@ static const struct tune_params generic_tunings =
"8", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
1, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1382,6 +1383,7 @@ static const struct tune_params cortexa35_tunings =
"8", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
1, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1415,6 +1417,7 @@ static const struct tune_params cortexa53_tunings =
"8", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
1, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1448,6 +1451,7 @@ static const struct tune_params cortexa57_tunings =
"8", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
1, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1481,6 +1485,7 @@ static const struct tune_params cortexa72_tunings =
"8", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
1, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1514,6 +1519,7 @@ static const struct tune_params cortexa73_tunings =
"8", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
1, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1548,6 +1554,7 @@ static const struct tune_params exynosm1_tunings =
"4", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
1, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1580,6 +1587,7 @@ static const struct tune_params thunderxt88_tunings =
"8", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
1, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1612,6 +1620,7 @@ static const struct tune_params thunderx_tunings =
"8", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
1, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1646,6 +1655,7 @@ static const struct tune_params tsv110_tunings =
"8", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
1, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1678,6 +1688,7 @@ static const struct tune_params xgene1_tunings =
"16", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
1, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1710,6 +1721,7 @@ static const struct tune_params emag_tunings =
"16", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
1, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1743,6 +1755,7 @@ static const struct tune_params qdf24xx_tunings =
"16", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
1, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1778,6 +1791,7 @@ static const struct tune_params saphira_tunings =
"16", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
1, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1811,6 +1825,7 @@ static const struct tune_params thunderx2t99_tunings =
"16", /* loop_align. */
3, /* int_reassoc_width. */
2, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
2, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1844,6 +1859,7 @@ static const struct tune_params thunderx3t110_tunings =
"16", /* loop_align. */
3, /* int_reassoc_width. */
2, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
2, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1876,6 +1892,7 @@ static const struct tune_params neoversen1_tunings =
"32:16", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
2, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -1912,6 +1929,45 @@ static const struct tune_params ampere1_tunings =
"32:16", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
+ 2, /* vec_reassoc_width. */
+ 2, /* min_div_recip_mul_sf. */
+ 2, /* min_div_recip_mul_df. */
+ 0, /* max_case_values. */
+ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */
+ (AARCH64_EXTRA_TUNE_NONE), /* tune_flags. */
+ &ampere1_prefetch_tune
+};
+
+static const struct tune_params ampere1a_tunings =
+{
+ &ampere1a_extra_costs,
+ &generic_addrcost_table,
+ &generic_regmove_cost,
+ &ampere1_vector_cost,
+ &generic_branch_cost,
+ &generic_approx_modes,
+ SVE_NOT_IMPLEMENTED, /* sve_width */
+ { 4, /* load_int. */
+ 4, /* store_int. */
+ 4, /* load_fp. */
+ 4, /* store_fp. */
+ 4, /* load_pred. */
+ 4 /* store_pred. */
+ }, /* memmov_cost. */
+ 4, /* issue_rate */
+ (AARCH64_FUSE_ADRP_ADD | AARCH64_FUSE_AES_AESMC |
+ AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_MOVK_MOVK |
+ AARCH64_FUSE_ALU_BRANCH /* adds, ands, bics, ccmp, ccmn */ |
+ AARCH64_FUSE_CMP_BRANCH | AARCH64_FUSE_ALU_CBZ |
+ AARCH64_FUSE_ADDSUB_2REG_CONST1),
+ /* fusible_ops */
+ "32", /* function_align. */
+ "4", /* jump_align. */
+ "32:16", /* loop_align. */
+ 2, /* int_reassoc_width. */
+ 4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
2, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -2089,6 +2145,7 @@ static const struct tune_params neoversev1_tunings =
"32:16", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 4, /* fma_reassoc_width. */
2, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -2226,6 +2283,7 @@ static const struct tune_params neoverse512tvb_tunings =
"32:16", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 4, /* fma_reassoc_width. */
2, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -2414,6 +2472,7 @@ static const struct tune_params neoversen2_tunings =
"32:16", /* loop_align. */
2, /* int_reassoc_width. */
4, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
2, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -2603,6 +2662,7 @@ static const struct tune_params neoversev2_tunings =
"32:16", /* loop_align. */
3, /* int_reassoc_width. */
6, /* fp_reassoc_width. */
+ 4, /* fma_reassoc_width. */
3, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -2638,6 +2698,7 @@ static const struct tune_params a64fx_tunings =
"32", /* loop_align. */
4, /* int_reassoc_width. */
2, /* fp_reassoc_width. */
+ 1, /* fma_reassoc_width. */
2, /* vec_reassoc_width. */
2, /* min_div_recip_mul_sf. */
2, /* min_div_recip_mul_df. */
@@ -3350,9 +3411,15 @@ aarch64_reassociation_width (unsigned opc, machine_mode mode)
return aarch64_tune_params.vec_reassoc_width;
if (INTEGRAL_MODE_P (mode))
return aarch64_tune_params.int_reassoc_width;
- /* Avoid reassociating floating point addition so we emit more FMAs. */
- if (FLOAT_MODE_P (mode) && opc != PLUS_EXPR)
- return aarch64_tune_params.fp_reassoc_width;
+ /* Reassociation reduces the number of FMAs which may result in worse
+ performance. Use a per-CPU setting for FMA reassociation which allows
+ narrow CPUs with few FP pipes to switch it off (value of 1), and wider
+ CPUs with many FP pipes to enable reassociation.
+ Since the reassociation pass doesn't understand FMA at all, assume
+ that any FP addition might turn into FMA. */
+ if (FLOAT_MODE_P (mode))
+ return opc == PLUS_EXPR ? aarch64_tune_params.fma_reassoc_width
+ : aarch64_tune_params.fp_reassoc_width;
return 1;
}
@@ -3567,6 +3634,7 @@ aarch64_classify_vector_mode (machine_mode mode)
case E_V8BFmode:
case E_V4SFmode:
case E_V2DFmode:
+ case E_V2HFmode:
return TARGET_FLOAT ? VEC_ADVSIMD : 0;
default:
@@ -5558,12 +5626,10 @@ aarch64_bitmask_imm (unsigned HOST_WIDE_INT val)
/* Return true if VAL is a valid bitmask immediate for MODE. */
bool
-aarch64_bitmask_imm (HOST_WIDE_INT val_in, machine_mode mode)
+aarch64_bitmask_imm (unsigned HOST_WIDE_INT val, machine_mode mode)
{
if (mode == DImode)
- return aarch64_bitmask_imm (val_in);
-
- unsigned HOST_WIDE_INT val = val_in;
+ return aarch64_bitmask_imm (val);
if (mode == SImode)
return aarch64_bitmask_imm ((val & 0xffffffff) | (val << 32));
@@ -5602,51 +5668,55 @@ aarch64_check_bitmask (unsigned HOST_WIDE_INT val,
}
-/* Return true if val is an immediate that can be loaded into a
- register by a MOVZ instruction. */
-static bool
-aarch64_movw_imm (HOST_WIDE_INT val, scalar_int_mode mode)
+/* Return true if VAL is a valid MOVZ immediate. */
+static inline bool
+aarch64_is_movz (unsigned HOST_WIDE_INT val)
{
- if (GET_MODE_SIZE (mode) > 4)
- {
- if ((val & (((HOST_WIDE_INT) 0xffff) << 32)) == val
- || (val & (((HOST_WIDE_INT) 0xffff) << 48)) == val)
- return 1;
- }
- else
- {
- /* Ignore sign extension. */
- val &= (HOST_WIDE_INT) 0xffffffff;
- }
- return ((val & (((HOST_WIDE_INT) 0xffff) << 0)) == val
- || (val & (((HOST_WIDE_INT) 0xffff) << 16)) == val);
+ return (val >> (ctz_hwi (val) & 48)) < 65536;
}
-/* Return true if VAL is an immediate that can be loaded into a
- register in a single instruction. */
+/* Return true if immediate VAL can be created by a 64-bit MOVI/MOVN/MOVZ. */
bool
-aarch64_move_imm (HOST_WIDE_INT val, machine_mode mode)
+aarch64_is_mov_xn_imm (unsigned HOST_WIDE_INT val)
{
- scalar_int_mode int_mode;
- if (!is_a <scalar_int_mode> (mode, &int_mode))
- return false;
+ return aarch64_is_movz (val) || aarch64_is_movz (~val)
+ || aarch64_bitmask_imm (val);
+}
- if (aarch64_movw_imm (val, int_mode) || aarch64_movw_imm (~val, int_mode))
- return 1;
- return aarch64_bitmask_imm (val, int_mode);
+
+/* Return true if VAL is an immediate that can be created by a single
+ MOV instruction. */
+bool
+aarch64_move_imm (unsigned HOST_WIDE_INT val, machine_mode mode)
+{
+ gcc_assert (mode == SImode || mode == DImode);
+
+ if (val < 65536)
+ return true;
+
+ unsigned HOST_WIDE_INT mask =
+ (val >> 32) == 0 || mode == SImode ? 0xffffffff : HOST_WIDE_INT_M1U;
+
+ if (aarch64_is_movz (val & mask) || aarch64_is_movz (~val & mask))
+ return true;
+
+ val = (val & mask) | ((val << 32) & ~mask);
+ return aarch64_bitmask_imm (val);
}
static int
aarch64_internal_mov_immediate (rtx dest, rtx imm, bool generate,
- scalar_int_mode mode)
+ machine_mode mode)
{
int i;
unsigned HOST_WIDE_INT val, val2, mask;
int one_match, zero_match;
int num_insns;
+ gcc_assert (mode == SImode || mode == DImode);
+
val = INTVAL (imm);
if (aarch64_move_imm (val, mode))
@@ -5656,31 +5726,6 @@ aarch64_internal_mov_immediate (rtx dest, rtx imm, bool generate,
return 1;
}
- /* Check to see if the low 32 bits are either 0xffffXXXX or 0xXXXXffff
- (with XXXX non-zero). In that case check to see if the move can be done in
- a smaller mode. */
- val2 = val & 0xffffffff;
- if (mode == DImode
- && aarch64_move_imm (val2, SImode)
- && (((val >> 32) & 0xffff) == 0 || (val >> 48) == 0))
- {
- if (generate)
- emit_insn (gen_rtx_SET (dest, GEN_INT (val2)));
-
- /* Check if we have to emit a second instruction by checking to see
- if any of the upper 32 bits of the original DI mode value is set. */
- if (val == val2)
- return 1;
-
- i = (val >> 48) ? 48 : 32;
-
- if (generate)
- emit_insn (gen_insv_immdi (dest, GEN_INT (i),
- GEN_INT ((val >> i) & 0xffff)));
-
- return 2;
- }
-
if ((val >> 32) == 0 || mode == SImode)
{
if (generate)
@@ -5704,24 +5749,31 @@ aarch64_internal_mov_immediate (rtx dest, rtx imm, bool generate,
one_match = ((~val & mask) == 0) + ((~val & (mask << 16)) == 0) +
((~val & (mask << 32)) == 0) + ((~val & (mask << 48)) == 0);
+ /* Try a bitmask immediate and a movk to generate the immediate
+ in 2 instructions. */
+
if (zero_match < 2 && one_match < 2)
{
- /* Try emitting a bitmask immediate with a movk replacing 16 bits.
- For a 64-bit bitmask try whether changing 16 bits to all ones or
- zeroes creates a valid bitmask. To check any repeated bitmask,
- try using 16 bits from the other 32-bit half of val. */
-
for (i = 0; i < 64; i += 16)
- if (aarch64_check_bitmask (val, val2, mask << i))
- {
- if (generate)
- {
- emit_insn (gen_rtx_SET (dest, GEN_INT (val2)));
- emit_insn (gen_insv_immdi (dest, GEN_INT (i),
- GEN_INT ((val >> i) & 0xffff)));
- }
- return 2;
- }
+ {
+ if (aarch64_check_bitmask (val, val2, mask << i))
+ break;
+
+ val2 = val & ~(mask << i);
+ if ((val2 >> 32) == 0 && aarch64_move_imm (val2, DImode))
+ break;
+ }
+
+ if (i != 64)
+ {
+ if (generate)
+ {
+ emit_insn (gen_rtx_SET (dest, GEN_INT (val2)));
+ emit_insn (gen_insv_immdi (dest, GEN_INT (i),
+ GEN_INT ((val >> i) & 0xffff)));
+ }
+ return 2;
+ }
}
/* Try a bitmask plus 2 movk to generate the immediate in 3 instructions. */
@@ -5790,26 +5842,24 @@ aarch64_mov128_immediate (rtx imm)
/* Return true if val can be encoded as a 12-bit unsigned immediate with
a left shift of 0 or 12 bits. */
bool
-aarch64_uimm12_shift (HOST_WIDE_INT val)
+aarch64_uimm12_shift (unsigned HOST_WIDE_INT val)
{
- return ((val & (((HOST_WIDE_INT) 0xfff) << 0)) == val
- || (val & (((HOST_WIDE_INT) 0xfff) << 12)) == val
- );
+ return val < 4096 || (val & 0xfff000) == val;
}
/* Returns the nearest value to VAL that will fit as a 12-bit unsigned immediate
that can be created with a left shift of 0 or 12. */
static HOST_WIDE_INT
-aarch64_clamp_to_uimm12_shift (HOST_WIDE_INT val)
+aarch64_clamp_to_uimm12_shift (unsigned HOST_WIDE_INT val)
{
/* Check to see if the value fits in 24 bits, as that is the maximum we can
handle correctly. */
- gcc_assert ((val & 0xffffff) == val);
+ gcc_assert (val < 0x1000000);
- if (((val & 0xfff) << 0) == val)
+ if (val < 4096)
return val;
- return val & (0xfff << 12);
+ return val & 0xfff000;
}
@@ -6464,7 +6514,8 @@ aarch64_expand_sve_const_vector (rtx target, rtx src)
/* If the integer can be moved into a general register by a
single instruction, do that and duplicate the result. */
if (CONST_INT_P (elt_value)
- && aarch64_move_imm (INTVAL (elt_value), elt_mode))
+ && aarch64_move_imm (INTVAL (elt_value),
+ encoded_bits <= 32 ? SImode : DImode))
{
elt_value = force_reg (elt_mode, elt_value);
return expand_vector_broadcast (mode, elt_value);
@@ -6957,8 +7008,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
return;
}
- aarch64_internal_mov_immediate (dest, imm, true,
- as_a <scalar_int_mode> (mode));
+ aarch64_internal_mov_immediate (dest, imm, true, mode);
}
/* Return the MEM rtx that provides the canary value that should be used
@@ -11130,9 +11180,7 @@ aarch64_float_const_rtx_p (rtx x)
&& SCALAR_FLOAT_MODE_P (mode)
&& aarch64_reinterpret_float_as_int (x, &ival))
{
- scalar_int_mode imode = (mode == HFmode
- ? SImode
- : int_mode_for_mode (mode).require ());
+ machine_mode imode = known_eq (GET_MODE_SIZE (mode), 8) ? DImode : SImode;
int num_instr = aarch64_internal_mov_immediate
(NULL_RTX, gen_int_mode (ival, imode), false, imode);
return num_instr < 3;
@@ -13790,10 +13838,10 @@ aarch64_rtx_costs (rtx x, machine_mode mode, int outer ATTRIBUTE_UNUSED,
proportionally expensive to the number of instructions
required to build that constant. This is true whether we
are compiling for SPEED or otherwise. */
- if (!is_a <scalar_int_mode> (mode, &int_mode))
- int_mode = word_mode;
+ machine_mode imode = known_le (GET_MODE_SIZE (mode), 4)
+ ? SImode : DImode;
*cost = COSTS_N_INSNS (aarch64_internal_mov_immediate
- (NULL_RTX, x, false, int_mode));
+ (NULL_RTX, x, false, imode));
}
return true;
@@ -13809,9 +13857,8 @@ aarch64_rtx_costs (rtx x, machine_mode mode, int outer ATTRIBUTE_UNUSED,
bool succeed = aarch64_reinterpret_float_as_int (x, &ival);
gcc_assert (succeed);
- scalar_int_mode imode = (mode == HFmode
- ? SImode
- : int_mode_for_mode (mode).require ());
+ machine_mode imode = known_eq (GET_MODE_SIZE (mode), 8)
+ ? DImode : SImode;
int ncost = aarch64_internal_mov_immediate
(NULL_RTX, gen_int_mode (ival, imode), false, imode);
*cost += COSTS_N_INSNS (ncost);
@@ -14190,6 +14237,16 @@ cost_plus:
return true;
}
+ if (aarch64_pluslong_immediate (op1, mode))
+ {
+ /* 24-bit add in 2 instructions or 12-bit shifted add. */
+ if ((INTVAL (op1) & 0xfff) != 0)
+ *cost += COSTS_N_INSNS (1);
+
+ *cost += rtx_cost (op0, mode, PLUS, 0, speed);
+ return true;
+ }
+
*cost += rtx_cost (op1, mode, PLUS, 1, speed);
/* Look for ADD (extended register). */
@@ -21991,6 +22048,38 @@ aarch64_expand_vector_init (rtx target, rtx vals)
return;
}
+ /* Check for interleaving case.
+ For eg if initializer is (int16x8_t) {x, y, x, y, x, y, x, y}.
+ Generate following code:
+ dup v0.h, x
+ dup v1.h, y
+ zip1 v0.h, v0.h, v1.h
+ for "large enough" initializer. */
+
+ if (n_elts >= 8)
+ {
+ int i;
+ for (i = 2; i < n_elts; i++)
+ if (!rtx_equal_p (XVECEXP (vals, 0, i), XVECEXP (vals, 0, i % 2)))
+ break;
+
+ if (i == n_elts)
+ {
+ machine_mode mode = GET_MODE (target);
+ rtx dest[2];
+
+ for (int i = 0; i < 2; i++)
+ {
+ rtx x = expand_vector_broadcast (mode, XVECEXP (vals, 0, i));
+ dest[i] = force_reg (mode, x);
+ }
+
+ rtvec v = gen_rtvec (2, dest[0], dest[1]);
+ emit_set_insn (target, gen_rtx_UNSPEC (mode, v, UNSPEC_ZIP1));
+ return;
+ }
+ }
+
enum insn_code icode = optab_handler (vec_set_optab, mode);
gcc_assert (icode != CODE_FOR_nothing);
@@ -22594,30 +22683,56 @@ aarch64_declare_function_name (FILE *stream, const char* name,
cfun->machine->label_is_assembled = true;
}
-/* Implement PRINT_PATCHABLE_FUNCTION_ENTRY. Check if the patch area is after
- the function label and emit a BTI if necessary. */
+/* Implement PRINT_PATCHABLE_FUNCTION_ENTRY. */
void
aarch64_print_patchable_function_entry (FILE *file,
unsigned HOST_WIDE_INT patch_area_size,
bool record_p)
{
- if (cfun->machine->label_is_assembled
- && aarch64_bti_enabled ()
- && !cgraph_node::get (cfun->decl)->only_called_directly_p ())
+ if (!cfun->machine->label_is_assembled)
+ {
+ /* Emit the patching area before the entry label, if any. */
+ default_print_patchable_function_entry (file, patch_area_size,
+ record_p);
+ return;
+ }
+
+ rtx pa = gen_patchable_area (GEN_INT (patch_area_size),
+ GEN_INT (record_p));
+ basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
+
+ if (!aarch64_bti_enabled ()
+ || cgraph_node::get (cfun->decl)->only_called_directly_p ())
+ {
+ /* Emit the patchable_area at the beginning of the function. */
+ rtx_insn *insn = emit_insn_before (pa, BB_HEAD (bb));
+ INSN_ADDRESSES_NEW (insn, -1);
+ return;
+ }
+
+ rtx_insn *insn = next_real_nondebug_insn (get_insns ());
+ if (!insn
+ || !INSN_P (insn)
+ || GET_CODE (PATTERN (insn)) != UNSPEC_VOLATILE
+ || XINT (PATTERN (insn), 1) != UNSPECV_BTI_C)
{
- /* Remove the BTI that follows the patch area and insert a new BTI
- before the patch area right after the function label. */
- rtx_insn *insn = next_real_nondebug_insn (get_insns ());
- if (insn
- && INSN_P (insn)
- && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
- && XINT (PATTERN (insn), 1) == UNSPECV_BTI_C)
- delete_insn (insn);
- asm_fprintf (file, "\thint\t34 // bti c\n");
+ /* Emit a BTI_C. */
+ insn = emit_insn_before (gen_bti_c (), BB_HEAD (bb));
}
- default_print_patchable_function_entry (file, patch_area_size, record_p);
+ /* Emit the patchable_area after BTI_C. */
+ insn = emit_insn_after (pa, insn);
+ INSN_ADDRESSES_NEW (insn, -1);
+}
+
+/* Output patchable area. */
+
+void
+aarch64_output_patchable_area (unsigned int patch_area_size, bool record_p)
+{
+ default_print_patchable_function_entry (asm_out_file, patch_area_size,
+ record_p);
}
/* Implement ASM_OUTPUT_DEF_FROM_DECLS. Output .variant_pcs for aliases. */
@@ -24269,6 +24384,45 @@ aarch64_vectorize_vec_perm_const (machine_mode vmode, machine_mode op_mode,
return ret;
}
+/* Implement TARGET_VECTORIZE_CAN_SPECIAL_DIV_BY_CONST. */
+
+bool
+aarch64_vectorize_can_special_div_by_constant (enum tree_code code,
+ tree vectype, wide_int cst,
+ rtx *output, rtx in0, rtx in1)
+{
+ if (code != TRUNC_DIV_EXPR
+ || !TYPE_UNSIGNED (vectype))
+ return false;
+
+ unsigned int flags = aarch64_classify_vector_mode (TYPE_MODE (vectype));
+ if ((flags & VEC_ANY_SVE) && !TARGET_SVE2)
+ return false;
+
+ int pow = wi::exact_log2 (cst + 1);
+ auto insn_code = maybe_code_for_aarch64_bitmask_udiv3 (TYPE_MODE (vectype));
+ /* SVE actually has a div operator, we may have gotten here through
+ that route. */
+ if (pow != (int) (element_precision (vectype) / 2)
+ || insn_code == CODE_FOR_nothing)
+ return false;
+
+ /* We can use the optimized pattern. */
+ if (in0 == NULL_RTX && in1 == NULL_RTX)
+ return true;
+
+ if (!VECTOR_TYPE_P (vectype))
+ return false;
+
+ gcc_assert (output);
+
+ if (!*output)
+ *output = gen_reg_rtx (TYPE_MODE (vectype));
+
+ emit_insn (gen_aarch64_bitmask_udiv3 (TYPE_MODE (vectype), *output, in0, in1));
+ return true;
+}
+
/* Generate a byte permute mask for a register of mode MODE,
which has NUNITS units. */
@@ -25539,6 +25693,33 @@ aarch_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr)
}
}
+ /* Fuse A+B+1 and A-B-1 */
+ if (simple_sets_p
+ && aarch64_fusion_enabled_p (AARCH64_FUSE_ADDSUB_2REG_CONST1))
+ {
+ /* We're trying to match:
+ prev == (set (r0) (plus (r0) (r1)))
+ curr == (set (r0) (plus (r0) (const_int 1)))
+ or:
+ prev == (set (r0) (minus (r0) (r1)))
+ curr == (set (r0) (plus (r0) (const_int -1))) */
+
+ rtx prev_src = SET_SRC (prev_set);
+ rtx curr_src = SET_SRC (curr_set);
+
+ int polarity = 1;
+ if (GET_CODE (prev_src) == MINUS)
+ polarity = -1;
+
+ if (GET_CODE (curr_src) == PLUS
+ && (GET_CODE (prev_src) == PLUS || GET_CODE (prev_src) == MINUS)
+ && CONST_INT_P (XEXP (curr_src, 1))
+ && INTVAL (XEXP (curr_src, 1)) == polarity
+ && REG_P (XEXP (curr_src, 0))
+ && REGNO (SET_DEST (prev_set)) == REGNO (XEXP (curr_src, 0)))
+ return true;
+ }
+
return false;
}
@@ -26560,9 +26741,10 @@ aarch64_can_change_mode_class (machine_mode from,
bool from_pred_p = (from_flags & VEC_SVE_PRED);
bool to_pred_p = (to_flags & VEC_SVE_PRED);
- bool from_full_advsimd_struct_p = (from_flags == (VEC_ADVSIMD | VEC_STRUCT));
bool to_partial_advsimd_struct_p = (to_flags == (VEC_ADVSIMD | VEC_STRUCT
| VEC_PARTIAL));
+ bool from_partial_advsimd_struct_p = (from_flags == (VEC_ADVSIMD | VEC_STRUCT
+ | VEC_PARTIAL));
/* Don't allow changes between predicate modes and other modes.
Only predicate registers can hold predicate modes and only
@@ -26584,9 +26766,10 @@ aarch64_can_change_mode_class (machine_mode from,
|| GET_MODE_UNIT_SIZE (from) != GET_MODE_UNIT_SIZE (to)))
return false;
- /* Don't allow changes between partial and full Advanced SIMD structure
- modes. */
- if (from_full_advsimd_struct_p && to_partial_advsimd_struct_p)
+ /* Don't allow changes between partial and other registers only if
+ one is a normal SIMD register, allow only if not larger than 64-bit. */
+ if ((to_partial_advsimd_struct_p ^ from_partial_advsimd_struct_p)
+ && (known_gt (GET_MODE_SIZE (to), 8) || known_gt (GET_MODE_SIZE (to), 8)))
return false;
if (maybe_ne (BITS_PER_SVE_VECTOR, 128u))
@@ -26734,7 +26917,8 @@ currently_supported_simd_type (tree t, tree b)
static int
aarch64_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
struct cgraph_simd_clone *clonei,
- tree base_type, int num)
+ tree base_type, int num,
+ bool explicit_p)
{
tree t, ret_type;
unsigned int elt_bits, count;
@@ -26752,8 +26936,9 @@ aarch64_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
|| const_simdlen > 1024
|| (const_simdlen & (const_simdlen - 1)) != 0))
{
- warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
- "unsupported simdlen %wd", const_simdlen);
+ if (explicit_p)
+ warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+ "unsupported simdlen %wd", const_simdlen);
return 0;
}
@@ -26761,7 +26946,9 @@ aarch64_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
if (TREE_CODE (ret_type) != VOID_TYPE
&& !currently_supported_simd_type (ret_type, base_type))
{
- if (TYPE_SIZE (ret_type) != TYPE_SIZE (base_type))
+ if (!explicit_p)
+ ;
+ else if (TYPE_SIZE (ret_type) != TYPE_SIZE (base_type))
warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
"GCC does not currently support mixed size types "
"for %<simd%> functions");
@@ -26788,7 +26975,9 @@ aarch64_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
if (clonei->args[i].arg_type != SIMD_CLONE_ARG_TYPE_UNIFORM
&& !currently_supported_simd_type (arg_type, base_type))
{
- if (TYPE_SIZE (arg_type) != TYPE_SIZE (base_type))
+ if (!explicit_p)
+ ;
+ else if (TYPE_SIZE (arg_type) != TYPE_SIZE (base_type))
warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
"GCC does not currently support mixed size types "
"for %<simd%> functions");
@@ -26818,9 +27007,11 @@ aarch64_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
if (clonei->simdlen.is_constant (&const_simdlen)
&& maybe_ne (vec_bits, 64U) && maybe_ne (vec_bits, 128U))
{
- warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
- "GCC does not currently support simdlen %wd for type %qT",
- const_simdlen, base_type);
+ if (explicit_p)
+ warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+ "GCC does not currently support simdlen %wd for "
+ "type %qT",
+ const_simdlen, base_type);
return 0;
}
}
@@ -27732,6 +27923,10 @@ aarch64_libgcc_floating_mode_supported_p
#undef TARGET_VECTOR_ALIGNMENT
#define TARGET_VECTOR_ALIGNMENT aarch64_simd_vector_alignment
+#undef TARGET_VECTORIZE_CAN_SPECIAL_DIV_BY_CONST
+#define TARGET_VECTORIZE_CAN_SPECIAL_DIV_BY_CONST \
+ aarch64_vectorize_can_special_div_by_constant
+
#undef TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT
#define TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT \
aarch64_vectorize_preferred_vector_alignment
@@ -27906,6 +28101,9 @@ aarch64_libgcc_floating_mode_supported_p
#undef TARGET_HAVE_SHADOW_CALL_STACK
#define TARGET_HAVE_SHADOW_CALL_STACK true
+#undef TARGET_CONST_ANCHOR
+#define TARGET_CONST_ANCHOR 0x1000000
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-aarch64.h"
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index e60f9bc..db6ec5c 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -221,6 +221,8 @@ enum class aarch64_feature : unsigned char {
#define AARCH64_ISA_V9_3A (aarch64_isa_flags & AARCH64_FL_V9_3A)
#define AARCH64_ISA_MOPS (aarch64_isa_flags & AARCH64_FL_MOPS)
#define AARCH64_ISA_LS64 (aarch64_isa_flags & AARCH64_FL_LS64)
+#define AARCH64_ISA_CSSC (aarch64_isa_flags & AARCH64_FL_CSSC)
+#define AARCH64_ISA_RCPC (aarch64_isa_flags & AARCH64_FL_RCPC)
/* Crypto is an optional extension to AdvSIMD. */
#define TARGET_CRYPTO (AARCH64_ISA_CRYPTO)
@@ -310,12 +312,20 @@ enum class aarch64_feature : unsigned char {
/* PAUTH instructions are enabled through +pauth. */
#define TARGET_PAUTH (AARCH64_ISA_PAUTH)
+/* BTI instructions exist from Armv8.5-a onwards. Their automatic use is
+ enabled through -mbranch-protection by using NOP-space instructions,
+ but this TARGET_ is used for defining BTI-related ACLE things. */
+#define TARGET_BTI (AARCH64_ISA_V8_5A)
+
/* MOPS instructions are enabled through +mops. */
#define TARGET_MOPS (AARCH64_ISA_MOPS)
/* LS64 instructions are enabled through +ls64. */
#define TARGET_LS64 (AARCH64_ISA_LS64)
+/* CSSC instructions are enabled through +cssc. */
+#define TARGET_CSSC (AARCH64_ISA_CSSC)
+
/* Make sure this is always defined so we don't have to check for ifdefs
but rather use normal ifs. */
#ifndef TARGET_FIX_ERR_A53_835769_DEFAULT
@@ -328,6 +338,13 @@ enum class aarch64_feature : unsigned char {
/* SB instruction is enabled through +sb. */
#define TARGET_SB (AARCH64_ISA_SB)
+/* RCPC loads from Armv8.3-a. */
+#define TARGET_RCPC (AARCH64_ISA_RCPC)
+
+/* The RCPC2 extensions from Armv8.4-a that allow immediate offsets to LDAPR
+ and sign-extending versions.*/
+#define TARGET_RCPC2 (AARCH64_ISA_RCPC8_4)
+
/* Apply the workaround for Cortex-A53 erratum 835769. */
#define TARGET_FIX_ERR_A53_835769 \
((aarch64_fix_a53_err835769 == 2) \
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index f2e3d90..d749c98 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -303,6 +303,7 @@
UNSPEC_TAG_SPACE ; Translate address to MTE tag address space.
UNSPEC_LD1RO
UNSPEC_SALT_ADDR
+ UNSPECV_PATCHABLE_AREA
])
(define_c_enum "unspecv" [
@@ -946,12 +947,29 @@
(const_int 1)))]
)
-(define_insn "*tb<optab><mode>1"
+(define_expand "tbranch_<code><mode>3"
[(set (pc) (if_then_else
- (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
- (const_int 1)
- (match_operand 1
- "aarch64_simd_shift_imm_<mode>" "n"))
+ (EQL (match_operand:ALLI 0 "register_operand")
+ (match_operand 1 "aarch64_simd_shift_imm_<mode>"))
+ (label_ref (match_operand 2 ""))
+ (pc)))]
+ ""
+{
+ rtx bitvalue = gen_reg_rtx (<ZEROM>mode);
+ rtx reg = gen_lowpart (<ZEROM>mode, operands[0]);
+ rtx val = GEN_INT (1UL << UINTVAL (operands[1]));
+ emit_insn (gen_and<zerom>3 (bitvalue, reg, val));
+ operands[1] = const0_rtx;
+ operands[0] = aarch64_gen_compare_reg (<CODE>, bitvalue,
+ operands[1]);
+})
+
+(define_insn "*tb<optab><ALLI:mode><GPI:mode>1"
+ [(set (pc) (if_then_else
+ (EQL (zero_extract:GPI (match_operand:ALLI 0 "register_operand" "r")
+ (const_int 1)
+ (match_operand 1
+ "aarch64_simd_shift_imm_<ALLI:mode>" "n"))
(const_int 0))
(label_ref (match_operand 2 "" ""))
(pc)))
@@ -962,15 +980,15 @@
{
if (get_attr_far_branch (insn) == 1)
return aarch64_gen_far_branch (operands, 2, "Ltb",
- "<inv_tb>\\t%<w>0, %1, ");
+ "<inv_tb>\\t%<ALLI:w>0, %1, ");
else
{
operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1]));
- return "tst\t%<w>0, %1\;<bcond>\t%l2";
+ return "tst\t%<ALLI:w>0, %1\;<bcond>\t%l2";
}
}
else
- return "<tbz>\t%<w>0, %1, %l2";
+ return "<tbz>\t%<ALLI:w>0, %1, %l2";
}
[(set_attr "type" "branch")
(set (attr "length")
@@ -1309,16 +1327,15 @@
)
(define_insn_and_split "*movdi_aarch64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,r, r,w, m,m, r, r, r, w,r,w, w")
- (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,M,n,Usv,m,m,rZ,w,Usw,Usa,Ush,rZ,w,w,Dd"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r, r,w, m,m, r, r, r, w,r,w, w")
+ (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,O,n,Usv,m,m,rZ,w,Usw,Usa,Ush,rZ,w,w,Dd"))]
"(register_operand (operands[0], DImode)
|| aarch64_reg_or_zero (operands[1], DImode))"
"@
mov\\t%x0, %x1
mov\\t%0, %x1
mov\\t%x0, %1
- mov\\t%x0, %1
- mov\\t%w0, %1
+ * return aarch64_is_mov_xn_imm (INTVAL (operands[1])) ? \"mov\\t%x0, %1\" : \"mov\\t%w0, %1\";
#
* return aarch64_output_sve_cnt_immediate (\"cnt\", \"%x0\", operands[1]);
ldr\\t%x0, %1
@@ -1340,11 +1357,11 @@
DONE;
}"
;; The "mov_imm" type for CNTD is just a placeholder.
- [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,mov_imm,mov_imm,
+ [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,mov_imm,
load_8,load_8,store_8,store_8,load_8,adr,adr,f_mcr,f_mrc,
fmov,neon_move")
- (set_attr "arch" "*,*,*,*,*,*,sve,*,fp,*,fp,*,*,*,fp,fp,fp,simd")
- (set_attr "length" "4,4,4,4,4,*, 4,4, 4,4, 4,8,4,4, 4, 4, 4, 4")]
+ (set_attr "arch" "*,*,*,*,*,sve,*,fp,*,fp,*,*,*,fp,fp,fp,simd")
+ (set_attr "length" "4,4,4,4,*, 4,4, 4,4, 4,8,4,4, 4, 4, 4, 4")]
)
(define_insn "insv_imm<mode>"
@@ -1508,7 +1525,7 @@
(define_insn "*mov<mode>_aarch64"
[(set (match_operand:DFD 0 "nonimmediate_operand" "=w, w ,?r,w,w ,w ,w,m,r,m ,r,r")
- (match_operand:DFD 1 "general_operand" "Y , ?rY, w,w,Ufc,Uvi,m,w,m,rY,r,N"))]
+ (match_operand:DFD 1 "general_operand" "Y , ?rY, w,w,Ufc,Uvi,m,w,m,rY,r,O"))]
"TARGET_FLOAT && (register_operand (operands[0], <MODE>mode)
|| aarch64_reg_or_fp_zero (operands[1], <MODE>mode))"
"@
@@ -1523,7 +1540,7 @@
ldr\\t%x0, %1
str\\t%x1, %0
mov\\t%x0, %x1
- mov\\t%x0, %1"
+ * return aarch64_is_mov_xn_imm (INTVAL (operands[1])) ? \"mov\\t%x0, %1\" : \"mov\\t%w0, %1\";"
[(set_attr "type" "neon_move,f_mcr,f_mrc,fmov,fconstd,neon_move,\
f_loadd,f_stored,load_8,store_8,mov_reg,\
fconstd")
@@ -1592,6 +1609,7 @@
[(set (match_operand 2) (const_int 0))
(clobber (match_dup 3))
(clobber (match_dup 4))
+ (clobber (reg:CC CC_REGNUM))
(set (match_operand 0)
(unspec:BLK [(match_operand 1) (match_dup 2)] UNSPEC_CPYMEM))])]
"TARGET_MOPS"
@@ -1605,6 +1623,7 @@
[(set (match_operand:DI 2 "register_operand" "+&r") (const_int 0))
(clobber (match_operand:DI 0 "register_operand" "+&r"))
(clobber (match_operand:DI 1 "register_operand" "+&r"))
+ (clobber (reg:CC CC_REGNUM))
(set (mem:BLK (match_dup 0))
(unspec:BLK [(mem:BLK (match_dup 1)) (match_dup 2)] UNSPEC_CPYMEM))]
"TARGET_MOPS"
@@ -1635,6 +1654,7 @@
(set (match_operand:DI 2 "register_operand" "+&r") (const_int 0))
(clobber (match_operand:DI 0 "register_operand" "+&r"))
(clobber (match_operand:DI 1 "register_operand" "+&r"))
+ (clobber (reg:CC CC_REGNUM))
(set (mem:BLK (match_dup 0))
(unspec:BLK [(mem:BLK (match_dup 1)) (match_dup 2)] UNSPEC_MOVMEM))])]
"TARGET_MOPS"
@@ -1680,6 +1700,7 @@
[(parallel
[(set (match_operand 2) (const_int 0))
(clobber (match_dup 3))
+ (clobber (reg:CC CC_REGNUM))
(set (match_operand 0)
(unspec:BLK [(match_operand 1)
(match_dup 2)] UNSPEC_SETMEM))])]
@@ -1692,6 +1713,7 @@
(define_insn "*aarch64_setmemdi"
[(set (match_operand:DI 2 "register_operand" "+&r") (const_int 0))
(clobber (match_operand:DI 0 "register_operand" "+&r"))
+ (clobber (reg:CC CC_REGNUM))
(set (mem:BLK (match_dup 0))
(unspec:BLK [(match_operand:QI 1 "aarch64_reg_or_zero" "rZ")
(match_dup 2)] UNSPEC_SETMEM))]
@@ -3577,15 +3599,26 @@
[(set_attr "type" "alu_ext")]
)
+(define_insn "*aarch64_abs<mode>2_cssc_insn"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (abs:GPI (match_operand:GPI 1 "register_operand" "r")))]
+ "TARGET_CSSC"
+ "abs\\t%<w>0, %<w>1"
+ [(set_attr "type" "alu_sreg")]
+)
+
(define_expand "abs<mode>2"
- [(match_operand:GPI 0 "register_operand")
- (match_operand:GPI 1 "register_operand")]
+ [(set (match_operand:GPI 0 "register_operand")
+ (abs:GPI (match_operand:GPI 1 "register_operand")))]
""
{
- rtx ccreg = aarch64_gen_compare_reg (LT, operands[1], const0_rtx);
- rtx x = gen_rtx_LT (VOIDmode, ccreg, const0_rtx);
- emit_insn (gen_csneg3<mode>_insn (operands[0], x, operands[1], operands[1]));
- DONE;
+ if (!TARGET_CSSC)
+ {
+ rtx ccreg = aarch64_gen_compare_reg (LT, operands[1], const0_rtx);
+ rtx x = gen_rtx_LT (VOIDmode, ccreg, const0_rtx);
+ emit_insn (gen_csneg3<mode>_insn (operands[0], x, operands[1], operands[1]));
+ DONE;
+ }
}
)
@@ -4379,6 +4412,17 @@
[(set_attr "type" "csel")]
)
+(define_insn "aarch64_umax<mode>3_insn"
+ [(set (match_operand:GPI 0 "register_operand" "=r,r")
+ (umax:GPI (match_operand:GPI 1 "register_operand" "r,r")
+ (match_operand:GPI 2 "aarch64_uminmax_operand" "r,Uum")))]
+ "TARGET_CSSC"
+ "@
+ umax\\t%<w>0, %<w>1, %<w>2
+ umax\\t%<w>0, %<w>1, %2"
+ [(set_attr "type" "alu_sreg,alu_imm")]
+)
+
;; If X can be loaded by a single CNT[BHWD] instruction,
;;
;; A = UMAX (B, X)
@@ -4409,11 +4453,23 @@
[(set (match_operand:GPI 0 "register_operand")
(umax:GPI (match_operand:GPI 1 "")
(match_operand:GPI 2 "")))]
- "TARGET_SVE"
+ "TARGET_SVE || TARGET_CSSC"
{
if (aarch64_sve_cnt_immediate (operands[1], <MODE>mode))
std::swap (operands[1], operands[2]);
- else if (!aarch64_sve_cnt_immediate (operands[2], <MODE>mode))
+ else if (!aarch64_sve_cnt_immediate (operands[2], <MODE>mode)
+ && TARGET_CSSC)
+ {
+ if (aarch64_uminmax_immediate (operands[1], <MODE>mode))
+ std::swap (operands[1], operands[2]);
+ operands[1] = force_reg (<MODE>mode, operands[1]);
+ if (!aarch64_uminmax_operand (operands[2], <MODE>mode))
+ operands[2] = force_reg (<MODE>mode, operands[2]);
+ emit_insn (gen_aarch64_umax<mode>3_insn (operands[0], operands[1],
+ operands[2]));
+ DONE;
+ }
+ else
FAIL;
rtx temp = gen_reg_rtx (<MODE>mode);
operands[1] = force_reg (<MODE>mode, operands[1]);
@@ -4963,35 +5019,47 @@
}
)
-;; Pop count be done via the "CNT" instruction in AdvSIMD.
-;;
+(define_insn "*aarch64_popcount<mode>2_cssc_insn"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (popcount:GPI (match_operand:GPI 1 "register_operand" "r")))]
+ "TARGET_CSSC"
+ "cnt\\t%<w>0, %<w>1"
+ [(set_attr "type" "clz")]
+)
+
+;; The CSSC instructions can do popcount in the GP registers directly through
+;; CNT. If it is not available then we can use CNT on the Advanced SIMD side
+;; through:
;; MOV v.1d, x0
;; CNT v1.8b, v.8b
;; ADDV b2, v1.8b
;; MOV w0, v2.b[0]
(define_expand "popcount<mode>2"
- [(match_operand:GPI 0 "register_operand")
- (match_operand:GPI 1 "register_operand")]
- "TARGET_SIMD"
+ [(set (match_operand:GPI 0 "register_operand")
+ (popcount:GPI (match_operand:GPI 1 "register_operand")))]
+ "TARGET_CSSC || TARGET_SIMD"
{
- rtx v = gen_reg_rtx (V8QImode);
- rtx v1 = gen_reg_rtx (V8QImode);
- rtx in = operands[1];
- rtx out = operands[0];
- if(<MODE>mode == SImode)
+ if (!TARGET_CSSC)
{
- rtx tmp;
- tmp = gen_reg_rtx (DImode);
- /* If we have SImode, zero extend to DImode, pop count does
- not change if we have extra zeros. */
- emit_insn (gen_zero_extendsidi2 (tmp, in));
- in = tmp;
+ rtx v = gen_reg_rtx (V8QImode);
+ rtx v1 = gen_reg_rtx (V8QImode);
+ rtx in = operands[1];
+ rtx out = operands[0];
+ if(<MODE>mode == SImode)
+ {
+ rtx tmp;
+ tmp = gen_reg_rtx (DImode);
+ /* If we have SImode, zero extend to DImode, pop count does
+ not change if we have extra zeros. */
+ emit_insn (gen_zero_extendsidi2 (tmp, in));
+ in = tmp;
+ }
+ emit_move_insn (v, gen_lowpart (V8QImode, in));
+ emit_insn (gen_popcountv8qi2 (v1, v));
+ emit_insn (gen_aarch64_zero_extend<mode>_reduc_plus_v8qi (out, v1));
+ DONE;
}
- emit_move_insn (v, gen_lowpart (V8QImode, in));
- emit_insn (gen_popcountv8qi2 (v1, v));
- emit_insn (gen_aarch64_zero_extend<mode>_reduc_plus_v8qi (out, v1));
- DONE;
})
(define_insn "clrsb<mode>2"
@@ -5013,14 +5081,14 @@
;; Split after reload into RBIT + CLZ. Since RBIT is represented as an UNSPEC
;; it is unlikely to fold with any other operation, so keep this as a CTZ
;; expression and split after reload to enable scheduling them apart if
-;; needed.
+;; needed. For TARGET_CSSC we have a single CTZ instruction that can do this.
(define_insn_and_split "ctz<mode>2"
[(set (match_operand:GPI 0 "register_operand" "=r")
(ctz:GPI (match_operand:GPI 1 "register_operand" "r")))]
""
- "#"
- "reload_completed"
+ { return TARGET_CSSC ? "ctz\\t%<w>0, %<w>1" : "#"; }
+ "reload_completed && !TARGET_CSSC"
[(const_int 0)]
"
emit_insn (gen_aarch64_rbit (<MODE>mode, operands[0], operands[1]));
@@ -6659,6 +6727,17 @@
[(set_attr "type" "ffarith<stype>")]
)
+(define_insn "<optab><mode>3"
+ [(set (match_operand:GPI 0 "register_operand" "=r,r")
+ (MAXMIN_NOUMAX:GPI (match_operand:GPI 1 "register_operand" "r,r")
+ (match_operand:GPI 2 "aarch64_<su>minmax_operand" "r,U<su>m")))]
+ "TARGET_CSSC"
+ "@
+ <optab>\\t%<w>0, %<w>1, %<w>2
+ <optab>\\t%<w>0, %<w>1, %2"
+ [(set_attr "type" "alu_sreg,alu_imm")]
+)
+
;; Given that smax/smin do not specify the result when either input is NaN,
;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
;; for smin.
@@ -7764,6 +7843,19 @@
[(set_attr "type" "ls64")]
)
+(define_insn "patchable_area"
+ [(unspec_volatile [(match_operand 0 "const_int_operand")
+ (match_operand 1 "const_int_operand")]
+ UNSPECV_PATCHABLE_AREA)]
+ ""
+{
+ aarch64_output_patchable_area (INTVAL (operands[0]),
+ INTVAL (operands[1]) != 0);
+ return "";
+}
+ [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))]
+)
+
;; AdvSIMD Stuff
(include "aarch64-simd.md")
diff --git a/gcc/config/aarch64/atomics.md b/gcc/config/aarch64/atomics.md
index bc95f6d..5407cf7 100644
--- a/gcc/config/aarch64/atomics.md
+++ b/gcc/config/aarch64/atomics.md
@@ -657,7 +657,38 @@
}
)
-(define_insn "atomic_load<mode>"
+(define_expand "atomic_load<mode>"
+ [(match_operand:ALLI 0 "register_operand" "=r")
+ (match_operand:ALLI 1 "aarch64_sync_memory_operand" "Q")
+ (match_operand:SI 2 "const_int_operand")]
+ ""
+ {
+ /* If TARGET_RCPC and this is an ACQUIRE load, then expand to a pattern
+ using UNSPECV_LDAP. */
+ enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
+ if (TARGET_RCPC
+ && (is_mm_acquire (model)
+ || is_mm_acq_rel (model)))
+ emit_insn (gen_aarch64_atomic_load<mode>_rcpc (operands[0], operands[1],
+ operands[2]));
+ else
+ emit_insn (gen_aarch64_atomic_load<mode> (operands[0], operands[1],
+ operands[2]));
+ DONE;
+ }
+)
+
+(define_insn "aarch64_atomic_load<mode>_rcpc"
+ [(set (match_operand:ALLI 0 "register_operand" "=r")
+ (unspec_volatile:ALLI
+ [(match_operand:ALLI 1 "aarch64_sync_memory_operand" "Q")
+ (match_operand:SI 2 "const_int_operand")] ;; model
+ UNSPECV_LDAP))]
+ "TARGET_RCPC"
+ "ldapr<atomic_sfx>\t%<w>0, %1"
+)
+
+(define_insn "aarch64_atomic_load<mode>"
[(set (match_operand:ALLI 0 "register_operand" "=r")
(unspec_volatile:ALLI
[(match_operand:ALLI 1 "aarch64_sync_memory_operand" "Q")
@@ -673,6 +704,28 @@
}
)
+(define_insn "*aarch64_atomic_load<ALLX:mode>_rcpc_zext"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (zero_extend:GPI
+ (unspec_volatile:ALLX
+ [(match_operand:ALLX 1 "aarch64_sync_memory_operand" "Q")
+ (match_operand:SI 2 "const_int_operand")] ;; model
+ UNSPECV_LDAP)))]
+ "TARGET_RCPC && (<GPI:sizen> > <ALLX:sizen>)"
+ "ldapr<ALLX:atomic_sfx>\t%w0, %1"
+)
+
+(define_insn "*aarch64_atomic_load<ALLX:mode>_rcpc_sext"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (sign_extend:GPI
+ (unspec_volatile:ALLX
+ [(match_operand:ALLX 1 "aarch64_sync_memory_operand" "Q")
+ (match_operand:SI 2 "const_int_operand")] ;; model
+ UNSPECV_LDAP)))]
+ "TARGET_RCPC2 && (<GPI:sizen> > <ALLX:sizen>)"
+ "ldapurs<ALLX:size>\t%<GPI:w>0, %1"
+)
+
(define_insn "atomic_store<mode>"
[(set (match_operand:ALLI 0 "aarch64_rcpc_memory_operand" "=Q,Ust")
(unspec_volatile:ALLI
diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md
index ee7587c..ad2e5e0 100644
--- a/gcc/config/aarch64/constraints.md
+++ b/gcc/config/aarch64/constraints.md
@@ -107,6 +107,11 @@
(define_constraint "N"
"A constant that can be used with a 64-bit MOV immediate operation."
(and (match_code "const_int")
+ (match_test "aarch64_is_mov_xn_imm (ival)")))
+
+(define_constraint "O"
+ "A constant that can be used with a 32 or 64-bit MOV immediate operation."
+ (and (match_code "const_int")
(match_test "aarch64_move_imm (ival, DImode)")))
(define_constraint "Uti"
@@ -152,6 +157,11 @@
(match_test "aarch64_symbolic_address_p (op)")
(match_test "aarch64_mov_operand_p (op, GET_MODE (op))")))
+(define_constraint "Usm"
+ "A constant that can be used with the S[MIN/MAX] CSSC instructions."
+ (and (match_code "const_int")
+ (match_test "aarch64_sminmax_immediate (op, VOIDmode)")))
+
;; const is needed here to support UNSPEC_SALT_ADDR.
(define_constraint "Usw"
"@internal
@@ -389,6 +399,11 @@
(and (match_code "const_double,const_vector")
(match_test "aarch64_float_const_representable_p (op)")))
+(define_constraint "Uum"
+ "A constant that can be used with the U[MIN/MAX] CSSC instructions."
+ (and (match_code "const_int")
+ (match_test "aarch64_uminmax_immediate (op, VOIDmode)")))
+
(define_constraint "Uvi"
"A floating point constant which can be used with a\
MOVI immediate operation."
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index a8ad4e5..a521dbd 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -160,6 +160,10 @@
(define_mode_iterator VHSDF [(V4HF "TARGET_SIMD_F16INST")
(V8HF "TARGET_SIMD_F16INST")
V2SF V4SF V2DF])
+;; Advanced SIMD Float modes suitable for reduction or pairwise operations
+(define_mode_iterator VHSDF_P [(V4HF "TARGET_SIMD_F16INST")
+ (V8HF "TARGET_SIMD_F16INST")
+ V2SF V4SF V2DF (V2HF "TARGET_SIMD_F16INST")])
;; Advanced SIMD Float modes, and DF.
(define_mode_iterator VDQF_DF [V2SF V4SF V2DF DF])
@@ -188,15 +192,22 @@
(define_mode_iterator VALLF [V2SF V4SF V2DF SF DF])
;; Advanced SIMD Float modes with 2 elements.
-(define_mode_iterator V2F [V2SF V2DF])
+(define_mode_iterator V2F [V2SF V2DF V2HF])
;; All Advanced SIMD modes on which we support any arithmetic operations.
(define_mode_iterator VALL [V8QI V16QI V4HI V8HI V2SI V4SI V2DI V2SF V4SF V2DF])
-;; All Advanced SIMD modes suitable for moving, loading, and storing.
+;; The set of all modes for which vld1 intrinsics are provided.
(define_mode_iterator VALL_F16 [V8QI V16QI V4HI V8HI V2SI V4SI V2DI
V4HF V8HF V4BF V8BF V2SF V4SF V2DF])
+;; All Advanced SIMD modes suitable for moving, loading, and storing
+;; including V2HF
+(define_mode_iterator VMOVE [V8QI V16QI V4HI V8HI V2SI V4SI V2DI
+ V4HF V8HF V4BF V8BF V2SF V4SF V2DF
+ (V2HF "TARGET_SIMD_F16INST")])
+
+
;; The VALL_F16 modes except the 128-bit 2-element ones.
(define_mode_iterator VALL_F16_NO_V2Q [V8QI V16QI V4HI V8HI V2SI V4SI
V4HF V8HF V2SF V4SF])
@@ -988,6 +999,7 @@
UNSPECV_LX ; Represent a load-exclusive.
UNSPECV_SX ; Represent a store-exclusive.
UNSPECV_LDA ; Represent an atomic load or load-acquire.
+ UNSPECV_LDAP ; Represent an atomic acquire load with RCpc semantics.
UNSPECV_STL ; Represent an atomic store or store-release.
UNSPECV_ATOMIC_CMPSW ; Represent an atomic compare swap.
UNSPECV_ATOMIC_EXCHG ; Represent an atomic exchange.
@@ -1078,7 +1090,7 @@
(V2SF "2") (V4SF "4")
(V1DF "1") (V2DF "2")
(DI "1") (DF "1")
- (V8DI "8")])
+ (V8DI "8") (V2HF "2")])
;; Map a mode to the number of bits in it, if the size of the mode
;; is constant.
@@ -1095,6 +1107,8 @@
;; Give the number of bits in the mode
(define_mode_attr sizen [(QI "8") (HI "16") (SI "32") (DI "64")])
+(define_mode_attr ZEROM [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
+(define_mode_attr zerom [(QI "si") (HI "si") (SI "si") (DI "di")])
;; Give the ordinal of the MSB in the mode
(define_mode_attr sizem1 [(QI "#7") (HI "#15") (SI "#31") (DI "#63")
@@ -1195,7 +1209,7 @@
(define_mode_attr Vetype [(V8QI "b") (V16QI "b")
(V4HI "h") (V8HI "h")
(V2SI "s") (V4SI "s")
- (V2DI "d")
+ (V2DI "d") (V2HF "h")
(V4HF "h") (V8HF "h")
(V2SF "s") (V4SF "s")
(V2DF "d")
@@ -1287,7 +1301,7 @@
;; more accurately.
(define_mode_attr stype [(V8QI "b") (V16QI "b") (V4HI "s") (V8HI "s")
(V2SI "s") (V4SI "s") (V2DI "d") (V4HF "s")
- (V8HF "s") (V2SF "s") (V4SF "s") (V2DF "d")
+ (V8HF "s") (V2SF "s") (V4SF "s") (V2DF "d") (V2HF "s")
(HF "s") (SF "s") (DF "d") (QI "b") (HI "s")
(SI "s") (DI "d")])
@@ -1362,8 +1376,8 @@
(V4HF "HF") (V8HF "HF")
(V2SF "SF") (V4SF "SF")
(DF "DF") (V2DF "DF")
- (SI "SI") (HI "HI")
- (QI "QI")
+ (SI "SI") (V2HF "HF")
+ (QI "QI") (HI "HI")
(V4BF "BF") (V8BF "BF")
(VNx16QI "QI") (VNx8QI "QI") (VNx4QI "QI") (VNx2QI "QI")
(VNx8HI "HI") (VNx4HI "HI") (VNx2HI "HI")
@@ -1383,7 +1397,7 @@
(V2SF "sf") (V4SF "sf")
(V2DF "df") (DF "df")
(SI "si") (HI "hi")
- (QI "qi")
+ (QI "qi") (V2HF "hf")
(V4BF "bf") (V8BF "bf")
(VNx16QI "qi") (VNx8QI "qi") (VNx4QI "qi") (VNx2QI "qi")
(VNx8HI "hi") (VNx4HI "hi") (VNx2HI "hi")
@@ -1868,7 +1882,7 @@
(V4HF "") (V8HF "_q")
(V4BF "") (V8BF "_q")
(V2SF "") (V4SF "_q")
- (V2DF "_q")
+ (V2HF "") (V2DF "_q")
(QI "") (HI "") (SI "") (DI "") (HF "") (SF "") (DF "")
(V2x8QI "") (V2x16QI "_q")
(V2x4HI "") (V2x8HI "_q")
@@ -1907,6 +1921,7 @@
(V2SI "p") (V4SI "v")
(V2DI "p") (V2DF "p")
(V2SF "p") (V4SF "v")
+ (V2HF "p")
(V4HF "v") (V8HF "v")])
(define_mode_attr vsi2qi [(V2SI "v8qi") (V4SI "v16qi")
@@ -2186,6 +2201,9 @@
;; Code iterator for variants of vector max and min.
(define_code_iterator MAXMIN [smax smin umax umin])
+;; Code iterator for min/max ops but without UMAX.
+(define_code_iterator MAXMIN_NOUMAX [smax smin umin])
+
(define_code_iterator FMAXMIN [smax smin])
;; Signed and unsigned max operations.
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index c308015..ff7f73d 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -146,7 +146,23 @@
(define_predicate "aarch64_pluslong_immediate"
(and (match_code "const_int")
- (match_test "(INTVAL (op) < 0xffffff && INTVAL (op) > -0xffffff)")))
+ (match_test "IN_RANGE (INTVAL (op), -0xffffff, 0xffffff)")))
+
+(define_predicate "aarch64_sminmax_immediate"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), -128, 127)")))
+
+(define_predicate "aarch64_sminmax_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "aarch64_sminmax_immediate")))
+
+(define_predicate "aarch64_uminmax_immediate"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 255)")))
+
+(define_predicate "aarch64_uminmax_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "aarch64_uminmax_immediate")))
(define_predicate "aarch64_pluslong_strict_immedate"
(and (match_operand 0 "aarch64_pluslong_immediate")
diff --git a/gcc/config/arm/arm-cpus.in b/gcc/config/arm/arm-cpus.in
index 5a63bc5..5ed4db3 100644
--- a/gcc/config/arm/arm-cpus.in
+++ b/gcc/config/arm/arm-cpus.in
@@ -1542,6 +1542,17 @@ begin cpu cortex-x1
part d44
end cpu cortex-x1
+begin cpu cortex-x1c
+ cname cortexx1c
+ tune for cortex-a57
+ tune flags LDSCHED
+ architecture armv8.2-a+fp16+dotprod
+ option crypto add FP_ARMv8 CRYPTO
+ costs cortex_a57
+ vendor 41
+ part d4c
+end cpu cortex-x1c
+
begin cpu neoverse-n1
cname neoversen1
alias !ares
diff --git a/gcc/config/arm/arm-tables.opt b/gcc/config/arm/arm-tables.opt
index e6461ab..a10a09e 100644
--- a/gcc/config/arm/arm-tables.opt
+++ b/gcc/config/arm/arm-tables.opt
@@ -256,6 +256,9 @@ EnumValue
Enum(processor_type) String(cortex-x1) Value( TARGET_CPU_cortexx1)
EnumValue
+Enum(processor_type) String(cortex-x1c) Value( TARGET_CPU_cortexx1c)
+
+EnumValue
Enum(processor_type) String(neoverse-n1) Value( TARGET_CPU_neoversen1)
EnumValue
diff --git a/gcc/config/arm/arm-tune.md b/gcc/config/arm/arm-tune.md
index abc290e..8af8c93 100644
--- a/gcc/config/arm/arm-tune.md
+++ b/gcc/config/arm/arm-tune.md
@@ -46,7 +46,7 @@
cortexa73cortexa53,cortexa55,cortexa75,
cortexa76,cortexa76ae,cortexa77,
cortexa78,cortexa78ae,cortexa78c,
- cortexa710,cortexx1,neoversen1,
+ cortexa710,cortexx1,cortexx1c,neoversen1,
cortexa75cortexa55,cortexa76cortexa55,neoversev1,
neoversen2,cortexm23,cortexm33,
cortexm35p,cortexm55,starmc1,
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 2eb4d51..b587561 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -375,7 +375,7 @@ static const struct attribute_spec arm_attribute_table[] =
/* ARMv8-M Security Extensions support. */
{ "cmse_nonsecure_entry", 0, 0, true, false, false, false,
arm_handle_cmse_nonsecure_entry, NULL },
- { "cmse_nonsecure_call", 0, 0, true, false, false, true,
+ { "cmse_nonsecure_call", 0, 0, false, false, false, true,
arm_handle_cmse_nonsecure_call, NULL },
{ "Advanced SIMD type", 1, 1, false, true, false, true, NULL, NULL },
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
@@ -7605,8 +7605,8 @@ arm_handle_cmse_nonsecure_call (tree *node, tree name,
int /* flags */,
bool *no_add_attrs)
{
- tree decl = NULL_TREE, fntype = NULL_TREE;
- tree type;
+ tree decl = NULL_TREE;
+ tree fntype, type;
if (!use_cmse)
{
@@ -7616,16 +7616,20 @@ arm_handle_cmse_nonsecure_call (tree *node, tree name,
return NULL_TREE;
}
- if (TREE_CODE (*node) == VAR_DECL || TREE_CODE (*node) == TYPE_DECL)
+ if (DECL_P (*node))
{
- decl = *node;
- fntype = TREE_TYPE (decl);
+ fntype = TREE_TYPE (*node);
+
+ if (TREE_CODE (*node) == VAR_DECL || TREE_CODE (*node) == TYPE_DECL)
+ decl = *node;
}
+ else
+ fntype = *node;
- while (fntype != NULL_TREE && TREE_CODE (fntype) == POINTER_TYPE)
+ while (fntype && TREE_CODE (fntype) == POINTER_TYPE)
fntype = TREE_TYPE (fntype);
- if (!decl || TREE_CODE (fntype) != FUNCTION_TYPE)
+ if ((DECL_P (*node) && !decl) || TREE_CODE (fntype) != FUNCTION_TYPE)
{
warning (OPT_Wattributes, "%qE attribute only applies to base type of a "
"function pointer", name);
@@ -7640,10 +7644,17 @@ arm_handle_cmse_nonsecure_call (tree *node, tree name,
/* Prevent trees being shared among function types with and without
cmse_nonsecure_call attribute. */
- type = TREE_TYPE (decl);
+ if (decl)
+ {
+ type = build_distinct_type_copy (TREE_TYPE (decl));
+ TREE_TYPE (decl) = type;
+ }
+ else
+ {
+ type = build_distinct_type_copy (*node);
+ *node = type;
+ }
- type = build_distinct_type_copy (type);
- TREE_TYPE (decl) = type;
fntype = type;
while (TREE_CODE (fntype) != FUNCTION_TYPE)
diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h
index 073e371..09167ec 100644
--- a/gcc/config/arm/arm_mve.h
+++ b/gcc/config/arm/arm_mve.h
@@ -9675,42 +9675,42 @@ __arm_vabdq_m_u16 (uint16x8_t __inactive, uint16x8_t __a, uint16x8_t __b, mve_pr
__extension__ extern __inline int8x16_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m_n_s8 (int8x16_t __inactive, int8x16_t __a, int __b, mve_pred16_t __p)
+__arm_vaddq_m_n_s8 (int8x16_t __inactive, int8x16_t __a, int8_t __b, mve_pred16_t __p)
{
return __builtin_mve_vaddq_m_n_sv16qi (__inactive, __a, __b, __p);
}
__extension__ extern __inline int32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m_n_s32 (int32x4_t __inactive, int32x4_t __a, int __b, mve_pred16_t __p)
+__arm_vaddq_m_n_s32 (int32x4_t __inactive, int32x4_t __a, int32_t __b, mve_pred16_t __p)
{
return __builtin_mve_vaddq_m_n_sv4si (__inactive, __a, __b, __p);
}
__extension__ extern __inline int16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m_n_s16 (int16x8_t __inactive, int16x8_t __a, int __b, mve_pred16_t __p)
+__arm_vaddq_m_n_s16 (int16x8_t __inactive, int16x8_t __a, int16_t __b, mve_pred16_t __p)
{
return __builtin_mve_vaddq_m_n_sv8hi (__inactive, __a, __b, __p);
}
__extension__ extern __inline uint8x16_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m_n_u8 (uint8x16_t __inactive, uint8x16_t __a, int __b, mve_pred16_t __p)
+__arm_vaddq_m_n_u8 (uint8x16_t __inactive, uint8x16_t __a, uint8_t __b, mve_pred16_t __p)
{
return __builtin_mve_vaddq_m_n_uv16qi (__inactive, __a, __b, __p);
}
__extension__ extern __inline uint32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m_n_u32 (uint32x4_t __inactive, uint32x4_t __a, int __b, mve_pred16_t __p)
+__arm_vaddq_m_n_u32 (uint32x4_t __inactive, uint32x4_t __a, uint32_t __b, mve_pred16_t __p)
{
return __builtin_mve_vaddq_m_n_uv4si (__inactive, __a, __b, __p);
}
__extension__ extern __inline uint16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m_n_u16 (uint16x8_t __inactive, uint16x8_t __a, int __b, mve_pred16_t __p)
+__arm_vaddq_m_n_u16 (uint16x8_t __inactive, uint16x8_t __a, uint16_t __b, mve_pred16_t __p)
{
return __builtin_mve_vaddq_m_n_uv8hi (__inactive, __a, __b, __p);
}
@@ -26417,42 +26417,42 @@ __arm_vabdq_m (uint16x8_t __inactive, uint16x8_t __a, uint16x8_t __b, mve_pred16
__extension__ extern __inline int8x16_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m (int8x16_t __inactive, int8x16_t __a, int __b, mve_pred16_t __p)
+__arm_vaddq_m (int8x16_t __inactive, int8x16_t __a, int8_t __b, mve_pred16_t __p)
{
return __arm_vaddq_m_n_s8 (__inactive, __a, __b, __p);
}
__extension__ extern __inline int32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m (int32x4_t __inactive, int32x4_t __a, int __b, mve_pred16_t __p)
+__arm_vaddq_m (int32x4_t __inactive, int32x4_t __a, int32_t __b, mve_pred16_t __p)
{
return __arm_vaddq_m_n_s32 (__inactive, __a, __b, __p);
}
__extension__ extern __inline int16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m (int16x8_t __inactive, int16x8_t __a, int __b, mve_pred16_t __p)
+__arm_vaddq_m (int16x8_t __inactive, int16x8_t __a, int16_t __b, mve_pred16_t __p)
{
return __arm_vaddq_m_n_s16 (__inactive, __a, __b, __p);
}
__extension__ extern __inline uint8x16_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m (uint8x16_t __inactive, uint8x16_t __a, int __b, mve_pred16_t __p)
+__arm_vaddq_m (uint8x16_t __inactive, uint8x16_t __a, uint8_t __b, mve_pred16_t __p)
{
return __arm_vaddq_m_n_u8 (__inactive, __a, __b, __p);
}
__extension__ extern __inline uint32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m (uint32x4_t __inactive, uint32x4_t __a, int __b, mve_pred16_t __p)
+__arm_vaddq_m (uint32x4_t __inactive, uint32x4_t __a, uint32_t __b, mve_pred16_t __p)
{
return __arm_vaddq_m_n_u32 (__inactive, __a, __b, __p);
}
__extension__ extern __inline uint16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m (uint16x8_t __inactive, uint16x8_t __a, int __b, mve_pred16_t __p)
+__arm_vaddq_m (uint16x8_t __inactive, uint16x8_t __a, uint16_t __b, mve_pred16_t __p)
{
return __arm_vaddq_m_n_u16 (__inactive, __a, __b, __p);
}
@@ -35582,6 +35582,9 @@ enum {
short: __ARM_mve_type_int_n, \
int: __ARM_mve_type_int_n, \
long: __ARM_mve_type_int_n, \
+ _Float16: __ARM_mve_type_fp_n, \
+ __fp16: __ARM_mve_type_fp_n, \
+ float: __ARM_mve_type_fp_n, \
double: __ARM_mve_type_fp_n, \
long long: __ARM_mve_type_int_n, \
unsigned char: __ARM_mve_type_int_n, \
@@ -35657,6 +35660,8 @@ extern void *__ARM_undef;
_Generic(param, type: param, const type: param, default: *(type *)__ARM_undef)
#define __ARM_mve_coerce2(param, type) \
_Generic(param, type: param, float16_t: param, float32_t: param, default: *(type *)__ARM_undef)
+#define __ARM_mve_coerce3(param, type) \
+ _Generic(param, type: param, int8_t: param, int16_t: param, int32_t: param, int64_t: param, uint8_t: param, uint16_t: param, uint32_t: param, uint64_t: param, default: *(type *)__ARM_undef)
#if (__ARM_FEATURE_MVE & 2) /* MVE Floating point. */
@@ -35871,16 +35876,16 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vaddq_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t)), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vaddq_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t)), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vaddq_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t)), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vaddq_f16 (__ARM_mve_coerce(p0, float16x8_t), __ARM_mve_coerce(p1, float16x8_t)), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vaddq_f32 (__ARM_mve_coerce(p0, float32x4_t), __ARM_mve_coerce(p1, float32x4_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, int)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, int)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, int)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int)), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vaddq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(__p1, double)), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vaddq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(__p1, double)));})
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vaddq_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t)), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vaddq_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vaddq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(p1, double)), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vaddq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(p1, double)));})
#define __arm_vandq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -35925,14 +35930,14 @@ extern void *__ARM_undef;
#define __arm_vmulq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vmulq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(__p1, double)), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vmulq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(__p1, double)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vmulq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(p1, double)), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vmulq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(p1, double)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vmulq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmulq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmulq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -35957,14 +35962,14 @@ extern void *__ARM_undef;
#define __arm_vcmpeqq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpeqq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(__p1, double)), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpeqq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(__p1, double)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpeqq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(p1, double)), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpeqq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(p1, double)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpeqq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpeqq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpeqq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -35995,16 +36000,16 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcmpeqq_m_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), p2), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcmpeqq_m_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), p2), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcmpeqq_m_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), p2), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t), p2), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t), p2), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t), p2), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t), p2), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t), p2), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t), p2), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int), p2), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmpeqq_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), p2), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmpeqq_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), p2), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpeqq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(__p1, double), p2), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpeqq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(__p1, double), p2));})
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpeqq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(p1, double), p2), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpeqq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(p1, double), p2));})
#define __arm_vcmpgtq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -36012,13 +36017,13 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpgtq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpgtq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpgtq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmpgtq_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t)), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmpgtq_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t)), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpgtq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(__p1, double)), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpgtq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(__p1, double)));})
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpgtq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(p1, double)), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpgtq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(p1, double)));})
#define __arm_vcmpleq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -36028,11 +36033,11 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpleq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmpleq_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t)), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmpleq_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpleq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpleq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpleq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpleq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(__p1, double)), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpleq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(__p1, double)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpleq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpleq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpleq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpleq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(p1, double)), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpleq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(p1, double)));})
#define __arm_vcmpltq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -36040,25 +36045,25 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpltq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpltq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpltq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpltq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpltq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpltq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpltq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpltq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpltq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmpltq_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t)), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmpltq_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t)), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpltq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(__p1, double)), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpltq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(__p1, double)));})
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpltq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(p1, double)), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpltq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(p1, double)));})
#define __arm_vcmpneq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpneq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(__p1, double)), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpneq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(__p1, double)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpneq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(p1, double)), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpneq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(p1, double)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpneq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpneq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpneq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -36113,8 +36118,8 @@ extern void *__ARM_undef;
#define __arm_vmaxnmavq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vmaxnmavq_f16 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float16x8_t)), \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vmaxnmavq_f32 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float32x4_t)));})
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vmaxnmavq_f16 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float16x8_t)), \
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vmaxnmavq_f32 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float32x4_t)));})
#define __arm_vmaxnmq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -36125,14 +36130,14 @@ extern void *__ARM_undef;
#define __arm_vmaxnmvq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vmaxnmvq_f16 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float16x8_t)), \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vmaxnmvq_f32 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float32x4_t)));})
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vmaxnmvq_f16 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float16x8_t)), \
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vmaxnmvq_f32 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float32x4_t)));})
#define __arm_vmaxnmvq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vmaxnmvq_f16 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float16x8_t)), \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vmaxnmvq_f32 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float32x4_t)));})
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vmaxnmvq_f16 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float16x8_t)), \
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vmaxnmvq_f32 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float32x4_t)));})
#define __arm_vminnmaq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -36143,8 +36148,8 @@ extern void *__ARM_undef;
#define __arm_vminnmavq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vminnmavq_f16 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float16x8_t)), \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vminnmavq_f32 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float32x4_t)));})
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vminnmavq_f16 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float16x8_t)), \
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vminnmavq_f32 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float32x4_t)));})
#define __arm_vbrsrq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \
@@ -36166,14 +36171,14 @@ extern void *__ARM_undef;
#define __arm_vsubq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vsubq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(__p1, double)), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vsubq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(__p1, double)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)), \
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vsubq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(p1, double)), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vsubq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(p1, double)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vsubq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vsubq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vsubq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -36186,8 +36191,8 @@ extern void *__ARM_undef;
#define __arm_vminnmvq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vminnmvq_f16 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float16x8_t)), \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vminnmvq_f32 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float32x4_t)));})
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vminnmvq_f16 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float16x8_t)), \
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vminnmvq_f32 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float32x4_t)));})
#define __arm_vshlq_r(p0,p1) ({ __typeof(p0) __p0 = (p0); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \
@@ -36242,12 +36247,12 @@ extern void *__ARM_undef;
#define __arm_vrshlq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vrshlq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vrshlq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vrshlq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -36278,12 +36283,12 @@ extern void *__ARM_undef;
#define __arm_vqsubq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vqsubq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqsubq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqsubq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -36334,12 +36339,12 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int8x16_t]: __arm_vqrshlq_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqrshlq_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqrshlq_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)));})
#define __arm_vqrdmulhq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -36347,9 +36352,9 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vqrdmulhq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqrdmulhq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqrdmulhq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)));})
#define __arm_vmlaldavxq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -36382,8 +36387,8 @@ extern void *__ARM_undef;
#define __arm_vqdmulltq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmulltq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmulltq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmulltq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmulltq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqdmulltq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqdmulltq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)));})
@@ -36396,17 +36401,17 @@ extern void *__ARM_undef;
#define __arm_vqdmullbq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmullbq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmullbq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmullbq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmullbq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqdmullbq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqdmullbq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)));})
#define __arm_vqdmulhq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vqdmulhq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqdmulhq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqdmulhq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)));})
@@ -36414,12 +36419,12 @@ extern void *__ARM_undef;
#define __arm_vqaddq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vqaddq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqaddq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqaddq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -36452,12 +36457,12 @@ extern void *__ARM_undef;
#define __arm_vhaddq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vhaddq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vhaddq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vhaddq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -36482,12 +36487,12 @@ extern void *__ARM_undef;
#define __arm_vhsubq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vhsubq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vhsubq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vhsubq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -36630,12 +36635,12 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int)));})
#define __arm_vsriq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -36714,44 +36719,44 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int)));})
#define __arm_vqdmlashq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int)));})
#define __arm_vqrdmlahq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int)));})
#define __arm_vmlasq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int)));})
#define __arm_vqdmlahq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int)));})
#define __arm_vqrdmladhxq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -36941,11 +36946,11 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpgtq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), p2), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpgtq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), p2), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpgtq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), p2), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t), p2), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t), p2), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t), p2), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpgtq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(__p1, double), p2), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpgtq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(__p1, double), p2), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpgtq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(p1, double), p2), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpgtq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(p1, double), p2), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmpgtq_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), p2), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmpgtq_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), p2));})
@@ -36957,11 +36962,11 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpleq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), p2), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmpleq_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), p2), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmpleq_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), p2), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpleq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t), p2), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpleq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t), p2), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpleq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t), p2), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpleq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(__p1, double), p2), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpleq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(__p1, double), p2));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpleq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpleq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpleq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpleq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(p1, double), p2), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpleq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(p1, double), p2));})
#define __arm_vcmpltq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -36971,11 +36976,11 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpltq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), p2), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmpltq_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), p2), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmpltq_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), p2), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpltq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t), p2), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpltq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t), p2), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpltq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t), p2), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpltq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(__p1, double), p2), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpltq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(__p1, double), p2));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpltq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpltq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpltq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpltq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(p1, double), p2), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpltq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(p1, double), p2));})
#define __arm_vcmpneq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -36988,14 +36993,14 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcmpneq_m_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), p2), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmpneq_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), p2), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmpneq_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), p2), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t), p2), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t), p2), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t), p2), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t), p2), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t), p2), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t), p2), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpneq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(__p1, double), p2), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpneq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(__p1, double), p2));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpneq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(p1, double), p2), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpneq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(p1, double), p2));})
#define __arm_vcvtbq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -37049,8 +37054,8 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vfmaq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(__p2, double)), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vfmaq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(__p2, double)), \
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vfmaq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(p2, double)), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vfmaq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(p2, double)), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vfmaq_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t)), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vfmaq_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t)));})
@@ -37065,8 +37070,8 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vfmasq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(__p2, double)), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vfmasq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(__p2, double)));})
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vfmasq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(p2, double)), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vfmasq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(p2, double)));})
#define __arm_vmaxnmaq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -37089,14 +37094,14 @@ extern void *__ARM_undef;
#define __arm_vmaxnmavq_p(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vmaxnmavq_p_f16 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float16x8_t), p2), \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vmaxnmavq_p_f32 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float32x4_t), p2));})
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vmaxnmavq_p_f16 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float16x8_t), p2), \
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vmaxnmavq_p_f32 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float32x4_t), p2));})
#define __arm_vmaxnmvq_p(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vmaxnmvq_p_f16 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float16x8_t), p2), \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vmaxnmvq_p_f32 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float32x4_t), p2));})
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vmaxnmvq_p_f16 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float16x8_t), p2), \
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vmaxnmvq_p_f32 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float32x4_t), p2));})
#define __arm_vminnmaq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -37107,14 +37112,14 @@ extern void *__ARM_undef;
#define __arm_vminnmavq_p(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vminnmavq_p_f16 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float16x8_t), p2), \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vminnmavq_p_f32 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float32x4_t), p2));})
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vminnmavq_p_f16 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float16x8_t), p2), \
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vminnmavq_p_f32 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float32x4_t), p2));})
#define __arm_vminnmvq_p(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vminnmvq_p_f16 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float16x8_t), p2), \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vminnmvq_p_f32 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float32x4_t), p2));})
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vminnmvq_p_f16 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float16x8_t), p2), \
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vminnmvq_p_f32 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float32x4_t), p2));})
#define __arm_vrndnq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -37176,13 +37181,13 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpgeq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpgeq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpgeq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmpgeq_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t)), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmpgeq_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t)), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpgeq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(__p1, double)), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpgeq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(__p1, double)));})
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpgeq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(p1, double)), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpgeq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(p1, double)));})
#define __arm_vrshrnbq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -37283,11 +37288,11 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpgeq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), p2), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpgeq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), p2), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpgeq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), p2), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t), p2), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t), p2), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t), p2), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpgeq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(__p1, double), p2), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpgeq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(__p1, double), p2), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vcmpgeq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce2(p1, double), p2), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vcmpgeq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce2(p1, double), p2), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vcmpgeq_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), p2), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vcmpgeq_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), p2));})
@@ -37316,14 +37321,14 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vaddq_m_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vaddq_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vaddq_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, int), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, int), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, int), p3), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vaddq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(__p2, double), p3), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vaddq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(__p2, double), p3));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vaddq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(p2, double), p3), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vaddq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(p2, double), p3));})
#define __arm_vandq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -37464,15 +37469,15 @@ extern void *__ARM_undef;
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vfmaq_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vfmaq_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vfmaq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(__p2, double), p3), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vfmaq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(__p2, double), p3));})
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vfmaq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(p2, double), p3), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vfmaq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(p2, double), p3));})
#define __arm_vfmasq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vfmasq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(__p2, double), p3), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vfmasq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(__p2, double), p3));})
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vfmasq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(p2, double), p3), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vfmasq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(p2, double), p3));})
#define __arm_vfmsq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -37507,14 +37512,14 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmulq_m_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vmulq_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vmulq_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vmulq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(__p2, double), p3), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vmulq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(__p2, double), p3));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vmulq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(p2, double), p3), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vmulq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(p2, double), p3));})
#define __arm_vornq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -37541,14 +37546,14 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vsubq_m_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vsubq_m_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vsubq_m_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vsubq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(__p2, double), p3), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vsubq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(__p2, double), p3));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vsubq_m_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(p2, double), p3), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vsubq_m_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(p2, double), p3));})
#define __arm_vorrq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -38021,19 +38026,19 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vaddq_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vaddq_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vaddq_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vaddq_x_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vaddq_x_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vaddq_x_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vaddq_x_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vaddq_x_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vaddq_x_n_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(__p2, double), p3), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vaddq_x_n_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(__p2, double), p3));})
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vaddq_x_n_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(p2, double), p3), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vaddq_x_n_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(p2, double), p3));})
#define __arm_vandq_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
@@ -38156,19 +38161,19 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vmulq_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmulq_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmulq_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vmulq_x_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmulq_x_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmulq_x_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vmulq_x_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vmulq_x_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vmulq_x_n_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(__p2, double), p3), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vmulq_x_n_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(__p2, double), p3));})
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vmulq_x_n_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(p2, double), p3), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vmulq_x_n_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(p2, double), p3));})
#define __arm_vnegq_x(p1,p2) ({ __typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p1)])0, \
@@ -38254,10 +38259,22 @@ extern void *__ARM_undef;
#define __arm_vsubq_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vsubq_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vsubq_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vsubq_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vsubq_x_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vsubq_x_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vsubq_x_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: __arm_vsubq_x_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, float16x8_t), p3), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: __arm_vsubq_x_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, float32x4_t), p3), \
- int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vsubq_x_n_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(__p2, double), p3), \
- int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vsubq_x_n_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(__p2, double), p3));})
+ int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: __arm_vsubq_x_n_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(p2, double), p3), \
+ int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_fp_n]: __arm_vsubq_x_n_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce2(p2, double), p3));})
#define __arm_vcmulq_rot90_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
@@ -38281,16 +38298,16 @@ extern void *__ARM_undef;
#define __arm_vsetq_lane(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t]: __arm_vsetq_lane_s8 (__ARM_mve_coerce(__p0, int8_t), __ARM_mve_coerce(__p1, int8x16_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t]: __arm_vsetq_lane_s16 (__ARM_mve_coerce(__p0, int16_t), __ARM_mve_coerce(__p1, int16x8_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t]: __arm_vsetq_lane_s32 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int32x4_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int64x2_t]: __arm_vsetq_lane_s64 (__ARM_mve_coerce(__p0, int64_t), __ARM_mve_coerce(__p1, int64x2_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t]: __arm_vsetq_lane_u8 (__ARM_mve_coerce(__p0, uint8_t), __ARM_mve_coerce(__p1, uint8x16_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t]: __arm_vsetq_lane_u16 (__ARM_mve_coerce(__p0, uint16_t), __ARM_mve_coerce(__p1, uint16x8_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t]: __arm_vsetq_lane_u32 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint32x4_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint64x2_t]: __arm_vsetq_lane_u64 (__ARM_mve_coerce(__p0, uint64_t), __ARM_mve_coerce(__p1, uint64x2_t), p2), \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vsetq_lane_f16 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float16x8_t), p2), \
- int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vsetq_lane_f32 (__ARM_mve_coerce2(__p0, double), __ARM_mve_coerce(__p1, float32x4_t), p2));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t]: __arm_vsetq_lane_s8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int8x16_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t]: __arm_vsetq_lane_s16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int16x8_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t]: __arm_vsetq_lane_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int64x2_t]: __arm_vsetq_lane_s64 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int64x2_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t]: __arm_vsetq_lane_u8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint8x16_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t]: __arm_vsetq_lane_u16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint16x8_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t]: __arm_vsetq_lane_u32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint32x4_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint64x2_t]: __arm_vsetq_lane_u64 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint64x2_t), p2), \
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float16x8_t]: __arm_vsetq_lane_f16 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float16x8_t), p2), \
+ int (*)[__ARM_mve_type_fp_n][__ARM_mve_type_float32x4_t]: __arm_vsetq_lane_f32 (__ARM_mve_coerce2(p0, double), __ARM_mve_coerce(__p1, float32x4_t), p2));})
#else /* MVE Integer. */
@@ -38408,12 +38425,12 @@ extern void *__ARM_undef;
#define __arm_vcmpneq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpneq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpneq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpneq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -38440,12 +38457,12 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vsubq_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t)), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vsubq_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t)), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vsubq_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)));})
#define __arm_vshlq_r(p0,p1) ({ __typeof(p0) __p0 = (p0); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \
@@ -38459,12 +38476,12 @@ extern void *__ARM_undef;
#define __arm_vrshlq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vrshlq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vrshlq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vrshlq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vrshlq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -38495,12 +38512,12 @@ extern void *__ARM_undef;
#define __arm_vqsubq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqsubq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vqsubq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqsubq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqsubq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -38569,12 +38586,12 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int8x16_t]: __arm_vqrshlq_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqrshlq_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqrshlq_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqrshlq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)));})
#define __arm_vqrdmulhq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -38582,16 +38599,16 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vqrdmulhq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqrdmulhq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqrdmulhq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)));})
#define __arm_vqdmulhq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vqdmulhq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqdmulhq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqdmulhq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)));})
@@ -38599,12 +38616,12 @@ extern void *__ARM_undef;
#define __arm_vqaddq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqaddq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vqaddq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqaddq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqaddq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -38635,12 +38652,12 @@ extern void *__ARM_undef;
#define __arm_vmulq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vmulq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmulq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmulq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -38715,12 +38732,12 @@ extern void *__ARM_undef;
#define __arm_vhsubq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vhsubq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vhsubq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vhsubq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -38745,12 +38762,12 @@ extern void *__ARM_undef;
#define __arm_vhaddq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vhaddq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vhaddq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vhaddq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
@@ -38820,12 +38837,12 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vaddq_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t)), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vaddq_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t)), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vaddq_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, int)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, int)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, int)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int)));})
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)));})
#define __arm_vandq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -38856,12 +38873,12 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcmpeqq_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t)), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcmpeqq_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t)), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcmpeqq_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)));})
#define __arm_vqmovntq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -38942,16 +38959,16 @@ extern void *__ARM_undef;
#define __arm_vqdmulltq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmulltq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmulltq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmulltq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmulltq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqdmulltq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqdmulltq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)));})
#define __arm_vqdmullbq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmullbq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmullbq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmullbq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmullbq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqdmullbq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqdmullbq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)));})
@@ -38961,9 +38978,9 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpgeq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpgeq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpgeq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)));})
#define __arm_vcmpgtq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -38971,9 +38988,9 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpgtq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpgtq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpgtq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)));})
#define __arm_vcmpleq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -38981,9 +38998,9 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpleq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpleq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpleq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpleq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpleq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpleq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpleq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpleq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpleq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)));})
#define __arm_vcmpltq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -38991,20 +39008,20 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpltq_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t)), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpltq_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t)), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpltq_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t)), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpltq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpltq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpltq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpltq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpltq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpltq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int)));})
#define __arm_vcmpneq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpneq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), p2), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t), p2), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t), p2), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t), p2), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t), p2), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t), p2), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t), p2), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int), p2), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpneq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), p2), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpneq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), p2), \
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcmpneq_m_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), p2), \
@@ -39029,12 +39046,12 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcmpeqq_m_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), p2), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcmpeqq_m_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), p2), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcmpeqq_m_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), p2), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t), p2), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t), p2), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t), p2), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t), p2), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t), p2), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t), p2));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpeqq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int), p2));})
#define __arm_vbicq_m_n(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \
@@ -39144,25 +39161,25 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int)));})
#define __arm_vqdmlashq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int)));})
#define __arm_vqrdmlahq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int)));})
#define __arm_vqrdmladhxq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -39225,9 +39242,56 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpgeq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), p2), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpgeq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), p2), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpgeq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), p2), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8_t), p2), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16_t), p2), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32_t), p2));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpgeq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int), p2));})
+
+
+#define __arm_vcmpgtq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
+ __typeof(p1) __p1 = (p1); \
+ _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpgtq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpgtq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpgtq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), p2), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpgtq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int), p2));})
+
+#define __arm_vcmpleq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
+ __typeof(p1) __p1 = (p1); \
+ _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpleq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpleq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpleq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), p2), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpleq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpleq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpleq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int), p2));})
+
+#define __arm_vcmpltq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
+ __typeof(p1) __p1 = (p1); \
+ _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpltq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpltq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpltq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), p2), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpltq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpltq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpltq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int), p2));})
+
+#define __arm_vcmpneq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
+ __typeof(p1) __p1 = (p1); \
+ _Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vcmpneq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vcmpneq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vcmpneq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), p2), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcmpneq_m_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), p2), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcmpneq_m_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), p2), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcmpneq_m_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), p2), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpneq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int), p2));})
#define __arm_vdupq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -39250,23 +39314,23 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmlaq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int)));})
#define __arm_vmlasq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmlasq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int)));})
#define __arm_vnegq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -39291,9 +39355,9 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t)), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t)), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t)));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int)), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int)));})
#define __arm_vqdmlsdhq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -39456,12 +39520,12 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vsubq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vsubq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vsubq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
@@ -39561,12 +39625,12 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vmladavaq_p_s8 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmladavaq_p_s16 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmladavaq_p_s32 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vmladavaq_p_u8 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmladavaq_p_u16 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmladavaq_p_u32 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vmladavaq_p_s8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmladavaq_p_s16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmladavaq_p_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vmladavaq_p_u8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmladavaq_p_u16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmladavaq_p_u32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3));})
#define __arm_vornq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -39594,12 +39658,12 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, int), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, int), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, int), p3), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vaddq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vaddq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vaddq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
@@ -39611,12 +39675,12 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vmulq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmulq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmulq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
@@ -39953,15 +40017,15 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vaddq_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vaddq_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vaddq_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vaddq_x_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vaddq_x_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vaddq_x_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3));})
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vaddq_x_n_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3));})
#define __arm_vcaddq_rot270_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
@@ -40055,15 +40119,15 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vmulq_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmulq_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmulq_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vmulq_x_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmulq_x_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmulq_x_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3));})
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmulq_x_n_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3));})
#define __arm_vnegq_x(p1,p2) ({ __typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p1)])0, \
@@ -40171,6 +40235,22 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld4q_u16 (__ARM_mve_coerce1(p0, uint16_t *)), \
int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld4q_u32 (__ARM_mve_coerce1(p0, uint32_t *))))
+#define __arm_vsubq_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \
+ __typeof(p2) __p2 = (p2); \
+ _Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vsubq_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vsubq_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vsubq_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vsubq_x_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vsubq_x_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vsubq_x_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3));})
+
#define __arm_vgetq_lane(p0,p1) ({ __typeof(p0) __p0 = (p0); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \
int (*)[__ARM_mve_type_int8x16_t]: __arm_vgetq_lane_s8 (__ARM_mve_coerce(__p0, int8x16_t), p1), \
@@ -40185,14 +40265,14 @@ extern void *__ARM_undef;
#define __arm_vsetq_lane(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t]: __arm_vsetq_lane_s8 (__ARM_mve_coerce(__p0, int8_t), __ARM_mve_coerce(__p1, int8x16_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t]: __arm_vsetq_lane_s16 (__ARM_mve_coerce(__p0, int16_t), __ARM_mve_coerce(__p1, int16x8_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t]: __arm_vsetq_lane_s32 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int32x4_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int64x2_t]: __arm_vsetq_lane_s64 (__ARM_mve_coerce(__p0, int64_t), __ARM_mve_coerce(__p1, int64x2_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t]: __arm_vsetq_lane_u8 (__ARM_mve_coerce(__p0, uint8_t), __ARM_mve_coerce(__p1, uint8x16_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t]: __arm_vsetq_lane_u16 (__ARM_mve_coerce(__p0, uint16_t), __ARM_mve_coerce(__p1, uint16x8_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t]: __arm_vsetq_lane_u32 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint32x4_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint64x2_t]: __arm_vsetq_lane_u64 (__ARM_mve_coerce(__p0, uint64_t), __ARM_mve_coerce(__p1, uint64x2_t), p2));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t]: __arm_vsetq_lane_s8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int8x16_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t]: __arm_vsetq_lane_s16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int16x8_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t]: __arm_vsetq_lane_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int64x2_t]: __arm_vsetq_lane_s64 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int64x2_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t]: __arm_vsetq_lane_u8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint8x16_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t]: __arm_vsetq_lane_u16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint16x8_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t]: __arm_vsetq_lane_u32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint32x4_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint64x2_t]: __arm_vsetq_lane_u64 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint64x2_t), p2));})
#endif /* MVE Integer. */
@@ -40372,12 +40452,12 @@ extern void *__ARM_undef;
#define __arm_vhaddq_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_x_n_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_x_n_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_x_n_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_x_n_u8( __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_x_n_u16( __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_x_n_u32( __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_x_n_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_x_n_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_x_n_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_x_n_u8( __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_x_n_u16( __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_x_n_u32( __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vhaddq_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vhaddq_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vhaddq_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
@@ -40402,12 +40482,12 @@ extern void *__ARM_undef;
#define __arm_vhsubq_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_x_n_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_x_n_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_x_n_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_x_n_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_x_n_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_x_n_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_x_n_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_x_n_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_x_n_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_x_n_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_x_n_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_x_n_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vhsubq_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vhsubq_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vhsubq_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
@@ -40527,25 +40607,25 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmlahq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3));})
#define __arm_vqrdmlashq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmlashq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3));})
#define __arm_vqdmlashq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmlashq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3));})
#define __arm_vqrshlq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -40646,12 +40726,12 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqsubq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqsubq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqsubq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqsubq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqsubq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqsubq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqsubq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqsubq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqsubq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqsubq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqsubq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqsubq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vqsubq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqsubq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqsubq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
@@ -40666,9 +40746,9 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vqrdmulhq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqrdmulhq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqrdmulhq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqrdmulhq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3));})
#define __arm_vqrdmlsdhxq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -40794,17 +40874,17 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmlaldavaq_p_s16 (__ARM_mve_coerce(__p0, int64_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmlaldavaq_p_s32 (__ARM_mve_coerce(__p0, int64_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmlaldavaq_p_u16 (__ARM_mve_coerce(__p0, uint64_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmlaldavaq_p_u32 (__ARM_mve_coerce(__p0, uint64_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmlaldavaq_p_s16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmlaldavaq_p_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmlaldavaq_p_u16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmlaldavaq_p_u32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3));})
#define __arm_vmlaldavaxq_p(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmlaldavaxq_p_s16 (__ARM_mve_coerce(__p0, int64_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmlaldavaxq_p_s32 (__ARM_mve_coerce(__p0, int64_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmlaldavaxq_p_s16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmlaldavaxq_p_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3));})
#define __arm_vmlsldavaq_p(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -40943,12 +41023,12 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhaddq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhaddq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhaddq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vhaddq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vhaddq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vhaddq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
@@ -40982,12 +41062,12 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vhsubq_m_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vhsubq_m_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vhsubq_m_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3), \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vhsubq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vhsubq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vhsubq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3));})
#define __arm_vmaxq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -41015,23 +41095,23 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmlaq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmlaq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmlaq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmlaq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmlaq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmlaq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmlaq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmlaq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmlaq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmlaq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmlaq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmlaq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3));})
#define __arm_vmlasq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmlasq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmlasq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmlasq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmlasq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmlasq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmlasq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vmlasq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vmlasq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vmlasq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vmlasq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vmlasq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vmlasq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3));})
#define __arm_vmulhq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -41077,12 +41157,12 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqaddq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqaddq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqaddq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqaddq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8_t), p3), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqaddq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16_t), p3), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqaddq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32_t), p3), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqaddq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqaddq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqaddq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vqaddq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vqaddq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vqaddq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vqaddq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqaddq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqaddq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
@@ -41094,17 +41174,17 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3));})
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmlahq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3));})
#define __arm_vqdmulhq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8_t), p3), \
- int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
+ int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_m_n_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_m_n_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmulhq_m_n_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vqdmulhq_m_s8 (__ARM_mve_coerce(__p0, int8x16_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqdmulhq_m_s16 (__ARM_mve_coerce(__p0, int16x8_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqdmulhq_m_s32 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3));})
@@ -41115,15 +41195,15 @@ extern void *__ARM_undef;
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqdmullbq_m_s16 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int64x2_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqdmullbq_m_s32 (__ARM_mve_coerce(__p0, int64x2_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmullbq_m_n_s16 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int64x2_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmullbq_m_n_s32 (__ARM_mve_coerce(__p0, int64x2_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3));})
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmullbq_m_n_s16 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int64x2_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmullbq_m_n_s32 (__ARM_mve_coerce(__p0, int64x2_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3));})
#define __arm_vqdmulltq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmulltq_m_n_s16 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16_t), p3), \
- int (*)[__ARM_mve_type_int64x2_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmulltq_m_n_s32 (__ARM_mve_coerce(__p0, int64x2_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32_t), p3), \
+ int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vqdmulltq_m_n_s16 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+ int (*)[__ARM_mve_type_int64x2_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vqdmulltq_m_n_s32 (__ARM_mve_coerce(__p0, int64x2_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vqdmulltq_m_s16 (__ARM_mve_coerce(__p0, int32x4_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
int (*)[__ARM_mve_type_int64x2_t][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vqdmulltq_m_s32 (__ARM_mve_coerce(__p0, int64x2_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3));})
@@ -41189,9 +41269,9 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vmladavaxq_p_s8 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmladavaxq_p_s16 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmladavaxq_p_s32 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vmladavaxq_p_s8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmladavaxq_p_s16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmladavaxq_p_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3));})
#define __arm_vmullbq_poly_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -41262,51 +41342,51 @@ extern void *__ARM_undef;
#define __arm_viwdupq_m(p0,p1,p2,p3,p4) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_viwdupq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint32_t), p2, p3, p4), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_viwdupq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint32_t), p2, p3, p4), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_viwdupq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t), p2, p3, p4), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_viwdupq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int), p2, p3, p4), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_viwdupq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int), p2, p3, p4), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_viwdupq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int), p2, p3, p4), \
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint32_t_ptr]: __arm_viwdupq_m_wb_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint32_t *), p2, p3, p4), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint32_t_ptr]: __arm_viwdupq_m_wb_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint32_t *), p2, p3, p4), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32_t_ptr]: __arm_viwdupq_m_wb_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t *), p2, p3, p4));})
#define __arm_viwdupq_u16(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \
- int (*)[__ARM_mve_type_int_n]: __arm_viwdupq_n_u16 (__ARM_mve_coerce(__p0, uint32_t), p1, (const int) p2), \
+ int (*)[__ARM_mve_type_int_n]: __arm_viwdupq_n_u16 (__ARM_mve_coerce3(p0, int), p1, (const int) p2), \
int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_viwdupq_wb_u16 (__ARM_mve_coerce(__p0, uint32_t *), p1, (const int) p2));})
#define __arm_viwdupq_u32(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \
- int (*)[__ARM_mve_type_int_n]: __arm_viwdupq_n_u32 (__ARM_mve_coerce(__p0, uint32_t), p1, p2), \
+ int (*)[__ARM_mve_type_int_n]: __arm_viwdupq_n_u32 (__ARM_mve_coerce3(p0, int), p1, p2), \
int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_viwdupq_wb_u32 (__ARM_mve_coerce(__p0, uint32_t *), p1, p2));})
#define __arm_viwdupq_u8(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \
- int (*)[__ARM_mve_type_int_n]: __arm_viwdupq_n_u8 (__ARM_mve_coerce(__p0, uint32_t), p1, p2), \
+ int (*)[__ARM_mve_type_int_n]: __arm_viwdupq_n_u8 (__ARM_mve_coerce3(p0, int), p1, p2), \
int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_viwdupq_wb_u8 (__ARM_mve_coerce(__p0, uint32_t *), p1, p2));})
#define __arm_vdwdupq_m(p0,p1,p2,p3,p4) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vdwdupq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint32_t), p2, p3, p4), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vdwdupq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint32_t), p2, p3, p4), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vdwdupq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t), p2, p3, p4), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vdwdupq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int), p2, p3, p4), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vdwdupq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int), p2, p3, p4), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vdwdupq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int), p2, p3, p4), \
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint32_t_ptr]: __arm_vdwdupq_m_wb_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint32_t *), p2, p3, p4), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint32_t_ptr]: __arm_vdwdupq_m_wb_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint32_t *), p2, p3, p4), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32_t_ptr]: __arm_vdwdupq_m_wb_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t *), p2, p3, p4));})
#define __arm_vdwdupq_u16(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \
- int (*)[__ARM_mve_type_int_n]: __arm_vdwdupq_n_u16 (__ARM_mve_coerce(__p0, uint32_t), p1, p2), \
+ int (*)[__ARM_mve_type_int_n]: __arm_vdwdupq_n_u16 (__ARM_mve_coerce3(p0, int), p1, p2), \
int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vdwdupq_wb_u16 (__ARM_mve_coerce(__p0, uint32_t *), p1, p2));})
#define __arm_vdwdupq_u32(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \
- int (*)[__ARM_mve_type_int_n]: __arm_vdwdupq_n_u32 (__ARM_mve_coerce(__p0, uint32_t), p1, p2), \
+ int (*)[__ARM_mve_type_int_n]: __arm_vdwdupq_n_u32 (__ARM_mve_coerce3(p0, int), p1, p2), \
int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vdwdupq_wb_u32 (__ARM_mve_coerce(__p0, uint32_t *), p1, p2));})
#define __arm_vdwdupq_u8(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \
- int (*)[__ARM_mve_type_int_n]: __arm_vdwdupq_n_u8 (__ARM_mve_coerce(__p0, uint32_t), p1, p2), \
+ int (*)[__ARM_mve_type_int_n]: __arm_vdwdupq_n_u8 (__ARM_mve_coerce3(p0, int), p1, p2), \
int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vdwdupq_wb_u8 (__ARM_mve_coerce(__p0, uint32_t *), p1, p2));})
#define __arm_vshlcq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
@@ -41343,14 +41423,14 @@ extern void *__ARM_undef;
#define __arm_vaddlvaq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t]: __arm_vaddlvaq_s32 (__ARM_mve_coerce(__p0, int64_t), __ARM_mve_coerce(__p1, int32x4_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t]: __arm_vaddlvaq_u32 (__ARM_mve_coerce(__p0, uint64_t), __ARM_mve_coerce(__p1, uint32x4_t)));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t]: __arm_vaddlvaq_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t]: __arm_vaddlvaq_u32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint32x4_t)));})
#define __arm_vaddlvaq_p(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t]: __arm_vaddlvaq_p_s32 (__ARM_mve_coerce(__p0, int64_t), __ARM_mve_coerce(__p1, int32x4_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t]: __arm_vaddlvaq_p_u32 (__ARM_mve_coerce(__p0, uint64_t), __ARM_mve_coerce(__p1, uint32x4_t), p2));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t]: __arm_vaddlvaq_p_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t]: __arm_vaddlvaq_p_u32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint32x4_t), p2));})
#define __arm_vaddlvq(p0) ({ __typeof(p0) __p0 = (p0); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \
@@ -41365,22 +41445,22 @@ extern void *__ARM_undef;
#define __arm_vaddvaq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t]: __arm_vaddvaq_s8 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int8x16_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t]: __arm_vaddvaq_s16 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int16x8_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t]: __arm_vaddvaq_s32 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int32x4_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t]: __arm_vaddvaq_u8 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint8x16_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t]: __arm_vaddvaq_u16 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint16x8_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t]: __arm_vaddvaq_u32 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint32x4_t)));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t]: __arm_vaddvaq_s8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int8x16_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t]: __arm_vaddvaq_s16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int16x8_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t]: __arm_vaddvaq_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t]: __arm_vaddvaq_u8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint8x16_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t]: __arm_vaddvaq_u16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint16x8_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t]: __arm_vaddvaq_u32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint32x4_t)));})
#define __arm_vaddvaq_p(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t]: __arm_vaddvaq_p_s8 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int8x16_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t]: __arm_vaddvaq_p_s16 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int16x8_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t]: __arm_vaddvaq_p_s32 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int32x4_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t]: __arm_vaddvaq_p_u8 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint8x16_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t]: __arm_vaddvaq_p_u16 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint16x8_t), p2), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t]: __arm_vaddvaq_p_u32 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint32x4_t), p2));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t]: __arm_vaddvaq_p_s8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int8x16_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t]: __arm_vaddvaq_p_s16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int16x8_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t]: __arm_vaddvaq_p_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t]: __arm_vaddvaq_p_u8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint8x16_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t]: __arm_vaddvaq_p_u16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint16x8_t), p2), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t]: __arm_vaddvaq_p_u32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint32x4_t), p2));})
#define __arm_vaddvq(p0) ({ __typeof(p0) __p0 = (p0); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \
@@ -41406,9 +41486,9 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcmpcsq_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t)), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcmpcsq_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t)), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcmpcsq_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpcsq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpcsq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpcsq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)));})
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpcsq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpcsq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpcsq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)));})
#define __arm_vcmpcsq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -41416,9 +41496,9 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcmpcsq_m_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), p2), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcmpcsq_m_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), p2), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcmpcsq_m_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), p2), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpcsq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t), p2), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpcsq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t), p2), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpcsq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t), p2));})
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmpcsq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmpcsq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmpcsq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int), p2));})
#define __arm_vcmphiq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -41426,16 +41506,16 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcmphiq_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t)), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcmphiq_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t)), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcmphiq_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t)), \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmphiq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t)), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmphiq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t)), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmphiq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t)));})
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmphiq_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmphiq_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int)), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmphiq_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int)));})
#define __arm_vcmphiq_m(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
- int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmphiq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8_t), p2), \
- int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmphiq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16_t), p2), \
- int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmphiq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32_t), p2), \
+ int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vcmphiq_m_n_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: __arm_vcmphiq_m_n_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce3(p1, int), p2), \
+ int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: __arm_vcmphiq_m_n_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce3(p1, int), p2), \
int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vcmphiq_m_u8 (__ARM_mve_coerce(__p0, uint8x16_t), __ARM_mve_coerce(__p1, uint8x16_t), p2), \
int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vcmphiq_m_u16 (__ARM_mve_coerce(__p0, uint16x8_t), __ARM_mve_coerce(__p1, uint16x8_t), p2), \
int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vcmphiq_m_u32 (__ARM_mve_coerce(__p0, uint32x4_t), __ARM_mve_coerce(__p1, uint32x4_t), p2));})
@@ -41532,34 +41612,34 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vmladavaq_s8 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmladavaq_s16 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmladavaq_s32 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vmladavaq_u8 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmladavaq_u16 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmladavaq_u32 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t)));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vmladavaq_s8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmladavaq_s16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmladavaq_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vmladavaq_u8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmladavaq_u16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmladavaq_u32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t)));})
#define __arm_vmladavaq_p(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vmladavaq_p_s8 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmladavaq_p_s16 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmladavaq_p_s32 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vmladavaq_p_u8 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmladavaq_p_u16 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmladavaq_p_u32 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vmladavaq_p_s8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmladavaq_p_s16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmladavaq_p_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vmladavaq_p_u8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmladavaq_p_u16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmladavaq_p_u32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3));})
#define __arm_vmladavaxq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vmladavaxq_s8 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmladavaxq_s16 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmladavaxq_s32 (__ARM_mve_coerce(__p0, int32_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vmladavaxq_u8 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmladavaxq_u16 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmladavaxq_u32 (__ARM_mve_coerce(__p0, uint32_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t)));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: __arm_vmladavaxq_s8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, int8x16_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmladavaxq_s16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmladavaxq_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: __arm_vmladavaxq_u8 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, uint8x16_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmladavaxq_u16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmladavaxq_u32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t)));})
#define __arm_vmladavq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -41602,17 +41682,17 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmlaldavaq_s16 (__ARM_mve_coerce(__p0, int64_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmlaldavaq_s32 (__ARM_mve_coerce(__p0, int64_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmlaldavaq_u16 (__ARM_mve_coerce(__p0, uint64_t), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmlaldavaq_u32 (__ARM_mve_coerce(__p0, uint64_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t)));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmlaldavaq_s16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmlaldavaq_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: __arm_vmlaldavaq_u16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, uint16x8_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vmlaldavaq_u32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t)));})
#define __arm_vmlaldavaxq(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmlaldavaxq_s16 (__ARM_mve_coerce(__p0, int64_t), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmlaldavaxq_s32 (__ARM_mve_coerce(__p0, int64_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t)));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: __arm_vmlaldavaxq_s16 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, int16x8_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vmlaldavaxq_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t)));})
#define __arm_vmlaldavq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
@@ -41807,15 +41887,15 @@ extern void *__ARM_undef;
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vrmlaldavhaq_s32 (__ARM_mve_coerce(__p0, int64_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t)), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vrmlaldavhaq_u32 (__ARM_mve_coerce(__p0, uint64_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t)));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vrmlaldavhaq_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t)), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vrmlaldavhaq_u32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t)));})
#define __arm_vrmlaldavhaq_p(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
__typeof(p2) __p2 = (p2); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vrmlaldavhaq_p_s32 (__ARM_mve_coerce(__p0, int64_t), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
- int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vrmlaldavhaq_p_u32 (__ARM_mve_coerce(__p0, uint64_t), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3));})
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: __arm_vrmlaldavhaq_p_s32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, int32x4_t), p3), \
+ int (*)[__ARM_mve_type_int_n][__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: __arm_vrmlaldavhaq_p_u32 (__ARM_mve_coerce3(p0, int), __ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, uint32x4_t), p3));})
#define __arm_vstrbq_scatter_offset(p0,p1,p2) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 62186f1..3fe9db8 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -266,7 +266,7 @@
VDUPQ_N_F))
]
"TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
- "vdup.%#<V_sz_elem> %q0, %1"
+ "vdup.%#<V_sz_elem>\t%q0, %1"
[(set_attr "type" "mve_move")
])
@@ -279,7 +279,7 @@
(abs:MVE_0 (match_operand:MVE_0 1 "s_register_operand" "w")))
]
"TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
- "vabs.f%#<V_sz_elem> %q0, %q1"
+ "vabs.f%#<V_sz_elem>\t%q0, %q1"
[(set_attr "type" "mve_move")
])
@@ -435,7 +435,7 @@
VDUPQ_N))
]
"TARGET_HAVE_MVE"
- "vdup.%#<V_sz_elem> %q0, %1"
+ "vdup.%#<V_sz_elem>\t%q0, %1"
[(set_attr "type" "mve_move")
])
@@ -636,7 +636,7 @@
VADDLVQ))
]
"TARGET_HAVE_MVE"
- "vaddlv.<supf>32 %Q0, %R0, %q1"
+ "vaddlv.<supf>32\t%Q0, %R0, %q1"
[(set_attr "type" "mve_move")
])
@@ -679,7 +679,7 @@
VSUBQ_N_F))
]
"TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
- "vsub.f<V_sz_elem> %q0, %q1, %2"
+ "vsub.f<V_sz_elem>\t%q0, %q1, %2"
[(set_attr "type" "mve_move")
])
@@ -817,7 +817,7 @@
VADDLVQ_P))
]
"TARGET_HAVE_MVE"
- "vpst\;vaddlvt.<supf>32 %Q0, %R0, %q1"
+ "vpst\;vaddlvt.<supf>32\t%Q0, %R0, %q1"
[(set_attr "type" "mve_move")
(set_attr "length""8")])
@@ -831,7 +831,7 @@
(match_operand:MVE_2 2 "s_register_operand" "w")))
]
"TARGET_HAVE_MVE"
- "vcmp.<mve_cmp_type>%#<V_sz_elem> <mve_cmp_op>, %q1, %q2"
+ "vcmp.<mve_cmp_type>%#<V_sz_elem>\t<mve_cmp_op>, %q1, %q2"
[(set_attr "type" "mve_move")
])
@@ -841,8 +841,9 @@
(define_insn "mve_vcmp<mve_cmp_op>q_n_<mode>"
[
(set (match_operand:<MVE_VPRED> 0 "vpr_register_operand" "=Up")
- (MVE_COMPARISONS:<MVE_VPRED> (match_operand:MVE_2 1 "s_register_operand" "w")
- (match_operand:<V_elem> 2 "s_register_operand" "r")))
+ (MVE_COMPARISONS:<MVE_VPRED>
+ (match_operand:MVE_2 1 "s_register_operand" "w")
+ (vec_duplicate:MVE_2 (match_operand:<V_elem> 2 "s_register_operand" "r"))))
]
"TARGET_HAVE_MVE"
"vcmp.<mve_cmp_type>%#<V_sz_elem> <mve_cmp_op>, %q1, %2"
@@ -879,7 +880,7 @@
VADDQ_N))
]
"TARGET_HAVE_MVE"
- "vadd.i%#<V_sz_elem> %q0, %q1, %2"
+ "vadd.i%#<V_sz_elem>\t%q0, %q1, %2"
[(set_attr "type" "mve_move")
])
@@ -894,7 +895,7 @@
VADDVAQ))
]
"TARGET_HAVE_MVE"
- "vaddva.<supf>%#<V_sz_elem> %0, %q2"
+ "vaddva.<supf>%#<V_sz_elem>\t%0, %q2"
[(set_attr "type" "mve_move")
])
@@ -1834,7 +1835,7 @@
VADDLVAQ))
]
"TARGET_HAVE_MVE"
- "vaddlva.<supf>32 %Q0, %R0, %q2"
+ "vaddlva.<supf>32\t%Q0, %R0, %q2"
[(set_attr "type" "mve_move")
])
@@ -1849,7 +1850,7 @@
VADDQ_N_F))
]
"TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
- "vadd.f%#<V_sz_elem> %q0, %q1, %2"
+ "vadd.f%#<V_sz_elem>\t%q0, %q1, %2"
[(set_attr "type" "mve_move")
])
@@ -1931,8 +1932,9 @@
(define_insn "@mve_vcmp<mve_cmp_op>q_n_f<mode>"
[
(set (match_operand:<MVE_VPRED> 0 "vpr_register_operand" "=Up")
- (MVE_FP_COMPARISONS:<MVE_VPRED> (match_operand:MVE_0 1 "s_register_operand" "w")
- (match_operand:<V_elem> 2 "s_register_operand" "r")))
+ (MVE_FP_COMPARISONS:<MVE_VPRED>
+ (match_operand:MVE_0 1 "s_register_operand" "w")
+ (vec_duplicate:MVE_0 (match_operand:<V_elem> 2 "s_register_operand" "r"))))
]
"TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
"vcmp.f%#<V_sz_elem> <mve_cmp_op>, %q1, %2"
@@ -2543,7 +2545,7 @@
VRMLALDAVHQ))
]
"TARGET_HAVE_MVE"
- "vrmlaldavh.<supf>32 %Q0, %R0, %q1, %q2"
+ "vrmlaldavh.<supf>32\t%Q0, %R0, %q1, %q2"
[(set_attr "type" "mve_move")
])
@@ -2649,7 +2651,7 @@
VRMLALDAVHAQ))
]
"TARGET_HAVE_MVE"
- "vrmlaldavha.<supf>32 %Q0, %R0, %q2, %q3"
+ "vrmlaldavha.<supf>32\t%Q0, %R0, %q2, %q3"
[(set_attr "type" "mve_move")
])
@@ -3046,7 +3048,7 @@
VDUPQ_M_N))
]
"TARGET_HAVE_MVE"
- "vpst\;vdupt.%#<V_sz_elem> %q0, %2"
+ "vpst\;vdupt.%#<V_sz_elem>\t%q0, %2"
[(set_attr "type" "mve_move")
(set_attr "length""8")])
@@ -3717,7 +3719,7 @@
VADDLVAQ_P))
]
"TARGET_HAVE_MVE"
- "vpst\;vaddlvat.<supf>32 %Q0, %R0, %q2"
+ "vpst\;vaddlvat.<supf>32\t%Q0, %R0, %q2"
[(set_attr "type" "mve_move")
(set_attr "length""8")])
;;
@@ -3991,7 +3993,7 @@
VDUPQ_M_N_F))
]
"TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
- "vpst\;vdupt.%#<V_sz_elem> %q0, %2"
+ "vpst\;vdupt.%#<V_sz_elem>\t%q0, %2"
[(set_attr "type" "mve_move")
(set_attr "length""8")])
@@ -4163,7 +4165,7 @@
VMLALDAVAQ))
]
"TARGET_HAVE_MVE"
- "vmlaldava.<supf>%#<V_sz_elem> %Q0, %R0, %q2, %q3"
+ "vmlaldava.<supf>%#<V_sz_elem>\t%Q0, %R0, %q2, %q3"
[(set_attr "type" "mve_move")
])
@@ -4179,7 +4181,7 @@
VMLALDAVAXQ_S))
]
"TARGET_HAVE_MVE"
- "vmlaldavax.s%#<V_sz_elem> %Q0, %R0, %q2, %q3"
+ "vmlaldavax.s%#<V_sz_elem>\t%Q0, %R0, %q2, %q3"
[(set_attr "type" "mve_move")
])
@@ -6126,7 +6128,7 @@
VMLALDAVAXQ_P))
]
"TARGET_HAVE_MVE"
- "vpst\;vmlaldavaxt.<supf>%#<V_sz_elem> %Q0, %R0, %q2, %q3"
+ "vpst\;vmlaldavaxt.<supf>%#<V_sz_elem>\t%Q0, %R0, %q2, %q3"
[(set_attr "type" "mve_move")
(set_attr "length""8")])
@@ -8928,7 +8930,7 @@
(match_operand:MVE_2 2 "s_register_operand" "w")))
]
"TARGET_HAVE_MVE"
- "vadd.i%#<V_sz_elem> %q0, %q1, %q2"
+ "vadd.i%#<V_sz_elem>\t%q0, %q1, %q2"
[(set_attr "type" "mve_move")
])
@@ -8942,7 +8944,7 @@
(match_operand:MVE_0 2 "s_register_operand" "w")))
]
"TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
- "vadd.f%#<V_sz_elem> %q0, %q1, %q2"
+ "vadd.f%#<V_sz_elem>\t%q0, %q1, %q2"
[(set_attr "type" "mve_move")
])
@@ -9043,7 +9045,7 @@
(minus:SI (match_dup 2)
(match_operand:SI 4 "immediate_operand" "i")))]
"TARGET_HAVE_MVE"
- "vddup.u%#<V_sz_elem> %q0, %1, %3")
+ "vddup.u%#<V_sz_elem>\t%q0, %1, %3")
;;
;; [vddupq_m_n_u])
@@ -9079,7 +9081,7 @@
(minus:SI (match_dup 3)
(match_operand:SI 6 "immediate_operand" "i")))]
"TARGET_HAVE_MVE"
- "vpst\;\tvddupt.u%#<V_sz_elem>\t%q0, %2, %4"
+ "vpst\;vddupt.u%#<V_sz_elem>\t%q0, %2, %4"
[(set_attr "length""8")])
;;
@@ -9195,7 +9197,7 @@
VDWDUPQ_M))
]
"TARGET_HAVE_MVE"
- "vpst\;\tvdwdupt.u%#<V_sz_elem>\t%q2, %3, %R4, %5"
+ "vpst\;vdwdupt.u%#<V_sz_elem>\t%q2, %3, %R4, %5"
[(set_attr "type" "mve_move")
(set_attr "length""8")])
diff --git a/gcc/config/arm/types.md b/gcc/config/arm/types.md
index 7d0504b..880353d 100644
--- a/gcc/config/arm/types.md
+++ b/gcc/config/arm/types.md
@@ -248,7 +248,8 @@
; wmmx_wunpckil
; wmmx_wxor
;
-; The classification below is for NEON instructions.
+; The classification below is for NEON instructions. If a new neon type is
+; added, please ensure this is added to the is_neon_type attribute below too.
;
; neon_add
; neon_add_q
@@ -483,6 +484,7 @@
; neon_fp_minmax_s_q
; neon_fp_minmax_d
; neon_fp_minmax_d_q
+; neon_fp_reduc_add_h
; neon_fp_reduc_add_s
; neon_fp_reduc_add_s_q
; neon_fp_reduc_add_d
@@ -1033,6 +1035,7 @@
neon_fp_minmax_d,\
neon_fp_minmax_d_q,\
\
+ neon_fp_reduc_add_h,\
neon_fp_reduc_add_s,\
neon_fp_reduc_add_s_q,\
neon_fp_reduc_add_d,\
@@ -1257,8 +1260,8 @@
neon_fp_compare_d, neon_fp_compare_d_q, neon_fp_minmax_s,\
neon_fp_minmax_s_q, neon_fp_minmax_d, neon_fp_minmax_d_q,\
neon_fp_neg_s, neon_fp_neg_s_q, neon_fp_neg_d, neon_fp_neg_d_q,\
- neon_fp_reduc_add_s, neon_fp_reduc_add_s_q, neon_fp_reduc_add_d,\
- neon_fp_reduc_add_d_q, neon_fp_reduc_minmax_s,
+ neon_fp_reduc_add_h, neon_fp_reduc_add_s, neon_fp_reduc_add_s_q,\
+ neon_fp_reduc_add_d, neon_fp_reduc_add_d_q, neon_fp_reduc_minmax_s,\
neon_fp_reduc_minmax_s_q, neon_fp_reduc_minmax_d,\
neon_fp_reduc_minmax_d_q,\
neon_fp_cvt_narrow_s_q, neon_fp_cvt_narrow_d_q,\
@@ -1281,6 +1284,7 @@
neon_fp_mla_d_q, neon_fp_mla_d_scalar_q, neon_fp_sqrt_s,\
neon_fp_sqrt_s_q, neon_fp_sqrt_d, neon_fp_sqrt_d_q,\
neon_fp_div_s, neon_fp_div_s_q, neon_fp_div_d, neon_fp_div_d_q, crypto_aese,\
+ neon_fcadd, neon_fcmla, \
crypto_aesmc, crypto_sha1_xor, crypto_sha1_fast, crypto_sha1_slow,\
crypto_sha256_fast, crypto_sha256_slow")
(const_string "yes")
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index d0f423c..932e4b7 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -105,9 +105,9 @@
case 8:
return "vmov%?.f32\t%0, %1\t%@ int";
case 9:
- return "vmsr%?\t P0, %1\t@ movhi";
+ return "vmsr%?\tp0, %1\t@ movhi";
case 10:
- return "vmrs%?\t %0, P0\t@ movhi";
+ return "vmrs%?\t%0, p0\t@ movhi";
default:
gcc_unreachable ();
}
@@ -209,9 +209,9 @@
case 8:
return "vmov%?.f32\t%0, %1\t%@ int";
case 9:
- return "vmsr%?\t P0, %1\t%@ movhi";
+ return "vmsr%?\tp0, %1\t%@ movhi";
case 10:
- return "vmrs%?\t%0, P0\t%@ movhi";
+ return "vmrs%?\t%0, p0\t%@ movhi";
default:
gcc_unreachable ();
}
diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h
index 4e77530..1d75c65 100644
--- a/gcc/config/bfin/bfin.h
+++ b/gcc/config/bfin/bfin.h
@@ -810,7 +810,6 @@ typedef struct {
subsequent accesses occur to other fields in the same word of the
structure, but to different bytes. */
#define SLOW_BYTE_ACCESS 0
-#define SLOW_SHORT_ACCESS 0
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields. */
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index ea8ca64..51e4695 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -1222,7 +1222,7 @@ bpf_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
return gen_rtx_REG (ops[0].mode, BPF_R0);
}
- else if (code == -1)
+ else if (code == -BPF_BUILTIN_PRESERVE_ACCESS_INDEX)
{
/* A resolved overloaded __builtin_preserve_access_index. */
tree arg = CALL_EXPR_ARG (exp, 0);
@@ -1249,16 +1249,19 @@ bpf_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
return expand_normal (arg);
}
- else if (code == -2)
+ else if (code == -BPF_BUILTIN_PRESERVE_FIELD_INFO)
{
/* A resolved overloaded __builtin_preserve_field_info. */
tree src = CALL_EXPR_ARG (exp, 0);
tree kind_tree = CALL_EXPR_ARG (exp, 1);
- unsigned HOST_WIDE_INT kind_val;
+ unsigned HOST_WIDE_INT kind_val = 0;
if (tree_fits_uhwi_p (kind_tree))
kind_val = tree_to_uhwi (kind_tree);
else
- error ("invalid argument to built-in function");
+ {
+ error ("invalid argument to built-in function");
+ return expand_normal (error_mark_node);
+ }
enum btf_core_reloc_kind kind = (enum btf_core_reloc_kind) kind_val;
@@ -1444,28 +1447,37 @@ bpf_core_get_index (const tree node)
__builtin_preserve_access_index. */
static tree
-bpf_core_newdecl (tree type, bool is_pai)
+bpf_core_newdecl (tree type, enum bpf_builtins which)
{
tree rettype;
char name[80];
static unsigned long pai_count = 0;
static unsigned long pfi_count = 0;
- if (is_pai)
+ switch (which)
{
- rettype = build_function_type_list (type, type, NULL);
- int len = snprintf (name, sizeof (name), "%s", "__builtin_pai_");
- len = snprintf (name + len, sizeof (name) - len, "%lu", pai_count++);
- }
- else
- {
- rettype = build_function_type_list (unsigned_type_node, type,
- unsigned_type_node, NULL);
- int len = snprintf (name, sizeof (name), "%s", "__builtin_pfi_");
- len = snprintf (name + len, sizeof (name) - len, "%lu", pfi_count++);
+ case BPF_BUILTIN_PRESERVE_ACCESS_INDEX:
+ {
+ rettype = build_function_type_list (type, type, NULL);
+ int len = snprintf (name, sizeof (name), "%s", "__builtin_pai_");
+ len = snprintf (name + len, sizeof (name) - len, "%lu", pai_count++);
+ }
+ break;
+
+ case BPF_BUILTIN_PRESERVE_FIELD_INFO:
+ {
+ rettype = build_function_type_list (unsigned_type_node, type,
+ unsigned_type_node, NULL);
+ int len = snprintf (name, sizeof (name), "%s", "__builtin_pfi_");
+ len = snprintf (name + len, sizeof (name) - len, "%lu", pfi_count++);
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
}
- return add_builtin_function_ext_scope (name, rettype, is_pai ? -1 : -2,
+ return add_builtin_function_ext_scope (name, rettype, -which,
BUILT_IN_MD, NULL, NULL_TREE);
}
@@ -1492,6 +1504,7 @@ bpf_core_is_maybe_aggregate_access (tree expr)
struct core_walk_data {
location_t loc;
+ enum bpf_builtins which;
tree arg;
};
@@ -1501,7 +1514,6 @@ static tree
bpf_core_walk (tree *tp, int *walk_subtrees, void *data)
{
struct core_walk_data *dat = (struct core_walk_data *) data;
- bool is_pai = dat->arg == NULL_TREE;
/* If this is a type, don't do anything. */
if (TYPE_P (*tp))
@@ -1510,19 +1522,21 @@ bpf_core_walk (tree *tp, int *walk_subtrees, void *data)
return NULL_TREE;
}
- /* Build a new function call to a resolved builtin for the desired operation.
- If this is a preserve_field_info call, pass along the argument to the
- resolved builtin call. */
- if (bpf_core_is_maybe_aggregate_access (*tp))
- {
- tree newdecl = bpf_core_newdecl (TREE_TYPE (*tp), is_pai);
- tree newcall;
- if (is_pai)
- newcall = build_call_expr_loc (dat->loc, newdecl, 1, *tp);
- else
- newcall = build_call_expr_loc (dat->loc, newdecl, 2, *tp, dat->arg);
+ /* Build a new function call to a type-resolved temporary builtin for the
+ desired operation, and pass along args as necessary. */
+ tree newdecl = bpf_core_newdecl (TREE_TYPE (*tp), dat->which);
- *tp = newcall;
+ if (dat->which == BPF_BUILTIN_PRESERVE_ACCESS_INDEX)
+ {
+ if (bpf_core_is_maybe_aggregate_access (*tp))
+ {
+ *tp = build_call_expr_loc (dat->loc, newdecl, 1, *tp);
+ *walk_subtrees = 0;
+ }
+ }
+ else
+ {
+ *tp = build_call_expr_loc (dat->loc, newdecl, 2, *tp, dat->arg);
*walk_subtrees = 0;
}
@@ -1572,32 +1586,26 @@ bpf_is_valid_preserve_field_info_arg (tree expr)
/* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN (see gccint manual section
Target Macros::Misc.).
- We use this for the __builtin_preserve_access_index builtin for CO-RE
- support.
+ Used for CO-RE support builtins such as __builtin_preserve_access_index
+ and __builtin_preserve_field_info.
FNDECL is the declaration of the builtin, and ARGLIST is the list of
- arguments passed to it, and is really a vec<tree,_> *.
-
- In this case, the 'operation' implemented by the builtin is a no-op;
- the builtin is just a marker. So, the result is simply the argument. */
+ arguments passed to it, and is really a vec<tree,_> *. */
static tree
bpf_resolve_overloaded_builtin (location_t loc, tree fndecl, void *arglist)
{
- bool is_pai = DECL_MD_FUNCTION_CODE (fndecl)
- == BPF_BUILTIN_PRESERVE_ACCESS_INDEX;
- bool is_pfi = DECL_MD_FUNCTION_CODE (fndecl)
- == BPF_BUILTIN_PRESERVE_FIELD_INFO;
+ enum bpf_builtins which = (enum bpf_builtins) DECL_MD_FUNCTION_CODE (fndecl);
- if (!is_pai && !is_pfi)
+ if (which < BPF_BUILTIN_PRESERVE_ACCESS_INDEX
+ || which >= BPF_BUILTIN_MAX)
return NULL_TREE;
- /* We only expect one argument, but it may be an arbitrarily-complicated
- statement-expression. */
vec<tree, va_gc> *params = static_cast<vec<tree, va_gc> *> (arglist);
unsigned n_params = params ? params->length() : 0;
- if ((is_pai && n_params != 1) || (is_pfi && n_params != 2))
+ if (!(which == BPF_BUILTIN_PRESERVE_ACCESS_INDEX && n_params == 1)
+ && n_params != 2)
{
error_at (loc, "wrong number of arguments");
return error_mark_node;
@@ -1605,12 +1613,15 @@ bpf_resolve_overloaded_builtin (location_t loc, tree fndecl, void *arglist)
tree param = (*params)[0];
- /* If not generating BPF_CORE information, preserve_access_index does nothing,
- and simply "resolves to" the argument. */
- if (!TARGET_BPF_CORE && is_pai)
+ /* If not generating BPF_CORE information, preserve_access_index does
+ nothing, and simply "resolves to" the argument. */
+ if (which == BPF_BUILTIN_PRESERVE_ACCESS_INDEX && !TARGET_BPF_CORE)
return param;
- if (is_pfi && !bpf_is_valid_preserve_field_info_arg (param))
+ /* For __builtin_preserve_field_info, enforce that the parameter is exactly a
+ field access and not a more complex expression. */
+ else if (which == BPF_BUILTIN_PRESERVE_FIELD_INFO
+ && !bpf_is_valid_preserve_field_info_arg (param))
{
error_at (EXPR_LOC_OR_LOC (param, loc),
"argument is not a field access");
@@ -1642,7 +1653,11 @@ bpf_resolve_overloaded_builtin (location_t loc, tree fndecl, void *arglist)
struct core_walk_data data;
data.loc = loc;
- data.arg = is_pai ? NULL_TREE : (*params)[1];
+ data.which = which;
+ if (which == BPF_BUILTIN_PRESERVE_ACCESS_INDEX)
+ data.arg = NULL_TREE;
+ else
+ data.arg = (*params)[1];
walk_tree (&param, bpf_core_walk, (void *) &data, NULL);
@@ -1731,7 +1746,6 @@ handle_attr_preserve (function *fn)
{
basic_block bb;
rtx_insn *insn;
- rtx_code_label *label;
FOR_EACH_BB_FN (bb, fn)
{
FOR_BB_INSNS (bb, insn)
@@ -1762,28 +1776,7 @@ handle_attr_preserve (function *fn)
}
if (is_attr_preserve_access (expr))
- {
- auto_vec<unsigned int, 16> accessors;
- tree container = bpf_core_compute (expr, &accessors);
- if (accessors.length () < 1)
- continue;
- accessors.reverse ();
-
- container = TREE_TYPE (container);
- const char * section_name;
- if (DECL_SECTION_NAME (fn->decl))
- section_name = DECL_SECTION_NAME (fn->decl);
- else
- section_name = ".text";
-
- label = gen_label_rtx ();
- LABEL_PRESERVE_P (label) = 1;
- emit_label (label);
-
- /* Add the CO-RE relocation information to the BTF container. */
- bpf_core_reloc_add (container, section_name, &accessors, label,
- BPF_RELO_FIELD_BYTE_OFFSET);
- }
+ maybe_make_core_relo (expr, BPF_RELO_FIELD_BYTE_OFFSET);
}
}
rtx_insn *seq = get_insns ();
diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
index a28021a..22a133f 100644
--- a/gcc/config/bpf/bpf.md
+++ b/gcc/config/bpf/bpf.md
@@ -341,6 +341,23 @@
"rsh<msuffix>\t%0,%2"
[(set_attr "type" "<mtype>")])
+;;;; Endianness conversion
+
+(define_mode_iterator BSM [HI SI DI])
+(define_mode_attr endmode [(HI "16") (SI "32") (DI "64")])
+
+(define_insn "bswap<BSM:mode>2"
+ [(set (match_operand:BSM 0 "register_operand" "=r")
+ (bswap:BSM (match_operand:BSM 1 "register_operand" " r")))]
+ ""
+{
+ if (TARGET_BIG_ENDIAN)
+ return "endle\t%0, <endmode>";
+ else
+ return "endbe\t%0, <endmode>";
+}
+ [(set_attr "type" "end")])
+
;;;; Conditional branches
;; The eBPF jump instructions use 64-bit arithmetic when evaluating
diff --git a/gcc/config/gcn/gcn-builtins.def b/gcc/config/gcn/gcn-builtins.def
index 2769190..f1cf30b 100644
--- a/gcc/config/gcn/gcn-builtins.def
+++ b/gcc/config/gcn/gcn-builtins.def
@@ -64,6 +64,21 @@ DEF_BUILTIN (FABSVF, 3 /*CODE_FOR_fabsvf */,
_A2 (GCN_BTI_V64SF, GCN_BTI_V64SF),
gcn_expand_builtin_1)
+DEF_BUILTIN (FABSV, 3 /*CODE_FOR_fabsv */,
+ "fabsv", B_INSN,
+ _A2 (GCN_BTI_V64DF, GCN_BTI_V64DF),
+ gcn_expand_builtin_1)
+
+DEF_BUILTIN (FLOORVF, 3 /*CODE_FOR_floorvf */,
+ "floorvf", B_INSN,
+ _A2 (GCN_BTI_V64SF, GCN_BTI_V64SF),
+ gcn_expand_builtin_1)
+
+DEF_BUILTIN (FLOORV, 3 /*CODE_FOR_floorv */,
+ "floorv", B_INSN,
+ _A2 (GCN_BTI_V64DF, GCN_BTI_V64DF),
+ gcn_expand_builtin_1)
+
DEF_BUILTIN (LDEXPVF, 3 /*CODE_FOR_ldexpvf */,
"ldexpvf", B_INSN,
_A3 (GCN_BTI_V64SF, GCN_BTI_V64SF, GCN_BTI_V64SI),
@@ -143,6 +158,14 @@ DEF_BUILTIN (ACC_SINGLE_COPY_END, -1, "single_copy_end", B_INSN,
DEF_BUILTIN (ACC_BARRIER, -1, "acc_barrier", B_INSN, _A1 (GCN_BTI_VOID),
gcn_expand_builtin_1)
+/* Kernel inputs. */
+
+DEF_BUILTIN (FIRST_CALL_THIS_THREAD_P, -1, "first_call_this_thread_p", B_INSN,
+ _A1 (GCN_BTI_BOOL), gcn_expand_builtin_1)
+DEF_BUILTIN (KERNARG_PTR, -1, "kernarg_ptr", B_INSN, _A1 (GCN_BTI_VOIDPTR),
+ gcn_expand_builtin_1)
+DEF_BUILTIN (GET_STACK_LIMIT, -1, "get_stack_limit", B_INSN,
+ _A1 (GCN_BTI_VOIDPTR), gcn_expand_builtin_1)
#undef _A1
#undef _A2
diff --git a/gcc/config/gcn/gcn-opts.h b/gcc/config/gcn/gcn-opts.h
index b62dfb4..b54eae7 100644
--- a/gcc/config/gcn/gcn-opts.h
+++ b/gcc/config/gcn/gcn-opts.h
@@ -27,6 +27,12 @@ enum processor_type
PROCESSOR_GFX90a
};
+#define TARGET_FIJI (gcn_arch == PROCESSOR_FIJI)
+#define TARGET_VEGA10 (gcn_arch == PROCESSOR_VEGA10)
+#define TARGET_VEGA20 (gcn_arch == PROCESSOR_VEGA20)
+#define TARGET_GFX908 (gcn_arch == PROCESSOR_GFX908)
+#define TARGET_GFX90a (gcn_arch == PROCESSOR_GFX90a)
+
/* Set in gcn_option_override. */
extern enum gcn_isa {
ISA_UNKNOWN,
diff --git a/gcc/config/gcn/gcn-valu.md b/gcc/config/gcn/gcn-valu.md
index 3b61951..9f43538 100644
--- a/gcc/config/gcn/gcn-valu.md
+++ b/gcc/config/gcn/gcn-valu.md
@@ -2549,13 +2549,21 @@
(UNSPEC_SIN "sin")
(UNSPEC_COS "cos")])
+(define_int_attr math_unop_insn
+ [(UNSPEC_FLOOR "floor")
+ (UNSPEC_CEIL "ceil")
+ (UNSPEC_EXP2 "exp")
+ (UNSPEC_LOG2 "log")
+ (UNSPEC_SIN "sin")
+ (UNSPEC_COS "cos")])
+
(define_insn "<math_unop><mode>2"
[(set (match_operand:FP 0 "register_operand" "= v")
(unspec:FP
[(match_operand:FP 1 "gcn_alu_operand" "vSvB")]
MATH_UNOP_1OR2REG))]
""
- "v_<math_unop>%i0\t%0, %1"
+ "v_<math_unop_insn>%i0\t%0, %1"
[(set_attr "type" "vop1")
(set_attr "length" "8")])
@@ -2565,7 +2573,7 @@
[(match_operand:V_FP 1 "gcn_alu_operand" "vSvB")]
MATH_UNOP_1OR2REG))]
""
- "v_<math_unop>%i0\t%0, %1"
+ "v_<math_unop_insn>%i0\t%0, %1"
[(set_attr "type" "vop1")
(set_attr "length" "8")])
@@ -2575,7 +2583,7 @@
[(match_operand:FP_1REG 1 "gcn_alu_operand" "vSvB")]
MATH_UNOP_1REG))]
"flag_unsafe_math_optimizations"
- "v_<math_unop>%i0\t%0, %1"
+ "v_<math_unop_insn>%i0\t%0, %1"
[(set_attr "type" "vop1")
(set_attr "length" "8")])
@@ -2585,7 +2593,7 @@
[(match_operand:V_FP_1REG 1 "gcn_alu_operand" "vSvB")]
MATH_UNOP_1REG))]
"flag_unsafe_math_optimizations"
- "v_<math_unop>%i0\t%0, %1"
+ "v_<math_unop_insn>%i0\t%0, %1"
[(set_attr "type" "vop1")
(set_attr "length" "8")])
@@ -2595,7 +2603,7 @@
[(match_operand:FP_1REG 1 "gcn_alu_operand" "vSvB")]
MATH_UNOP_TRIG))]
"flag_unsafe_math_optimizations"
- "v_<math_unop>%i0\t%0, %1"
+ "v_<math_unop_insn>%i0\t%0, %1"
[(set_attr "type" "vop1")
(set_attr "length" "8")])
@@ -2605,7 +2613,7 @@
[(match_operand:V_FP_1REG 1 "gcn_alu_operand" "vSvB")]
MATH_UNOP_TRIG))]
"flag_unsafe_math_optimizations"
- "v_<math_unop>%i0\t%0, %1"
+ "v_<math_unop_insn>%i0\t%0, %1"
[(set_attr "type" "vop1")
(set_attr "length" "8")])
diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc
index b9d9170..39e93ae 100644
--- a/gcc/config/gcn/gcn.cc
+++ b/gcc/config/gcn/gcn.cc
@@ -2985,7 +2985,7 @@ gcn_omp_device_kind_arch_isa (enum omp_device_kind_arch_isa trait,
case omp_device_arch:
return strcmp (name, "amdgcn") == 0 || strcmp (name, "gcn") == 0;
case omp_device_isa:
- if (strcmp (name, "fiji") == 0)
+ if (strcmp (name, "fiji") == 0 || strcmp (name, "gfx803") == 0)
return gcn_arch == PROCESSOR_FIJI;
if (strcmp (name, "gfx900") == 0)
return gcn_arch == PROCESSOR_VEGA10;
@@ -4058,15 +4058,15 @@ gcn_init_builtin_types (void)
(integer_type_node) */
, 64);
tree tmp = build_distinct_type_copy (intSI_type_node);
- TYPE_ADDR_SPACE (tmp) = ADDR_SPACE_FLAT;
+ TYPE_ADDR_SPACE (tmp) = ADDR_SPACE_DEFAULT;
siptr_type_node = build_pointer_type (tmp);
tmp = build_distinct_type_copy (float_type_node);
- TYPE_ADDR_SPACE (tmp) = ADDR_SPACE_FLAT;
+ TYPE_ADDR_SPACE (tmp) = ADDR_SPACE_DEFAULT;
sfptr_type_node = build_pointer_type (tmp);
tmp = build_distinct_type_copy (void_type_node);
- TYPE_ADDR_SPACE (tmp) = ADDR_SPACE_FLAT;
+ TYPE_ADDR_SPACE (tmp) = ADDR_SPACE_DEFAULT;
voidptr_type_node = build_pointer_type (tmp);
tmp = build_distinct_type_copy (void_type_node);
@@ -4329,6 +4329,39 @@ gcn_expand_builtin_1 (tree exp, rtx target, rtx /*subtarget */ ,
emit_insn (gen_absv64sf2 (target, arg));
return target;
}
+ case GCN_BUILTIN_FABSV:
+ {
+ if (ignore)
+ return target;
+ rtx arg = force_reg (V64DFmode,
+ expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX,
+ V64DFmode,
+ EXPAND_NORMAL));
+ emit_insn (gen_absv64df2 (target, arg));
+ return target;
+ }
+ case GCN_BUILTIN_FLOORVF:
+ {
+ if (ignore)
+ return target;
+ rtx arg = force_reg (V64SFmode,
+ expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX,
+ V64SFmode,
+ EXPAND_NORMAL));
+ emit_insn (gen_floorv64sf2 (target, arg));
+ return target;
+ }
+ case GCN_BUILTIN_FLOORV:
+ {
+ if (ignore)
+ return target;
+ rtx arg = force_reg (V64DFmode,
+ expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX,
+ V64DFmode,
+ EXPAND_NORMAL));
+ emit_insn (gen_floorv64df2 (target, arg));
+ return target;
+ }
case GCN_BUILTIN_LDEXPVF:
{
if (ignore)
@@ -4350,7 +4383,7 @@ gcn_expand_builtin_1 (tree exp, rtx target, rtx /*subtarget */ ,
return target;
rtx arg1 = force_reg (V64DFmode,
expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX,
- V64SFmode,
+ V64DFmode,
EXPAND_NORMAL));
rtx arg2 = force_reg (V64SImode,
expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX,
@@ -4460,6 +4493,88 @@ gcn_expand_builtin_1 (tree exp, rtx target, rtx /*subtarget */ ,
emit_insn (gen_gcn_wavefront_barrier ());
return target;
+ case GCN_BUILTIN_GET_STACK_LIMIT:
+ {
+ /* stackbase = (stack_segment_decr & 0x0000ffffffffffff)
+ + stack_wave_offset);
+ seg_size = dispatch_ptr->private_segment_size;
+ stacklimit = stackbase + seg_size*64;
+ with segsize = *(uint32_t *) ((char *) dispatch_ptr
+ + 6*sizeof(int16_t) + 3*sizeof(int32_t));
+ cf. struct hsa_kernel_dispatch_packet_s in the HSA doc. */
+ rtx ptr;
+ if (cfun->machine->args.reg[DISPATCH_PTR_ARG] >= 0
+ && cfun->machine->args.reg[PRIVATE_SEGMENT_BUFFER_ARG] >= 0)
+ {
+ rtx size_rtx = gen_rtx_REG (DImode,
+ cfun->machine->args.reg[DISPATCH_PTR_ARG]);
+ size_rtx = gen_rtx_MEM (SImode,
+ gen_rtx_PLUS (DImode, size_rtx,
+ GEN_INT (6*2 + 3*4)));
+ size_rtx = gen_rtx_MULT (SImode, size_rtx, GEN_INT (64));
+
+ ptr = gen_rtx_REG (DImode,
+ cfun->machine->args.reg[PRIVATE_SEGMENT_BUFFER_ARG]);
+ ptr = gen_rtx_AND (DImode, ptr, GEN_INT (0x0000ffffffffffff));
+ ptr = gen_rtx_PLUS (DImode, ptr, size_rtx);
+ if (cfun->machine->args.reg[PRIVATE_SEGMENT_WAVE_OFFSET_ARG] >= 0)
+ {
+ rtx off;
+ off = gen_rtx_REG (SImode,
+ cfun->machine->args.reg[PRIVATE_SEGMENT_WAVE_OFFSET_ARG]);
+ ptr = gen_rtx_PLUS (DImode, ptr, off);
+ }
+ }
+ else
+ {
+ ptr = gen_reg_rtx (DImode);
+ emit_move_insn (ptr, const0_rtx);
+ }
+ return ptr;
+ }
+ case GCN_BUILTIN_KERNARG_PTR:
+ {
+ rtx ptr;
+ if (cfun->machine->args.reg[KERNARG_SEGMENT_PTR_ARG] >= 0)
+ ptr = gen_rtx_REG (DImode,
+ cfun->machine->args.reg[KERNARG_SEGMENT_PTR_ARG]);
+ else
+ {
+ ptr = gen_reg_rtx (DImode);
+ emit_move_insn (ptr, const0_rtx);
+ }
+ return ptr;
+ }
+ case GCN_BUILTIN_FIRST_CALL_THIS_THREAD_P:
+ {
+ /* Stash a marker in the unused upper 16 bits of s[0:1] to indicate
+ whether it was the first call. */
+ rtx result = gen_reg_rtx (BImode);
+ emit_move_insn (result, const0_rtx);
+ if (cfun->machine->args.reg[PRIVATE_SEGMENT_BUFFER_ARG] >= 0)
+ {
+ rtx not_first = gen_label_rtx ();
+ rtx reg = gen_rtx_REG (DImode,
+ cfun->machine->args.reg[PRIVATE_SEGMENT_BUFFER_ARG]);
+ reg = gcn_operand_part (DImode, reg, 1);
+ rtx cmp = force_reg (SImode,
+ gen_rtx_LSHIFTRT (SImode, reg, GEN_INT (16)));
+ emit_insn (gen_cstoresi4 (result, gen_rtx_NE (BImode, cmp,
+ GEN_INT(12345)),
+ cmp, GEN_INT(12345)));
+ emit_jump_insn (gen_cjump (not_first, gen_rtx_EQ (BImode, result,
+ const0_rtx),
+ result));
+ emit_move_insn (reg,
+ force_reg (SImode,
+ gen_rtx_IOR (SImode,
+ gen_rtx_AND (SImode, reg, GEN_INT (0x0000ffff)),
+ GEN_INT (12345L << 16))));
+ emit_insn (gen_rtx_USE (VOIDmode, reg));
+ emit_label (not_first);
+ }
+ return result;
+ }
default:
gcc_unreachable ();
}
@@ -4927,7 +5042,6 @@ gcn_expand_reduc_scalar (machine_mode mode, rtx src, int unspec)
machine_mode scalar_mode = GET_MODE_INNER (mode);
int vf = GET_MODE_NUNITS (mode);
bool use_moves = (((unspec == UNSPEC_SMIN_DPP_SHR
- || unspec == UNSPEC_SMIN_DPP_SHR
|| unspec == UNSPEC_SMAX_DPP_SHR
|| unspec == UNSPEC_UMIN_DPP_SHR
|| unspec == UNSPEC_UMAX_DPP_SHR)
@@ -4936,7 +5050,6 @@ gcn_expand_reduc_scalar (machine_mode mode, rtx src, int unspec)
|| (unspec == UNSPEC_PLUS_DPP_SHR
&& scalar_mode == DFmode));
rtx_code code = (unspec == UNSPEC_SMIN_DPP_SHR ? SMIN
- : unspec == UNSPEC_SMIN_DPP_SHR ? SMIN
: unspec == UNSPEC_SMAX_DPP_SHR ? SMAX
: unspec == UNSPEC_UMIN_DPP_SHR ? UMIN
: unspec == UNSPEC_UMAX_DPP_SHR ? UMAX
@@ -5030,7 +5143,8 @@ static int
gcn_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *ARG_UNUSED (node),
struct cgraph_simd_clone *clonei,
tree ARG_UNUSED (base_type),
- int ARG_UNUSED (num))
+ int ARG_UNUSED (num),
+ bool explicit_p)
{
if (known_eq (clonei->simdlen, 0U))
clonei->simdlen = 64;
@@ -5038,9 +5152,10 @@ gcn_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *ARG_UNUSED (node
{
/* Note that x86 has a similar message that is likely to trigger on
sizes that are OK for gcn; the user can't win. */
- warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
- "unsupported simdlen %wd (amdgcn)",
- clonei->simdlen.to_constant ());
+ if (explicit_p)
+ warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+ "unsupported simdlen %wd (amdgcn)",
+ clonei->simdlen.to_constant ());
return 0;
}
@@ -5669,7 +5784,9 @@ gcn_oacc_dim_size (int dim)
cfun->machine->args.
reg[DISPATCH_PTR_ARG]),
GEN_INT (offset[dim]));
- return gen_rtx_MEM (SImode, addr);
+ rtx mem = gen_rtx_MEM (SImode, addr);
+ set_mem_addr_space (mem, ADDR_SPACE_SCALAR_FLAT);
+ return mem;
}
/* Helper function for oacc_dim_pos instruction.
diff --git a/gcc/config/gcn/gcn.h b/gcc/config/gcn/gcn.h
index 38f7212..1cc5981 100644
--- a/gcc/config/gcn/gcn.h
+++ b/gcc/config/gcn/gcn.h
@@ -16,20 +16,32 @@
#include "config/gcn/gcn-opts.h"
-#define TARGET_CPU_CPP_BUILTINS() \
- do \
- { \
- builtin_define ("__AMDGCN__"); \
- if (TARGET_GCN3) \
- builtin_define ("__GCN3__"); \
- else if (TARGET_GCN5) \
- builtin_define ("__GCN5__"); \
- else if (TARGET_CDNA1) \
- builtin_define ("__CDNA1__"); \
- else if (TARGET_CDNA2) \
- builtin_define ("__CDNA2__"); \
- } \
- while(0)
+#define TARGET_CPU_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__AMDGCN__"); \
+ if (TARGET_GCN3) \
+ builtin_define ("__GCN3__"); \
+ else if (TARGET_GCN5) \
+ builtin_define ("__GCN5__"); \
+ else if (TARGET_CDNA1) \
+ builtin_define ("__CDNA1__"); \
+ else if (TARGET_CDNA2) \
+ builtin_define ("__CDNA2__"); \
+ if (TARGET_FIJI) \
+ { \
+ builtin_define ("__fiji__"); \
+ builtin_define ("__gfx803__"); \
+ } \
+ else if (TARGET_VEGA10) \
+ builtin_define ("__gfx900__"); \
+ else if (TARGET_VEGA20) \
+ builtin_define ("__gfx906__"); \
+ else if (TARGET_GFX908) \
+ builtin_define ("__gfx908__"); \
+ else if (TARGET_GFX90a) \
+ builtin_define ("__gfx90a__"); \
+ } while (0)
/* Support for a compile-time default architecture and tuning.
The rules are:
diff --git a/gcc/config/gcn/gcn.md b/gcc/config/gcn/gcn.md
index 987b763..92e9892 100644
--- a/gcc/config/gcn/gcn.md
+++ b/gcc/config/gcn/gcn.md
@@ -692,7 +692,7 @@
;; {{{ Prologue/Epilogue
(define_insn "prologue_use"
- [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
+ [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_PROLOGUE_USE)]
""
""
[(set_attr "length" "0")])
diff --git a/gcc/config/gcn/t-omp-device b/gcc/config/gcn/t-omp-device
index 27d36db..538624f 100644
--- a/gcc/config/gcn/t-omp-device
+++ b/gcc/config/gcn/t-omp-device
@@ -1,4 +1,4 @@
omp-device-properties-gcn: $(srcdir)/config/gcn/gcn.cc
echo kind: gpu > $@
echo arch: amdgcn gcn >> $@
- echo isa: fiji gfx900 gfx906 gfx908 gfx90a >> $@
+ echo isa: fiji gfx803 gfx900 gfx906 gfx908 gfx90a >> $@
diff --git a/gcc/config/i386/intelmic-offload.h b/gcc/config/i386/amxfp16intrin.h
index 42ce0d8..6a11474 100644
--- a/gcc/config/i386/intelmic-offload.h
+++ b/gcc/config/i386/amxfp16intrin.h
@@ -1,6 +1,4 @@
-/* Support for Intel MIC offloading.
-
- Copyright (C) 2014-2022 Free Software Foundation, Inc.
+/* Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of GCC.
@@ -23,13 +21,26 @@
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
-#ifndef INTELMIC_OFFLOAD_H
-#define INTELMIC_OFFLOAD_H
+#if !defined _IMMINTRIN_H_INCLUDED
+#error "Never use <amxfp16intrin.h> directly; include <immintrin.h> instead."
+#endif
-/* Support for OpenACC acc_on_device. */
+#ifndef _AMXFP16INTRIN_H_INCLUDED
+#define _AMXFP16INTRIN_H_INCLUDED
-#include "gomp-constants.h"
+#if defined(__x86_64__)
+#define _tile_dpfp16ps_internal(dst,src1,src2) \
+ __asm__ volatile \
+ ("{tdpfp16ps\t%%tmm"#src2", %%tmm"#src1", %%tmm"#dst"|tdpfp16ps\t%%tmm"#dst", %%tmm"#src1", %%tmm"#src2"}" ::)
-#define ACCEL_COMPILER_acc_device GOMP_DEVICE_INTEL_MIC
+#define _tile_dpfp16ps(dst,src1,src2) \
+ _tile_dpfp16ps_internal (dst,src1,src2)
#endif
+
+#ifdef __DISABLE_AMX_FP16__
+#undef __DISABLE_AMX_FP16__
+#pragma GCC pop_options
+#endif /* __DISABLE_AMX_FP16__ */
+
+#endif /* _AMXFP16INTRIN_H_INCLUDED */
diff --git a/gcc/config/i386/avx512bf16intrin.h b/gcc/config/i386/avx512bf16intrin.h
index ea1d012..75378af 100644
--- a/gcc/config/i386/avx512bf16intrin.h
+++ b/gcc/config/i386/avx512bf16intrin.h
@@ -46,9 +46,7 @@ extern __inline float
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_cvtsbh_ss (__bf16 __A)
{
- union{ float a; unsigned int b;} __tmp;
- __tmp.b = ((unsigned int)(__A)) << 16;
- return __tmp.a;
+ return __builtin_ia32_cvtbf2sf (__A);
}
/* vcvtne2ps2bf16 */
diff --git a/gcc/config/i386/avx512fp16intrin.h b/gcc/config/i386/avx512fp16intrin.h
index 75f7475..70f2f2b 100644
--- a/gcc/config/i386/avx512fp16intrin.h
+++ b/gcc/config/i386/avx512fp16intrin.h
@@ -272,10 +272,10 @@ _mm512_castph512_ph128 (__m512h __A)
{
union
{
- __m128h a[4];
- __m512h v;
- } u = { .v = __A };
- return u.a[0];
+ __m128h __a[4];
+ __m512h __v;
+ } __u = { .__v = __A };
+ return __u.__a[0];
}
extern __inline __m256h
@@ -284,10 +284,10 @@ _mm512_castph512_ph256 (__m512h __A)
{
union
{
- __m256h a[2];
- __m512h v;
- } u = { .v = __A };
- return u.a[0];
+ __m256h __a[2];
+ __m512h __v;
+ } __u = { .__v = __A };
+ return __u.__a[0];
}
extern __inline __m512h
@@ -296,11 +296,11 @@ _mm512_castph128_ph512 (__m128h __A)
{
union
{
- __m128h a[4];
- __m512h v;
- } u;
- u.a[0] = __A;
- return u.v;
+ __m128h __a[4];
+ __m512h __v;
+ } __u;
+ __u.__a[0] = __A;
+ return __u.__v;
}
extern __inline __m512h
@@ -309,11 +309,11 @@ _mm512_castph256_ph512 (__m256h __A)
{
union
{
- __m256h a[2];
- __m512h v;
- } u;
- u.a[0] = __A;
- return u.v;
+ __m256h __a[2];
+ __m512h __v;
+ } __u;
+ __u.__a[0] = __A;
+ return __u.__v;
}
extern __inline __m512h
@@ -7156,11 +7156,11 @@ _mm512_set1_pch (_Float16 _Complex __A)
{
union
{
- _Float16 _Complex a;
- float b;
- } u = { .a = __A};
+ _Float16 _Complex __a;
+ float __b;
+ } __u = { .__a = __A};
- return (__m512h) _mm512_set1_ps (u.b);
+ return (__m512h) _mm512_set1_ps (__u.__b);
}
// intrinsics below are alias for f*mul_*ch
diff --git a/gcc/config/i386/avx512fp16vlintrin.h b/gcc/config/i386/avx512fp16vlintrin.h
index 0794498..2783971 100644
--- a/gcc/config/i386/avx512fp16vlintrin.h
+++ b/gcc/config/i386/avx512fp16vlintrin.h
@@ -124,10 +124,10 @@ _mm256_castph256_ph128 (__m256h __A)
{
union
{
- __m128h a[2];
- __m256h v;
- } u = { .v = __A };
- return u.a[0];
+ __m128h __a[2];
+ __m256h __v;
+ } __u = { .__v = __A };
+ return __u.__a[0];
}
extern __inline __m256h
@@ -136,11 +136,11 @@ _mm256_castph128_ph256 (__m128h __A)
{
union
{
- __m128h a[2];
- __m256h v;
- } u;
- u.a[0] = __A;
- return u.v;
+ __m128h __a[2];
+ __m256h __v;
+ } __u;
+ __u.__a[0] = __A;
+ return __u.__v;
}
extern __inline __m256h
@@ -3317,11 +3317,11 @@ _mm256_set1_pch (_Float16 _Complex __A)
{
union
{
- _Float16 _Complex a;
- float b;
- } u = { .a = __A };
+ _Float16 _Complex __a;
+ float __b;
+ } __u = { .__a = __A };
- return (__m256h) _mm256_set1_ps (u.b);
+ return (__m256h) _mm256_set1_ps (__u.__b);
}
extern __inline __m128h
@@ -3330,11 +3330,11 @@ _mm_set1_pch (_Float16 _Complex __A)
{
union
{
- _Float16 _Complex a;
- float b;
- } u = { .a = __A };
+ _Float16 _Complex __a;
+ float __b;
+ } __u = { .__a = __A };
- return (__m128h) _mm_set1_ps (u.b);
+ return (__m128h) _mm_set1_ps (__u.__b);
}
// intrinsics below are alias for f*mul_*ch
diff --git a/gcc/config/i386/cmpccxaddintrin.h b/gcc/config/i386/cmpccxaddintrin.h
new file mode 100644
index 0000000..1afa03b
--- /dev/null
+++ b/gcc/config/i386/cmpccxaddintrin.h
@@ -0,0 +1,89 @@
+/* Copyright (C) 2012-2021 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _X86GPRINTRIN_H_INCLUDED
+#error "Never use <cmpccxaddintrin.h> directly; include <x86gprintrin.h> instead."
+#endif
+
+#ifndef _CMPCCXADDINTRIN_H_INCLUDED
+#define _CMPCCXADDINTRIN_H_INCLUDED
+
+#ifdef __x86_64__
+
+#ifndef __CMPCCXADD__
+#pragma GCC push_options
+#pragma GCC target("cmpccxadd")
+#define __DISABLE_CMPCCXADD__
+#endif /* __CMPCCXADD__ */
+
+typedef enum {
+ _CMPCCX_O, /* Overflow. */
+ _CMPCCX_NO, /* No overflow. */
+ _CMPCCX_B, /* Below. */
+ _CMPCCX_NB, /* Not below. */
+ _CMPCCX_Z, /* Zero. */
+ _CMPCCX_NZ, /* Not zero. */
+ _CMPCCX_BE, /* Below or equal. */
+ _CMPCCX_NBE, /* Neither below nor equal. */
+ _CMPCCX_S, /* Sign. */
+ _CMPCCX_NS, /* No sign. */
+ _CMPCCX_P, /* Parity. */
+ _CMPCCX_NP, /* No parity. */
+ _CMPCCX_L, /* Less. */
+ _CMPCCX_NL, /* Not less. */
+ _CMPCCX_LE, /* Less or equal. */
+ _CMPCCX_NLE, /* Neither less nor equal. */
+} _CMPCCX_ENUM;
+
+#ifdef __OPTIMIZE__
+extern __inline int
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__cmpccxadd_epi32 (int *__A, int __B, int __C, const _CMPCCX_ENUM __D)
+{
+ return __builtin_ia32_cmpccxadd (__A, __B, __C, __D);
+}
+
+extern __inline long long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__cmpccxadd_epi64 (long long *__A, long long __B, long long __C,
+ const _CMPCCX_ENUM __D)
+{
+ return __builtin_ia32_cmpccxadd64 (__A, __B, __C, __D);
+}
+#else
+#define __cmpccxadd_epi32(A,B,C,D) \
+ __builtin_ia32_cmpccxadd ((int *) (A), (int) (B), (int) (C), \
+ (_CMPCCX_ENUM) (D))
+#define __cmpccxadd_epi64(A,B,C,D) \
+ __builtin_ia32_cmpccxadd64 ((long long *) (A), (long long) (B), \
+ (long long) (C), (_CMPCCX_ENUM) (D))
+#endif
+
+#ifdef __DISABLE_CMPCCXADD__
+#undef __DISABLE_CMPCCXADD__
+#pragma GCC pop_options
+#endif /* __DISABLE_CMPCCXADD__ */
+
+#endif
+
+#endif /* _CMPCCXADDINTRIN_H_INCLUDED */
diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h
index 18bbc0c..a33abf3 100644
--- a/gcc/config/i386/cpuid.h
+++ b/gcc/config/i386/cpuid.h
@@ -25,8 +25,11 @@
#define _CPUID_H_INCLUDED
/* %eax */
+#define bit_RAOINT (1 << 3)
#define bit_AVXVNNI (1 << 4)
#define bit_AVX512BF16 (1 << 5)
+#define bit_CMPCCXADD (1 << 7)
+#define bit_AMX_FP16 (1 << 21)
#define bit_HRESET (1 << 22)
#define bit_AVXIFMA (1 << 23)
@@ -52,6 +55,7 @@
#define bit_AVXVNNIINT8 (1 << 4)
#define bit_AVXNECONVERT (1 << 5)
#define bit_CMPXCHG8B (1 << 8)
+#define bit_PREFETCHI (1 << 14)
#define bit_CMOV (1 << 15)
#define bit_MMX (1 << 23)
#define bit_FXSAVE (1 << 24)
diff --git a/gcc/config/i386/driver-i386.cc b/gcc/config/i386/driver-i386.cc
index aa16895..95c16c2 100644
--- a/gcc/config/i386/driver-i386.cc
+++ b/gcc/config/i386/driver-i386.cc
@@ -591,8 +591,17 @@ const char *host_detect_local_cpu (int argc, const char **argv)
/* This is unknown family 0x6 CPU. */
if (has_feature (FEATURE_AVX))
{
+ /* Assume Grand Ridge. */
+ if (has_feature (FEATURE_RAOINT))
+ cpu = "grandridge";
+ /* Assume Granite Rapids. */
+ else if (has_feature (FEATURE_AMX_FP16))
+ cpu = "graniterapids";
+ /* Assume Sierra Forest. */
+ else if (has_feature (FEATURE_AVXVNNIINT8))
+ cpu = "sierraforest";
/* Assume Tiger Lake */
- if (has_feature (FEATURE_AVX512VP2INTERSECT))
+ else if (has_feature (FEATURE_AVX512VP2INTERSECT))
cpu = "tigerlake";
/* Assume Sapphire Rapids. */
else if (has_feature (FEATURE_TSXLDTRK))
diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def
index abbb50b..65fe070 100644
--- a/gcc/config/i386/i386-builtin-types.def
+++ b/gcc/config/i386/i386-builtin-types.def
@@ -1281,6 +1281,7 @@ DEF_FUNCTION_TYPE (V4SI, V4SI, V4SI, UHI)
DEF_FUNCTION_TYPE (V8SI, V8SI, V8SI, UHI)
# BF16 builtins
+DEF_FUNCTION_TYPE (FLOAT, BFLOAT16)
DEF_FUNCTION_TYPE (V32BF, V16SF, V16SF)
DEF_FUNCTION_TYPE (V32BF, V16SF, V16SF, V32BF, USI)
DEF_FUNCTION_TYPE (V32BF, V16SF, V16SF, USI)
@@ -1407,3 +1408,11 @@ DEF_FUNCTION_TYPE (V4SF, PCV8HF)
DEF_FUNCTION_TYPE (V8SF, PCV16HF)
DEF_FUNCTION_TYPE (V4SF, PCV8BF)
DEF_FUNCTION_TYPE (V8SF, PCV16BF)
+
+# CMPccXADD builtins
+DEF_FUNCTION_TYPE (INT, PINT, INT, INT, INT)
+DEF_FUNCTION_TYPE (LONGLONG, PLONGLONG, LONGLONG, LONGLONG, INT)
+
+# PREFETCHI builtins
+DEF_FUNCTION_TYPE (VOID, PCVOID, INT)
+DEF_FUNCTION_TYPE (VOID, PCVOID, INT, INT, INT)
diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def
index 9345b8c..d85b175 100644
--- a/gcc/config/i386/i386-builtin.def
+++ b/gcc/config/i386/i386-builtin.def
@@ -288,6 +288,10 @@ BDESC (0, OPTION_MASK_ISA2_AVXNECONVERT, CODE_FOR_vcvtneobf162ps_v16bf, "__built
BDESC (0, OPTION_MASK_ISA2_AVXNECONVERT, CODE_FOR_vcvtneoph2ps_v8hf, "__builtin_ia32_vcvtneoph2ps128", IX86_BUILTIN_VCVTNEOPH2PS128, UNKNOWN, (int) V4SF_FTYPE_PCV8HF)
BDESC (0, OPTION_MASK_ISA2_AVXNECONVERT, CODE_FOR_vcvtneoph2ps_v16hf, "__builtin_ia32_vcvtneoph2ps256", IX86_BUILTIN_VCVTNEOPH2PS256, UNKNOWN, (int) V8SF_FTYPE_PCV16HF)
+/* CMPCCXADD */
+BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_CMPCCXADD, CODE_FOR_cmpccxadd_si, "__builtin_ia32_cmpccxadd", IX86_BUILTIN_CMPCCXADD, UNKNOWN, (int) INT_FTYPE_PINT_INT_INT_INT)
+BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_CMPCCXADD, CODE_FOR_cmpccxadd_di, "__builtin_ia32_cmpccxadd64", IX86_BUILTIN_CMPCCXADD64, UNKNOWN, (int) LONGLONG_FTYPE_PLONGLONG_LONGLONG_LONGLONG_INT)
+
/* AVX512BW */
BDESC (OPTION_MASK_ISA_AVX512BW, 0, CODE_FOR_avx512bw_loadv32hi_mask, "__builtin_ia32_loaddquhi512_mask", IX86_BUILTIN_LOADDQUHI512_MASK, UNKNOWN, (int) V32HI_FTYPE_PCSHORT_V32HI_USI)
BDESC (OPTION_MASK_ISA_AVX512BW, 0, CODE_FOR_avx512bw_loadv64qi_mask, "__builtin_ia32_loaddquqi512_mask", IX86_BUILTIN_LOADDQUQI512_MASK, UNKNOWN, (int) V64QI_FTYPE_PCCHAR_V64QI_UDI)
@@ -411,6 +415,16 @@ BDESC (OPTION_MASK_ISA_AVX512BW, 0, CODE_FOR_avx512bw_truncatev32hiv32qi2_mask_s
BDESC (0, OPTION_MASK_ISA2_AVX512FP16, CODE_FOR_avx512f_loadhf_mask, "__builtin_ia32_loadsh_mask", IX86_BUILTIN_LOADSH_MASK, UNKNOWN, (int) V8HF_FTYPE_PCFLOAT16_V8HF_UQI)
BDESC (0, OPTION_MASK_ISA2_AVX512FP16, CODE_FOR_avx512f_storehf_mask, "__builtin_ia32_storesh_mask", IX86_BUILTIN_STORESH_MASK, UNKNOWN, (int) VOID_FTYPE_PCFLOAT16_V8HF_UQI)
+/* RAOINT */
+BDESC (0, OPTION_MASK_ISA2_RAOINT, CODE_FOR_rao_aaddsi, "__builtin_ia32_aadd32", IX86_BUILTIN_AADD32, UNKNOWN, (int) VOID_FTYPE_PINT_INT)
+BDESC (0, OPTION_MASK_ISA2_RAOINT, CODE_FOR_rao_aandsi, "__builtin_ia32_aand32", IX86_BUILTIN_AAND32, UNKNOWN, (int) VOID_FTYPE_PINT_INT)
+BDESC (0, OPTION_MASK_ISA2_RAOINT, CODE_FOR_rao_aorsi, "__builtin_ia32_aor32", IX86_BUILTIN_AOR32, UNKNOWN, (int) VOID_FTYPE_PINT_INT)
+BDESC (0, OPTION_MASK_ISA2_RAOINT, CODE_FOR_rao_axorsi, "__builtin_ia32_axor32", IX86_BUILTIN_AXOR32, UNKNOWN, (int) VOID_FTYPE_PINT_INT)
+BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_RAOINT, CODE_FOR_rao_aadddi, "__builtin_ia32_aadd64", IX86_BUILTIN_AADD64, UNKNOWN, (int) VOID_FTYPE_PLONGLONG_LONGLONG)
+BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_RAOINT, CODE_FOR_rao_aanddi, "__builtin_ia32_aand64", IX86_BUILTIN_AAND64, UNKNOWN, (int) VOID_FTYPE_PLONGLONG_LONGLONG)
+BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_RAOINT, CODE_FOR_rao_aordi, "__builtin_ia32_aor64", IX86_BUILTIN_AOR64, UNKNOWN, (int) VOID_FTYPE_PLONGLONG_LONGLONG)
+BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_RAOINT, CODE_FOR_rao_axordi, "__builtin_ia32_axor64", IX86_BUILTIN_AXOR64, UNKNOWN, (int) VOID_FTYPE_PLONGLONG_LONGLONG)
+
/* RDPKRU and WRPKRU. */
BDESC (OPTION_MASK_ISA_PKU, 0, CODE_FOR_rdpkru, "__builtin_ia32_rdpkru", IX86_BUILTIN_RDPKRU, UNKNOWN, (int) UNSIGNED_FTYPE_VOID)
BDESC (OPTION_MASK_ISA_PKU, 0, CODE_FOR_wrpkru, "__builtin_ia32_wrpkru", IX86_BUILTIN_WRPKRU, UNKNOWN, (int) VOID_FTYPE_UNSIGNED)
@@ -483,6 +497,10 @@ BDESC (0, OPTION_MASK_ISA2_WIDEKL, CODE_FOR_nothing, "__builtin_ia32_aesdecwide2
BDESC (0, OPTION_MASK_ISA2_WIDEKL, CODE_FOR_nothing, "__builtin_ia32_aesencwide128kl_u8", IX86_BUILTIN_AESENCWIDE128KLU8, UNKNOWN, (int) UINT8_FTYPE_PV2DI_PCV2DI_PCVOID)
BDESC (0, OPTION_MASK_ISA2_WIDEKL, CODE_FOR_nothing, "__builtin_ia32_aesencwide256kl_u8", IX86_BUILTIN_AESENCWIDE256KLU8, UNKNOWN, (int) UINT8_FTYPE_PV2DI_PCV2DI_PCVOID)
+/* PREFETCHI */
+BDESC (0, OPTION_MASK_ISA2_PREFETCHI, CODE_FOR_prefetchi, "__builtin_ia32_prefetchi", IX86_BUILTIN_PREFETCHI, UNKNOWN, (int) VOID_FTYPE_PCVOID_INT)
+BDESC (0, 0, CODE_FOR_nothing, "__builtin_ia32_prefetch", IX86_BUILTIN_PREFETCH, UNKNOWN, (int) VOID_FTYPE_PCVOID_INT_INT_INT)
+
BDESC_END (SPECIAL_ARGS, PURE_ARGS)
/* AVX */
@@ -2820,6 +2838,8 @@ BDESC (0, OPTION_MASK_ISA2_AVX512BF16, CODE_FOR_avx512f_dpbf16ps_v8sf_maskz, "__
BDESC (0, OPTION_MASK_ISA2_AVX512BF16, CODE_FOR_avx512f_dpbf16ps_v4sf, "__builtin_ia32_dpbf16ps_v4sf", IX86_BUILTIN_DPBF16PS_V4SF, UNKNOWN, (int) V4SF_FTYPE_V4SF_V8BF_V8BF)
BDESC (0, OPTION_MASK_ISA2_AVX512BF16, CODE_FOR_avx512f_dpbf16ps_v4sf_mask, "__builtin_ia32_dpbf16ps_v4sf_mask", IX86_BUILTIN_DPBF16PS_V4SF_MASK, UNKNOWN, (int) V4SF_FTYPE_V4SF_V8BF_V8BF_UQI)
BDESC (0, OPTION_MASK_ISA2_AVX512BF16, CODE_FOR_avx512f_dpbf16ps_v4sf_maskz, "__builtin_ia32_dpbf16ps_v4sf_maskz", IX86_BUILTIN_DPBF16PS_V4SF_MASKZ, UNKNOWN, (int) V4SF_FTYPE_V4SF_V8BF_V8BF_UQI)
+BDESC (OPTION_MASK_ISA_SSE2, 0, CODE_FOR_extendbfsf2_1, "__builtin_ia32_cvtbf2sf", IX86_BUILTIN_CVTBF2SF, UNKNOWN, (int) FLOAT_FTYPE_BFLOAT16)
+
/* AVX512FP16. */
BDESC (OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_AVX512FP16, CODE_FOR_addv8hf3_mask, "__builtin_ia32_addph128_mask", IX86_BUILTIN_ADDPH128_MASK, UNKNOWN, (int) V8HF_FTYPE_V8HF_V8HF_V8HF_UQI)
diff --git a/gcc/config/i386/i386-builtins.cc b/gcc/config/i386/i386-builtins.cc
index 9412cf1..01192ef 100644
--- a/gcc/config/i386/i386-builtins.cc
+++ b/gcc/config/i386/i386-builtins.cc
@@ -285,6 +285,8 @@ def_builtin (HOST_WIDE_INT mask, HOST_WIDE_INT mask2,
avx512vl exist. */
|| (mask2 == OPTION_MASK_ISA2_AVXVNNI)
|| (mask2 == OPTION_MASK_ISA2_AVXIFMA)
+ || (mask2 == (OPTION_MASK_ISA2_AVXNECONVERT
+ | OPTION_MASK_ISA2_AVX512BF16))
|| (lang_hooks.builtin_function
== lang_hooks.builtin_function_ext_scope))
{
@@ -2179,18 +2181,14 @@ fold_builtin_cpu (tree fndecl, tree *args)
varpool_node::add (ix86_cpu_features2_var);
}
+ /* Skip __cpu_features[0]. */
feature -= INT_TYPE_SIZE;
- field_val = 1U << (feature % INT_TYPE_SIZE);
tree index = size_int (feature / INT_TYPE_SIZE);
+ feature = feature % INT_TYPE_SIZE;
array_elt = build4 (ARRAY_REF, unsigned_type_node,
ix86_cpu_features2_var,
index, NULL_TREE, NULL_TREE);
/* Return __cpu_features2[index] & field_val */
- final = build2 (BIT_AND_EXPR, unsigned_type_node,
- array_elt,
- build_int_cstu (unsigned_type_node,
- field_val));
- return build1 (NOP_EXPR, integer_type_node, final);
}
else
{
@@ -2207,16 +2205,17 @@ fold_builtin_cpu (tree fndecl, tree *args)
array_elt = build4 (ARRAY_REF, unsigned_type_node, ref,
integer_zero_node, NULL_TREE, NULL_TREE);
- field_val = (1U << feature);
/* Return __cpu_model.__cpu_features[0] & field_val */
- final = build2 (BIT_AND_EXPR, unsigned_type_node, array_elt,
- build_int_cstu (unsigned_type_node, field_val));
- if (feature == (INT_TYPE_SIZE - 1))
- return build2 (NE_EXPR, integer_type_node, final,
- build_int_cst (unsigned_type_node, 0));
- else
- return build1 (NOP_EXPR, integer_type_node, final);
}
+
+ field_val = 1U << feature;
+ final = build2 (BIT_AND_EXPR, unsigned_type_node, array_elt,
+ build_int_cstu (unsigned_type_node, field_val));
+ if (feature == INT_TYPE_SIZE - 1)
+ return build2 (NE_EXPR, integer_type_node, final,
+ build_int_cst (unsigned_type_node, 0));
+ else
+ return build1 (NOP_EXPR, integer_type_node, final);
}
gcc_unreachable ();
}
diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc
index fa195e7..44fab6e 100644
--- a/gcc/config/i386/i386-c.cc
+++ b/gcc/config/i386/i386-c.cc
@@ -202,6 +202,14 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
def_or_undef (parse_in, "__tremont");
def_or_undef (parse_in, "__tremont__");
break;
+ case PROCESSOR_SIERRAFOREST:
+ def_or_undef (parse_in, "__sierraforest");
+ def_or_undef (parse_in, "__sierraforest__");
+ break;
+ case PROCESSOR_GRANDRIDGE:
+ def_or_undef (parse_in, "__grandridge");
+ def_or_undef (parse_in, "__grandridge__");
+ break;
case PROCESSOR_KNL:
def_or_undef (parse_in, "__knl");
def_or_undef (parse_in, "__knl__");
@@ -246,6 +254,10 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
def_or_undef (parse_in, "__sapphirerapids");
def_or_undef (parse_in, "__sapphirerapids__");
break;
+ case PROCESSOR_GRANITERAPIDS:
+ def_or_undef (parse_in, "__graniterapids");
+ def_or_undef (parse_in, "__graniterapids__");
+ break;
case PROCESSOR_ALDERLAKE:
def_or_undef (parse_in, "__alderlake");
def_or_undef (parse_in, "__alderlake__");
@@ -384,6 +396,12 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
case PROCESSOR_TREMONT:
def_or_undef (parse_in, "__tune_tremont__");
break;
+ case PROCESSOR_SIERRAFOREST:
+ def_or_undef (parse_in, "__tune_sierraforest__");
+ break;
+ case PROCESSOR_GRANDRIDGE:
+ def_or_undef (parse_in, "__tune_grandridge__");
+ break;
case PROCESSOR_KNL:
def_or_undef (parse_in, "__tune_knl__");
break;
@@ -426,6 +444,9 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
case PROCESSOR_ROCKETLAKE:
def_or_undef (parse_in, "__tune_rocketlake__");
break;
+ case PROCESSOR_GRANITERAPIDS:
+ def_or_undef (parse_in, "__tune_graniterapids__");
+ break;
case PROCESSOR_INTEL:
case PROCESSOR_GENERIC:
break;
@@ -646,6 +667,14 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
def_or_undef (parse_in, "__AVXVNNIINT8__");
if (isa_flag2 & OPTION_MASK_ISA2_AVXNECONVERT)
def_or_undef (parse_in, "__AVXNECONVERT__");
+ if (isa_flag2 & OPTION_MASK_ISA2_CMPCCXADD)
+ def_or_undef (parse_in, "__CMPCCXADD__");
+ if (isa_flag2 & OPTION_MASK_ISA2_AMX_FP16)
+ def_or_undef (parse_in, "__AMX_FP16__");
+ if (isa_flag2 & OPTION_MASK_ISA2_PREFETCHI)
+ def_or_undef (parse_in, "__PREFETCHI__");
+ if (isa_flag2 & OPTION_MASK_ISA2_RAOINT)
+ def_or_undef (parse_in, "__RAOINT__");
if (TARGET_IAMCU)
{
def_or_undef (parse_in, "__iamcu");
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 7d17bfe..a45640f 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -92,6 +92,7 @@ along with GCC; see the file COPYING3. If not see
#include "i386-options.h"
#include "i386-builtins.h"
#include "i386-expand.h"
+#include "asan.h"
/* Split one or more double-mode RTL references into pairs of half-mode
references. The RTL can be REG, offsettable MEM, integer constant, or
@@ -173,6 +174,33 @@ split_double_concat (machine_mode mode, rtx dst, rtx lo, rtx hi)
rtx dlo, dhi;
int deleted_move_count = 0;
split_double_mode (mode, &dst, 1, &dlo, &dhi);
+ /* Constraints ensure that if both lo and hi are MEMs, then
+ dst has early-clobber and thus addresses of MEMs don't use
+ dlo/dhi registers. Otherwise if at least one of li and hi are MEMs,
+ dlo/dhi are registers. */
+ if (MEM_P (lo)
+ && rtx_equal_p (dlo, hi)
+ && reg_overlap_mentioned_p (dhi, lo))
+ {
+ /* If dlo is same as hi and lo's address uses dhi register,
+ code below would first emit_move_insn (dhi, hi)
+ and then emit_move_insn (dlo, lo). But the former
+ would invalidate lo's address. Load into dhi first,
+ then swap. */
+ emit_move_insn (dhi, lo);
+ lo = dhi;
+ }
+ else if (MEM_P (hi)
+ && !MEM_P (lo)
+ && !rtx_equal_p (dlo, lo)
+ && reg_overlap_mentioned_p (dlo, hi))
+ {
+ /* In this case, code below would first emit_move_insn (dlo, lo)
+ and then emit_move_insn (dhi, hi). But the former would
+ invalidate hi's address. Load into dhi first. */
+ emit_move_insn (dhi, hi);
+ hi = dhi;
+ }
if (!rtx_equal_p (dlo, hi))
{
if (!rtx_equal_p (dlo, lo))
@@ -4510,15 +4538,88 @@ ix86_expand_int_sse_cmp (rtx dest, enum rtx_code code, rtx cop0, rtx cop1,
case GTU:
break;
- case NE:
case LE:
case LEU:
+ /* x <= cst can be handled as x < cst + 1 unless there is
+ wrap around in cst + 1. */
+ if (GET_CODE (cop1) == CONST_VECTOR
+ && GET_MODE_INNER (mode) != TImode)
+ {
+ unsigned int n_elts = GET_MODE_NUNITS (mode), i;
+ machine_mode eltmode = GET_MODE_INNER (mode);
+ for (i = 0; i < n_elts; ++i)
+ {
+ rtx elt = CONST_VECTOR_ELT (cop1, i);
+ if (!CONST_INT_P (elt))
+ break;
+ if (code == GE)
+ {
+ /* For LE punt if some element is signed maximum. */
+ if ((INTVAL (elt) & (GET_MODE_MASK (eltmode) >> 1))
+ == (GET_MODE_MASK (eltmode) >> 1))
+ break;
+ }
+ /* For LEU punt if some element is unsigned maximum. */
+ else if (elt == constm1_rtx)
+ break;
+ }
+ if (i == n_elts)
+ {
+ rtvec v = rtvec_alloc (n_elts);
+ for (i = 0; i < n_elts; ++i)
+ RTVEC_ELT (v, i)
+ = gen_int_mode (INTVAL (CONST_VECTOR_ELT (cop1, i)) + 1,
+ eltmode);
+ cop1 = gen_rtx_CONST_VECTOR (mode, v);
+ std::swap (cop0, cop1);
+ code = code == LE ? GT : GTU;
+ break;
+ }
+ }
+ /* FALLTHRU */
+ case NE:
code = reverse_condition (code);
*negate = true;
break;
case GE:
case GEU:
+ /* x >= cst can be handled as x > cst - 1 unless there is
+ wrap around in cst - 1. */
+ if (GET_CODE (cop1) == CONST_VECTOR
+ && GET_MODE_INNER (mode) != TImode)
+ {
+ unsigned int n_elts = GET_MODE_NUNITS (mode), i;
+ machine_mode eltmode = GET_MODE_INNER (mode);
+ for (i = 0; i < n_elts; ++i)
+ {
+ rtx elt = CONST_VECTOR_ELT (cop1, i);
+ if (!CONST_INT_P (elt))
+ break;
+ if (code == GE)
+ {
+ /* For GE punt if some element is signed minimum. */
+ if (INTVAL (elt) < 0
+ && ((INTVAL (elt) & (GET_MODE_MASK (eltmode) >> 1))
+ == 0))
+ break;
+ }
+ /* For GEU punt if some element is zero. */
+ else if (elt == const0_rtx)
+ break;
+ }
+ if (i == n_elts)
+ {
+ rtvec v = rtvec_alloc (n_elts);
+ for (i = 0; i < n_elts; ++i)
+ RTVEC_ELT (v, i)
+ = gen_int_mode (INTVAL (CONST_VECTOR_ELT (cop1, i)) - 1,
+ eltmode);
+ cop1 = gen_rtx_CONST_VECTOR (mode, v);
+ code = code == GE ? GT : GTU;
+ break;
+ }
+ }
code = reverse_condition (code);
*negate = true;
/* FALLTHRU */
@@ -4556,6 +4657,11 @@ ix86_expand_int_sse_cmp (rtx dest, enum rtx_code code, rtx cop0, rtx cop1,
}
}
+ if (GET_CODE (cop0) == CONST_VECTOR)
+ cop0 = force_reg (mode, cop0);
+ else if (GET_CODE (cop1) == CONST_VECTOR)
+ cop1 = force_reg (mode, cop1);
+
rtx optrue = op_true ? op_true : CONSTM1_RTX (data_mode);
rtx opfalse = op_false ? op_false : CONST0_RTX (data_mode);
if (*negate)
@@ -4752,13 +4858,13 @@ ix86_expand_int_sse_cmp (rtx dest, enum rtx_code code, rtx cop0, rtx cop1,
if (*negate)
std::swap (op_true, op_false);
+ if (GET_CODE (cop1) == CONST_VECTOR)
+ cop1 = force_reg (mode, cop1);
+
/* Allow the comparison to be done in one mode, but the movcc to
happen in another mode. */
if (data_mode == mode)
- {
- x = ix86_expand_sse_cmp (dest, code, cop0, cop1,
- op_true, op_false);
- }
+ x = ix86_expand_sse_cmp (dest, code, cop0, cop1, op_true, op_false);
else
{
gcc_assert (GET_MODE_SIZE (data_mode) == GET_MODE_SIZE (mode));
@@ -9360,6 +9466,17 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (word_mode, fnaddr));
}
+ /* PR100665: Hwasan may tag code pointer which is not supported by LAM,
+ mask off code pointers here.
+ TODO: also need to handle indirect jump. */
+ if (ix86_memtag_can_tag_addresses () && !fndecl
+ && sanitize_flags_p (SANITIZE_HWADDRESS))
+ {
+ rtx untagged_addr = ix86_memtag_untagged_pointer (XEXP (fnaddr, 0),
+ NULL_RTX);
+ fnaddr = gen_rtx_MEM (QImode, untagged_addr);
+ }
+
call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
if (retval)
@@ -10345,6 +10462,7 @@ ix86_expand_args_builtin (const struct builtin_description *d,
return ix86_expand_sse_ptest (d, exp, target);
case FLOAT128_FTYPE_FLOAT128:
case FLOAT_FTYPE_FLOAT:
+ case FLOAT_FTYPE_BFLOAT16:
case INT_FTYPE_INT:
case UINT_FTYPE_UINT:
case UINT16_FTYPE_UINT16:
@@ -11860,8 +11978,9 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
tree arg;
rtx pat, op;
unsigned int i, nargs, arg_adjust, memory;
+ unsigned int constant = 100;
bool aligned_mem = false;
- rtx xops[3];
+ rtx xops[4];
enum insn_code icode = d->icode;
const struct insn_data_d *insn_p = &insn_data[icode];
machine_mode tmode = insn_p->operand[0].mode;
@@ -12152,6 +12271,13 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
klass = load;
memory = 0;
break;
+ case INT_FTYPE_PINT_INT_INT_INT:
+ case LONGLONG_FTYPE_PLONGLONG_LONGLONG_LONGLONG_INT:
+ nargs = 4;
+ klass = load;
+ memory = 0;
+ constant = 3;
+ break;
default:
gcc_unreachable ();
}
@@ -12217,6 +12343,15 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
if (MEM_ALIGN (op) < align)
set_mem_align (op, align);
}
+ else if (i == constant)
+ {
+ /* This must be the constant. */
+ if (!insn_p->operand[nargs].predicate(op, SImode))
+ {
+ error ("the fourth argument must be one of enum %qs", "_CMPCCX_ENUM");
+ return const0_rtx;
+ }
+ }
else
{
/* This must be register. */
@@ -12258,6 +12393,9 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
case 3:
pat = GEN_FCN (icode) (target, xops[0], xops[1], xops[2]);
break;
+ case 4:
+ pat = GEN_FCN (icode) (target, xops[0], xops[1], xops[2], xops[3]);
+ break;
default:
gcc_unreachable ();
}
@@ -12377,7 +12515,7 @@ ix86_expand_vec_set_builtin (tree exp)
op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
elt = get_element_number (TREE_TYPE (arg0), arg2);
- if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
+ if (GET_MODE (op1) != mode1)
op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
op0 = force_reg (tmode, op0);
@@ -13015,6 +13153,90 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
return target;
}
+ case IX86_BUILTIN_PREFETCH:
+ {
+ arg0 = CALL_EXPR_ARG (exp, 0); // const void *
+ arg1 = CALL_EXPR_ARG (exp, 1); // const int
+ arg2 = CALL_EXPR_ARG (exp, 2); // const int
+ arg3 = CALL_EXPR_ARG (exp, 3); // const int
+
+ op0 = expand_normal (arg0);
+ op1 = expand_normal (arg1);
+ op2 = expand_normal (arg2);
+ op3 = expand_normal (arg3);
+
+ if (!CONST_INT_P (op1) || !CONST_INT_P (op2) || !CONST_INT_P (op3))
+ {
+ error ("second, third and fourth argument must be a const");
+ return const0_rtx;
+ }
+
+ if (INTVAL (op3) == 1)
+ {
+ if (TARGET_64BIT && TARGET_PREFETCHI
+ && local_func_symbolic_operand (op0, GET_MODE (op0)))
+ emit_insn (gen_prefetchi (op0, op2));
+ else
+ {
+ warning (0, "instruction prefetch applies when in 64-bit mode"
+ " with RIP-relative addressing and"
+ " option %<-mprefetchi%>;"
+ " they stay NOPs otherwise");
+ emit_insn (gen_nop ());
+ }
+ }
+ else
+ {
+ if (!address_operand (op0, VOIDmode))
+ {
+ op0 = convert_memory_address (Pmode, op0);
+ op0 = copy_addr_to_reg (op0);
+ }
+
+ if (TARGET_3DNOW || TARGET_PREFETCH_SSE
+ || TARGET_PRFCHW || TARGET_PREFETCHWT1)
+ emit_insn (gen_prefetch (op0, op1, op2));
+ else if (!MEM_P (op0) && side_effects_p (op0))
+ /* Don't do anything with direct references to volatile memory,
+ but generate code to handle other side effects. */
+ emit_insn (op0);
+ }
+
+ return 0;
+ }
+
+ case IX86_BUILTIN_PREFETCHI:
+ {
+ arg0 = CALL_EXPR_ARG (exp, 0); // const void *
+ arg1 = CALL_EXPR_ARG (exp, 1); // const int
+
+ op0 = expand_normal (arg0);
+ op1 = expand_normal (arg1);
+
+ if (!CONST_INT_P (op1))
+ {
+ error ("second argument must be a const");
+ return const0_rtx;
+ }
+
+ /* GOT/PLT_PIC should not be available for instruction prefetch.
+ It must be real instruction address. */
+ if (TARGET_64BIT
+ && local_func_symbolic_operand (op0, GET_MODE (op0)))
+ emit_insn (gen_prefetchi (op0, op1));
+ else
+ {
+ /* Ignore the hint. */
+ warning (0, "instruction prefetch applies when in 64-bit mode"
+ " with RIP-relative addressing and"
+ " option %<-mprefetchi%>;"
+ " they stay NOPs otherwise");
+ emit_insn (gen_nop ());
+ }
+
+ return 0;
+ }
+
case IX86_BUILTIN_VEC_INIT_V2SI:
case IX86_BUILTIN_VEC_INIT_V4HI:
case IX86_BUILTIN_VEC_INIT_V8QI:
@@ -14977,6 +15199,10 @@ ix86_vector_duplicate_value (machine_mode mode, rtx target, rtx val)
bool ok;
rtx_insn *insn;
rtx dup;
+ /* Save/restore recog_data in case this is called from splitters
+ or other routines where recog_data needs to stay valid across
+ force_reg. See PR106577. */
+ recog_data_d recog_data_save = recog_data;
/* First attempt to recognize VAL as-is. */
dup = gen_vec_duplicate (mode, val);
@@ -15002,6 +15228,7 @@ ix86_vector_duplicate_value (machine_mode mode, rtx target, rtx val)
ok = recog_memoized (insn) >= 0;
gcc_assert (ok);
}
+ recog_data = recog_data_save;
return true;
}
@@ -23956,4 +24183,29 @@ ix86_expand_cmpxchg_loop (rtx *ptarget_bool, rtx target_val,
*ptarget_bool = target_bool;
}
+/* Convert a BFmode VAL to SFmode without signaling sNaNs.
+ This is done by returning SF SUBREG of ((HI SUBREG) (VAL)) << 16. */
+
+rtx
+ix86_expand_fast_convert_bf_to_sf (rtx val)
+{
+ rtx op = gen_lowpart (HImode, val), ret;
+ if (CONST_INT_P (op))
+ {
+ ret = simplify_const_unary_operation (FLOAT_EXTEND, SFmode,
+ val, BFmode);
+ if (ret)
+ return ret;
+ /* FLOAT_EXTEND simplification will fail if VAL is a sNaN. */
+ ret = gen_reg_rtx (SImode);
+ emit_move_insn (ret, GEN_INT (INTVAL (op) & 0xffff));
+ emit_insn (gen_ashlsi3 (ret, ret, GEN_INT (16)));
+ return gen_lowpart (SFmode, ret);
+ }
+
+ ret = gen_reg_rtx (SFmode);
+ emit_insn (gen_extendbfsf2_1 (ret, force_reg (BFmode, val)));
+ return ret;
+}
+
#include "gt-i386-expand.h"
diff --git a/gcc/config/i386/i386-isa.def b/gcc/config/i386/i386-isa.def
index 4ea3f96..63a2490 100644
--- a/gcc/config/i386/i386-isa.def
+++ b/gcc/config/i386/i386-isa.def
@@ -112,3 +112,7 @@ DEF_PTA(AVX512FP16)
DEF_PTA(AVXIFMA)
DEF_PTA(AVXVNNIINT8)
DEF_PTA(AVXNECONVERT)
+DEF_PTA(CMPCCXADD)
+DEF_PTA(AMX_FP16)
+DEF_PTA(PREFETCHI)
+DEF_PTA(RAOINT)
diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
index ef9c888..25f21ac 100644
--- a/gcc/config/i386/i386-options.cc
+++ b/gcc/config/i386/i386-options.cc
@@ -127,15 +127,19 @@ along with GCC; see the file COPYING3. If not see
#define m_SAPPHIRERAPIDS (HOST_WIDE_INT_1U<<PROCESSOR_SAPPHIRERAPIDS)
#define m_ALDERLAKE (HOST_WIDE_INT_1U<<PROCESSOR_ALDERLAKE)
#define m_ROCKETLAKE (HOST_WIDE_INT_1U<<PROCESSOR_ROCKETLAKE)
+#define m_GRANITERAPIDS (HOST_WIDE_INT_1U<<PROCESSOR_GRANITERAPIDS)
#define m_CORE_AVX512 (m_SKYLAKE_AVX512 | m_CANNONLAKE \
| m_ICELAKE_CLIENT | m_ICELAKE_SERVER | m_CASCADELAKE \
| m_TIGERLAKE | m_COOPERLAKE | m_SAPPHIRERAPIDS \
- | m_ROCKETLAKE)
+ | m_ROCKETLAKE | m_GRANITERAPIDS)
#define m_CORE_AVX2 (m_HASWELL | m_SKYLAKE | m_CORE_AVX512)
#define m_CORE_ALL (m_CORE2 | m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2)
#define m_GOLDMONT (HOST_WIDE_INT_1U<<PROCESSOR_GOLDMONT)
#define m_GOLDMONT_PLUS (HOST_WIDE_INT_1U<<PROCESSOR_GOLDMONT_PLUS)
#define m_TREMONT (HOST_WIDE_INT_1U<<PROCESSOR_TREMONT)
+#define m_SIERRAFOREST (HOST_WIDE_INT_1U<<PROCESSOR_SIERRAFOREST)
+#define m_GRANDRIDGE (HOST_WIDE_INT_1U<<PROCESSOR_GRANDRIDGE)
+#define m_CORE_ATOM (m_SIERRAFOREST | m_GRANDRIDGE)
#define m_INTEL (HOST_WIDE_INT_1U<<PROCESSOR_INTEL)
#define m_LUJIAZUI (HOST_WIDE_INT_1U<<PROCESSOR_LUJIAZUI)
@@ -230,7 +234,11 @@ static struct ix86_target_opts isa2_opts[] =
{ "-mavx512fp16", OPTION_MASK_ISA2_AVX512FP16 },
{ "-mavxifma", OPTION_MASK_ISA2_AVXIFMA },
{ "-mavxvnniint8", OPTION_MASK_ISA2_AVXVNNIINT8 },
- { "-mavxneconvert", OPTION_MASK_ISA2_AVXNECONVERT }
+ { "-mavxneconvert", OPTION_MASK_ISA2_AVXNECONVERT },
+ { "-mcmpccxadd", OPTION_MASK_ISA2_CMPCCXADD },
+ { "-mamx-fp16", OPTION_MASK_ISA2_AMX_FP16 },
+ { "-mprefetchi", OPTION_MASK_ISA2_PREFETCHI },
+ { "-mraoint", OPTION_MASK_ISA2_RAOINT }
};
static struct ix86_target_opts isa_opts[] =
{
@@ -311,10 +319,6 @@ ix86_omp_device_kind_arch_isa (enum omp_device_kind_arch_isa trait,
case omp_device_kind:
return strcmp (name, "cpu") == 0;
case omp_device_arch:
-#ifdef ACCEL_COMPILER
- if (strcmp (name, "intel_mic") == 0)
- return 1;
-#endif
if (strcmp (name, "x86") == 0)
return 1;
if (TARGET_64BIT)
@@ -683,7 +687,6 @@ ix86_function_specific_save (struct cl_target_option *ptr,
ptr->x_recip_mask_explicit = opts->x_recip_mask_explicit;
ptr->x_ix86_arch_string = opts->x_ix86_arch_string;
ptr->x_ix86_tune_string = opts->x_ix86_tune_string;
- ptr->x_ix86_abi = opts->x_ix86_abi;
ptr->x_ix86_asm_dialect = opts->x_ix86_asm_dialect;
ptr->x_ix86_branch_cost = opts->x_ix86_branch_cost;
ptr->x_ix86_dump_tunes = opts->x_ix86_dump_tunes;
@@ -747,6 +750,8 @@ static const struct processor_costs *processor_cost_table[] =
&slm_cost,
&slm_cost,
&tremont_cost,
+ &alderlake_cost,
+ &alderlake_cost,
&slm_cost,
&slm_cost,
&skylake_cost,
@@ -760,6 +765,7 @@ static const struct processor_costs *processor_cost_table[] =
&icelake_cost,
&alderlake_cost,
&icelake_cost,
+ &icelake_cost,
&intel_cost,
&lujiazui_cost,
&geode_cost,
@@ -816,7 +822,6 @@ ix86_function_specific_restore (struct gcc_options *opts,
opts->x_recip_mask_explicit = ptr->x_recip_mask_explicit;
opts->x_ix86_arch_string = ptr->x_ix86_arch_string;
opts->x_ix86_tune_string = ptr->x_ix86_tune_string;
- opts->x_ix86_abi = ptr->x_ix86_abi;
opts->x_ix86_asm_dialect = ptr->x_ix86_asm_dialect;
opts->x_ix86_branch_cost = ptr->x_ix86_branch_cost;
opts->x_ix86_dump_tunes = ptr->x_ix86_dump_tunes;
@@ -1080,6 +1085,10 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
IX86_ATTR_ISA ("avxifma", OPT_mavxifma),
IX86_ATTR_ISA ("avxvnniint8", OPT_mavxvnniint8),
IX86_ATTR_ISA ("avxneconvert", OPT_mavxneconvert),
+ IX86_ATTR_ISA ("cmpccxadd", OPT_mcmpccxadd),
+ IX86_ATTR_ISA ("amx-fp16", OPT_mamx_fp16),
+ IX86_ATTR_ISA ("prefetchi", OPT_mprefetchi),
+ IX86_ATTR_ISA ("raoint", OPT_mraoint),
/* enum options */
IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_),
@@ -1827,8 +1836,37 @@ ix86_recompute_optlev_based_flags (struct gcc_options *opts,
void
ix86_override_options_after_change (void)
{
+ /* Default align_* from the processor table. */
ix86_default_align (&global_options);
+
ix86_recompute_optlev_based_flags (&global_options, &global_options_set);
+
+ /* Disable unrolling small loops when there's explicit
+ -f{,no}unroll-loop. */
+ if ((OPTION_SET_P (flag_unroll_loops))
+ || (OPTION_SET_P (flag_unroll_all_loops)
+ && flag_unroll_all_loops))
+ {
+ if (!OPTION_SET_P (ix86_unroll_only_small_loops))
+ ix86_unroll_only_small_loops = 0;
+ /* Re-enable -frename-registers and -fweb if funroll-loops
+ enabled. */
+ if (!OPTION_SET_P (flag_web))
+ flag_web = flag_unroll_loops;
+ if (!OPTION_SET_P (flag_rename_registers))
+ flag_rename_registers = flag_unroll_loops;
+ /* -fcunroll-grow-size default follws -f[no]-unroll-loops. */
+ if (!OPTION_SET_P (flag_cunroll_grow_size))
+ flag_cunroll_grow_size = flag_unroll_loops
+ || flag_peel_loops
+ || optimize >= 3;
+ }
+ else
+ {
+ if (!OPTION_SET_P (flag_cunroll_grow_size))
+ flag_cunroll_grow_size = flag_peel_loops || optimize >= 3;
+ }
+
}
/* Clear stack slot assignments remembered from previous functions.
@@ -1995,6 +2033,9 @@ ix86_option_override_internal (bool main_args_p,
if (TARGET_UINTR && !TARGET_64BIT)
error ("%<-muintr%> not supported for 32-bit code");
+ if (ix86_lam_type && !TARGET_LP64)
+ error ("%<-mlam=%> option: [u48|u57] not supported for 32-bit code");
+
if (!opts->x_ix86_arch_string)
opts->x_ix86_arch_string
= TARGET_64BIT_P (opts->x_ix86_isa_flags)
@@ -2340,7 +2381,7 @@ ix86_option_override_internal (bool main_args_p,
set_ix86_tune_features (opts, ix86_tune, opts->x_ix86_dump_tunes);
- ix86_recompute_optlev_based_flags (opts, opts_set);
+ ix86_override_options_after_change ();
ix86_tune_cost = processor_cost_table[ix86_tune];
/* TODO: ix86_cost should be chosen at instruction or function granuality
@@ -2371,9 +2412,6 @@ ix86_option_override_internal (bool main_args_p,
|| TARGET_64BIT_P (opts->x_ix86_isa_flags))
opts->x_ix86_regparm = REGPARM_MAX;
- /* Default align_* from the processor table. */
- ix86_default_align (opts);
-
/* Provide default for -mbranch-cost= value. */
SET_OPTION_IF_UNSET (opts, opts_set, ix86_branch_cost,
ix86_tune_cost->branch_cost);
diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h
index 8f71e89..d3bfeed 100644
--- a/gcc/config/i386/i386-opts.h
+++ b/gcc/config/i386/i386-opts.h
@@ -128,4 +128,10 @@ enum harden_sls {
harden_sls_all = harden_sls_return | harden_sls_indirect_jmp
};
+enum lam_type {
+ lam_none = 0,
+ lam_u48 = 1,
+ lam_u57
+};
+
#endif
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 5318fc7..abd123c 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -227,6 +227,9 @@ extern void ix86_expand_atomic_fetch_op_loop (rtx, rtx, rtx, enum rtx_code,
bool, bool);
extern void ix86_expand_cmpxchg_loop (rtx *, rtx, rtx, rtx, rtx, rtx,
bool, rtx_code_label *);
+extern rtx ix86_expand_fast_convert_bf_to_sf (rtx);
+extern rtx ix86_memtag_untagged_pointer (rtx, rtx);
+extern bool ix86_memtag_can_tag_addresses (void);
#ifdef TREE_CODE
extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index f858649..518cc9f 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -19725,7 +19725,8 @@ ix86_can_change_mode_class (machine_mode from, machine_mode to,
the vec_dupv4hi pattern.
NB: SSE2 can load 16bit data to sse register via pinsrw. */
int mov_size = MAYBE_SSE_CLASS_P (regclass) && TARGET_SSE2 ? 2 : 4;
- if (GET_MODE_SIZE (from) < mov_size)
+ if (GET_MODE_SIZE (from) < mov_size
+ || GET_MODE_SIZE (to) < mov_size)
return false;
}
@@ -20089,12 +20090,6 @@ ix86_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
|| VALID_AVX512F_SCALAR_MODE (mode)))
return true;
- /* For AVX512FP16, vmovw supports movement of HImode
- and HFmode between GPR and SSE registers. */
- if (TARGET_AVX512FP16
- && VALID_AVX512FP16_SCALAR_MODE (mode))
- return true;
-
/* For AVX-5124FMAPS or AVX-5124VNNIW
allow V64SF and V64SI modes for special regnos. */
if ((TARGET_AVX5124FMAPS || TARGET_AVX5124VNNIW)
@@ -20113,6 +20108,10 @@ ix86_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
if (EXT_REX_SSE_REGNO_P (regno))
return false;
+ /* Use pinsrw/pextrw to mov 16-bit data from/to sse to/from integer. */
+ if (TARGET_SSE2 && mode == HImode)
+ return true;
+
/* OImode and AVX modes are available only when AVX is enabled. */
return ((TARGET_AVX
&& VALID_AVX256_REG_OR_OI_MODE (mode))
@@ -23633,7 +23632,8 @@ ix86_memmodel_check (unsigned HOST_WIDE_INT val)
static int
ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
struct cgraph_simd_clone *clonei,
- tree base_type, int num)
+ tree base_type, int num,
+ bool explicit_p)
{
int ret = 1;
@@ -23642,8 +23642,9 @@ ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
|| clonei->simdlen > 1024
|| (clonei->simdlen & (clonei->simdlen - 1)) != 0))
{
- warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
- "unsupported simdlen %wd", clonei->simdlen.to_constant ());
+ if (explicit_p)
+ warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+ "unsupported simdlen %wd", clonei->simdlen.to_constant ());
return 0;
}
@@ -23663,8 +23664,9 @@ ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
break;
/* FALLTHRU */
default:
- warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
- "unsupported return type %qT for simd", ret_type);
+ if (explicit_p)
+ warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+ "unsupported return type %qT for simd", ret_type);
return 0;
}
@@ -23693,13 +23695,14 @@ ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
default:
if (clonei->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM)
break;
- warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
- "unsupported argument type %qT for simd", arg_type);
+ if (explicit_p)
+ warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+ "unsupported argument type %qT for simd", arg_type);
return 0;
}
}
- if (!TREE_PUBLIC (node->decl))
+ if (!TREE_PUBLIC (node->decl) || !explicit_p)
{
/* If the function isn't exported, we can pick up just one ISA
for the clones. */
@@ -23770,9 +23773,10 @@ ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
cnt /= clonei->vecsize_float;
if (cnt > (TARGET_64BIT ? 16 : 8))
{
- warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
- "unsupported simdlen %wd",
- clonei->simdlen.to_constant ());
+ if (explicit_p)
+ warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+ "unsupported simdlen %wd",
+ clonei->simdlen.to_constant ());
return 0;
}
}
@@ -23827,6 +23831,16 @@ ix86_loop_unroll_adjust (unsigned nunroll, class loop *loop)
unsigned i;
unsigned mem_count = 0;
+ /* Unroll small size loop when unroll factor is not explicitly
+ specified. */
+ if (ix86_unroll_only_small_loops && !loop->unroll)
+ {
+ if (loop->ninsns <= ix86_cost->small_unroll_ninsns)
+ return MIN (nunroll, ix86_cost->small_unroll_factor);
+ else
+ return 1;
+ }
+
if (!TARGET_ADJUST_UNROLL)
return nunroll;
@@ -24260,6 +24274,111 @@ ix86_push_rounding (poly_int64 bytes)
return ROUND_UP (bytes, UNITS_PER_WORD);
}
+/* Use 8 bits metadata start from bit48 for LAM_U48,
+ 6 bits metadat start from bit57 for LAM_U57. */
+#define IX86_HWASAN_SHIFT (ix86_lam_type == lam_u48 \
+ ? 48 \
+ : (ix86_lam_type == lam_u57 ? 57 : 0))
+#define IX86_HWASAN_TAG_SIZE (ix86_lam_type == lam_u48 \
+ ? 8 \
+ : (ix86_lam_type == lam_u57 ? 6 : 0))
+
+/* Implement TARGET_MEMTAG_CAN_TAG_ADDRESSES. */
+bool
+ix86_memtag_can_tag_addresses ()
+{
+ return ix86_lam_type != lam_none && TARGET_LP64;
+}
+
+/* Implement TARGET_MEMTAG_TAG_SIZE. */
+unsigned char
+ix86_memtag_tag_size ()
+{
+ return IX86_HWASAN_TAG_SIZE;
+}
+
+/* Implement TARGET_MEMTAG_SET_TAG. */
+rtx
+ix86_memtag_set_tag (rtx untagged, rtx tag, rtx target)
+{
+ /* default_memtag_insert_random_tag may
+ generate tag with value more than 6 bits. */
+ if (ix86_lam_type == lam_u57)
+ {
+ unsigned HOST_WIDE_INT and_imm
+ = (HOST_WIDE_INT_1U << IX86_HWASAN_TAG_SIZE) - 1;
+
+ emit_insn (gen_andqi3 (tag, tag, GEN_INT (and_imm)));
+ }
+ tag = expand_simple_binop (Pmode, ASHIFT, tag,
+ GEN_INT (IX86_HWASAN_SHIFT), NULL_RTX,
+ /* unsignedp = */1, OPTAB_WIDEN);
+ rtx ret = expand_simple_binop (Pmode, IOR, untagged, tag, target,
+ /* unsignedp = */1, OPTAB_DIRECT);
+ return ret;
+}
+
+/* Implement TARGET_MEMTAG_EXTRACT_TAG. */
+rtx
+ix86_memtag_extract_tag (rtx tagged_pointer, rtx target)
+{
+ rtx tag = expand_simple_binop (Pmode, LSHIFTRT, tagged_pointer,
+ GEN_INT (IX86_HWASAN_SHIFT), target,
+ /* unsignedp = */0,
+ OPTAB_DIRECT);
+ rtx ret = gen_reg_rtx (QImode);
+ /* Mask off bit63 when LAM_U57. */
+ if (ix86_lam_type == lam_u57)
+ {
+ unsigned HOST_WIDE_INT and_imm
+ = (HOST_WIDE_INT_1U << IX86_HWASAN_TAG_SIZE) - 1;
+ emit_insn (gen_andqi3 (ret, gen_lowpart (QImode, tag),
+ gen_int_mode (and_imm, QImode)));
+ }
+ else
+ emit_move_insn (ret, gen_lowpart (QImode, tag));
+ return ret;
+}
+
+/* The default implementation of TARGET_MEMTAG_UNTAGGED_POINTER. */
+rtx
+ix86_memtag_untagged_pointer (rtx tagged_pointer, rtx target)
+{
+ /* Leave bit63 alone. */
+ rtx tag_mask = gen_int_mode (((HOST_WIDE_INT_1U << IX86_HWASAN_SHIFT)
+ + (HOST_WIDE_INT_1U << 63) - 1),
+ Pmode);
+ rtx untagged_base = expand_simple_binop (Pmode, AND, tagged_pointer,
+ tag_mask, target, true,
+ OPTAB_DIRECT);
+ gcc_assert (untagged_base);
+ return untagged_base;
+}
+
+/* Implement TARGET_MEMTAG_ADD_TAG. */
+rtx
+ix86_memtag_add_tag (rtx base, poly_int64 offset, unsigned char tag_offset)
+{
+ rtx base_tag = gen_reg_rtx (QImode);
+ rtx base_addr = gen_reg_rtx (Pmode);
+ rtx tagged_addr = gen_reg_rtx (Pmode);
+ rtx new_tag = gen_reg_rtx (QImode);
+ unsigned HOST_WIDE_INT and_imm
+ = (HOST_WIDE_INT_1U << IX86_HWASAN_SHIFT) - 1;
+
+ /* When there's "overflow" in tag adding,
+ need to mask the most significant bit off. */
+ emit_move_insn (base_tag, ix86_memtag_extract_tag (base, NULL_RTX));
+ emit_move_insn (base_addr,
+ ix86_memtag_untagged_pointer (base, NULL_RTX));
+ emit_insn (gen_add2_insn (base_tag, gen_int_mode (tag_offset, QImode)));
+ emit_move_insn (new_tag, base_tag);
+ emit_insn (gen_andqi3 (new_tag, new_tag, gen_int_mode (and_imm, QImode)));
+ emit_move_insn (tagged_addr,
+ ix86_memtag_set_tag (base_addr, new_tag, NULL_RTX));
+ return plus_constant (Pmode, tagged_addr, offset);
+}
+
/* Target-specific selftests. */
#if CHECKING_P
@@ -25054,6 +25173,24 @@ ix86_libgcc_floating_mode_supported_p
# define TARGET_ASM_RELOC_RW_MASK ix86_reloc_rw_mask
#endif
+#undef TARGET_MEMTAG_CAN_TAG_ADDRESSES
+#define TARGET_MEMTAG_CAN_TAG_ADDRESSES ix86_memtag_can_tag_addresses
+
+#undef TARGET_MEMTAG_ADD_TAG
+#define TARGET_MEMTAG_ADD_TAG ix86_memtag_add_tag
+
+#undef TARGET_MEMTAG_SET_TAG
+#define TARGET_MEMTAG_SET_TAG ix86_memtag_set_tag
+
+#undef TARGET_MEMTAG_EXTRACT_TAG
+#define TARGET_MEMTAG_EXTRACT_TAG ix86_memtag_extract_tag
+
+#undef TARGET_MEMTAG_UNTAGGED_POINTER
+#define TARGET_MEMTAG_UNTAGGED_POINTER ix86_memtag_untagged_pointer
+
+#undef TARGET_MEMTAG_TAG_SIZE
+#define TARGET_MEMTAG_TAG_SIZE ix86_memtag_tag_size
+
static bool ix86_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED)
{
#ifdef OPTION_GLIBC
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 16d9c60..d865fcb 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -219,6 +219,11 @@ struct processor_costs {
const char *const align_jump; /* Jump alignment. */
const char *const align_label; /* Label alignment. */
const char *const align_func; /* Function alignment. */
+
+ const unsigned small_unroll_ninsns; /* Insn count limit for small loop
+ to be unrolled. */
+ const unsigned small_unroll_factor; /* Unroll factor for small loop to
+ be unrolled. */
};
extern const struct processor_costs *ix86_cost;
@@ -1012,11 +1017,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
(VALID_AVX256_REG_MODE (MODE) || (MODE) == OImode)
#define VALID_AVX512F_SCALAR_MODE(MODE) \
- ((MODE) == DImode || (MODE) == DFmode || (MODE) == SImode \
- || (MODE) == SFmode)
-
-#define VALID_AVX512FP16_SCALAR_MODE(MODE) \
- ((MODE) == HImode || (MODE) == HFmode)
+ ((MODE) == DImode || (MODE) == DFmode \
+ || (MODE) == SImode || (MODE) == SFmode \
+ || (MODE) == HImode || (MODE) == HFmode || (MODE) == BFmode)
#define VALID_AVX512F_REG_MODE(MODE) \
((MODE) == V8DImode || (MODE) == V8DFmode || (MODE) == V64QImode \
@@ -1040,13 +1043,15 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
|| (MODE) == V8HFmode || (MODE) == V4HFmode || (MODE) == V2HFmode \
|| (MODE) == V8BFmode || (MODE) == V4BFmode || (MODE) == V2BFmode \
|| (MODE) == V4QImode || (MODE) == V2HImode || (MODE) == V1SImode \
- || (MODE) == V2DImode || (MODE) == V2QImode || (MODE) == DFmode \
+ || (MODE) == V2DImode || (MODE) == V2QImode \
+ || (MODE) == DFmode || (MODE) == DImode \
|| (MODE) == HFmode || (MODE) == BFmode)
#define VALID_SSE_REG_MODE(MODE) \
((MODE) == V1TImode || (MODE) == TImode \
|| (MODE) == V4SFmode || (MODE) == V4SImode \
- || (MODE) == SFmode || (MODE) == TFmode || (MODE) == TDmode)
+ || (MODE) == SFmode || (MODE) == SImode \
+ || (MODE) == TFmode || (MODE) == TDmode)
#define VALID_MMX_REG_MODE_3DNOW(MODE) \
((MODE) == V2SFmode || (MODE) == SFmode)
@@ -1933,9 +1938,6 @@ do { \
#define SLOW_BYTE_ACCESS 0
-/* Nonzero if access to memory by shorts is slow and undesirable. */
-#define SLOW_SHORT_ACCESS 0
-
/* Define this macro if it is as good or better to call a constant
function address than to call an address kept in a register.
@@ -2225,6 +2227,8 @@ enum processor_type
PROCESSOR_GOLDMONT,
PROCESSOR_GOLDMONT_PLUS,
PROCESSOR_TREMONT,
+ PROCESSOR_SIERRAFOREST,
+ PROCESSOR_GRANDRIDGE,
PROCESSOR_KNL,
PROCESSOR_KNM,
PROCESSOR_SKYLAKE,
@@ -2238,6 +2242,7 @@ enum processor_type
PROCESSOR_SAPPHIRERAPIDS,
PROCESSOR_ALDERLAKE,
PROCESSOR_ROCKETLAKE,
+ PROCESSOR_GRANITERAPIDS,
PROCESSOR_INTEL,
PROCESSOR_LUJIAZUI,
PROCESSOR_GEODE,
@@ -2345,6 +2350,11 @@ constexpr wide_int_bitmask PTA_ALDERLAKE = PTA_TREMONT | PTA_ADX | PTA_AVX
| PTA_AVX2 | PTA_BMI | PTA_BMI2 | PTA_F16C | PTA_FMA | PTA_LZCNT
| PTA_PCONFIG | PTA_PKU | PTA_VAES | PTA_VPCLMULQDQ | PTA_SERIALIZE
| PTA_HRESET | PTA_KL | PTA_WIDEKL | PTA_AVXVNNI;
+constexpr wide_int_bitmask PTA_SIERRAFOREST = PTA_ALDERLAKE | PTA_AVXIFMA
+ | PTA_AVXVNNIINT8 | PTA_AVXNECONVERT | PTA_CMPCCXADD;
+constexpr wide_int_bitmask PTA_GRANITERAPIDS = PTA_SAPPHIRERAPIDS | PTA_AMX_FP16
+ | PTA_PREFETCHI;
+constexpr wide_int_bitmask PTA_GRANDRIDGE = PTA_SIERRAFOREST | PTA_RAOINT;
constexpr wide_int_bitmask PTA_KNM = PTA_KNL | PTA_AVX5124VNNIW
| PTA_AVX5124FMAPS | PTA_AVX512VPOPCNTDQ;
constexpr wide_int_bitmask PTA_ZNVER1 = PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 8556798..04a5d63 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -130,6 +130,7 @@
;; For AVX/AVX512F support
UNSPEC_SCALEF
UNSPEC_PCMP
+ UNSPEC_CVTBFSF
;; Generic math support
UNSPEC_IEEE_MIN ; not commutative
@@ -330,6 +331,9 @@
;; For HRESET support
UNSPECV_HRESET
+
+ ;; For PREFETCHI support
+ UNSPECV_PREFETCHI
])
;; Constants to represent rounding modes in the ROUND instruction
@@ -1130,6 +1134,10 @@
(define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
(define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
+;; Half sized integer modes.
+(define_mode_attr HALF [(TI "DI") (DI "SI")])
+(define_mode_attr half [(TI "di") (DI "si")])
+
;; LEA mode corresponding to an integer mode
(define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
@@ -1663,30 +1671,10 @@
(const_int 0)])
(label_ref (match_operand 3))
(pc)))]
- ""
+ "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
{
- rtx op1 = gen_lowpart (HImode, operands[1]);
- if (CONST_INT_P (op1))
- op1 = simplify_const_unary_operation (FLOAT_EXTEND, SFmode,
- operands[1], BFmode);
- else
- {
- rtx t1 = gen_reg_rtx (SImode);
- emit_insn (gen_zero_extendhisi2 (t1, op1));
- emit_insn (gen_ashlsi3 (t1, t1, GEN_INT (16)));
- op1 = gen_lowpart (SFmode, t1);
- }
- rtx op2 = gen_lowpart (HImode, operands[2]);
- if (CONST_INT_P (op2))
- op2 = simplify_const_unary_operation (FLOAT_EXTEND, SFmode,
- operands[2], BFmode);
- else
- {
- rtx t2 = gen_reg_rtx (SImode);
- emit_insn (gen_zero_extendhisi2 (t2, op2));
- emit_insn (gen_ashlsi3 (t2, t2, GEN_INT (16)));
- op2 = gen_lowpart (SFmode, t2);
- }
+ rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[1]);
+ rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0,
SFmode, NULL_RTX, NULL,
as_a <rtx_code_label *> (operands[3]),
@@ -1718,30 +1706,10 @@
(match_operator 1 "comparison_operator"
[(reg:CC FLAGS_REG)
(const_int 0)]))]
- ""
+ "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
{
- rtx op1 = gen_lowpart (HImode, operands[2]);
- if (CONST_INT_P (op1))
- op1 = simplify_const_unary_operation (FLOAT_EXTEND, SFmode,
- operands[2], BFmode);
- else
- {
- rtx t1 = gen_reg_rtx (SImode);
- emit_insn (gen_zero_extendhisi2 (t1, op1));
- emit_insn (gen_ashlsi3 (t1, t1, GEN_INT (16)));
- op1 = gen_lowpart (SFmode, t1);
- }
- rtx op2 = gen_lowpart (HImode, operands[3]);
- if (CONST_INT_P (op2))
- op2 = simplify_const_unary_operation (FLOAT_EXTEND, SFmode,
- operands[3], BFmode);
- else
- {
- rtx t2 = gen_reg_rtx (SImode);
- emit_insn (gen_zero_extendhisi2 (t2, op2));
- emit_insn (gen_ashlsi3 (t2, t2, GEN_INT (16)));
- op2 = gen_lowpart (SFmode, t2);
- }
+ rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
+ rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[3]);
rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]),
op1, op2, SFmode, 0, 1);
if (!rtx_equal_p (res, operands[0]))
@@ -4998,6 +4966,31 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<MODE>")])
+(define_expand "extendbfsf2"
+ [(set (match_operand:SF 0 "register_operand")
+ (unspec:SF
+ [(match_operand:BF 1 "register_operand")]
+ UNSPEC_CVTBFSF))]
+ "TARGET_SSE2 && !HONOR_NANS (BFmode)")
+
+;; Don't use float_extend since psrlld doesn't raise
+;; exceptions and turn a sNaN into a qNaN.
+(define_insn "extendbfsf2_1"
+ [(set (match_operand:SF 0 "register_operand" "=x,Yw")
+ (unspec:SF
+ [(match_operand:BF 1 "register_operand" " 0,Yw")]
+ UNSPEC_CVTBFSF))]
+ "TARGET_SSE2"
+ "@
+ pslld\t{$16, %0|%0, 16}
+ vpslld\t{$16, %1, %0|%0, %1, 16}"
+ [(set_attr "isa" "noavx,avx")
+ (set_attr "type" "sseishft1")
+ (set_attr "length_immediate" "1")
+ (set_attr "prefix_data16" "1,*")
+ (set_attr "prefix" "orig,vex")
+ (set_attr "mode" "TI")
+ (set_attr "memory" "none")])
(define_expand "extend<mode>xf2"
[(set (match_operand:XF 0 "nonimmediate_operand")
@@ -5214,7 +5207,19 @@
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "HF")])
-
+
+(define_insn "truncsfbf2"
+ [(set (match_operand:BF 0 "register_operand" "=x, v")
+ (float_truncate:BF
+ (match_operand:SF 1 "register_operand" "x,v")))]
+ "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
+ && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
+ "@
+ %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
+ vcvtneps2bf16\t{%1, %0|%0, %1}"
+ [(set_attr "isa" "avxneconvert,avx512bf16vl")
+ (set_attr "prefix" "vex,evex")])
+
;; Signed conversion to DImode.
(define_expand "fix_truncxfdi2"
@@ -11395,11 +11400,12 @@
;; Split DST = (HI<<32)|LO early to minimize register usage.
(define_code_iterator any_or_plus [plus ior xor])
(define_insn_and_split "*concat<mode><dwi>3_1"
- [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
+ [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
(any_or_plus:<DWI>
- (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r")
+ (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
(match_operand:<DWI> 2 "const_int_operand"))
- (zero_extend:<DWI> (match_operand:DWIH 3 "register_operand" "r"))))]
+ (zero_extend:<DWI>
+ (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
"INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
"#"
"&& reload_completed"
@@ -11411,10 +11417,11 @@
})
(define_insn_and_split "*concat<mode><dwi>3_2"
- [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
+ [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
(any_or_plus:<DWI>
- (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "r"))
- (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r")
+ (zero_extend:<DWI>
+ (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
+ (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
(match_operand:<DWI> 3 "const_int_operand"))))]
"INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
"#"
@@ -11427,12 +11434,14 @@
})
(define_insn_and_split "*concat<mode><dwi>3_3"
- [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
+ [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
(any_or_plus:<DWI>
(ashift:<DWI>
- (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "r"))
+ (zero_extend:<DWI>
+ (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
(match_operand:<DWI> 2 "const_int_operand"))
- (zero_extend:<DWI> (match_operand:DWIH 3 "register_operand" "r"))))]
+ (zero_extend:<DWI>
+ (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m"))))]
"INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
"#"
"&& reload_completed"
@@ -11443,11 +11452,13 @@
})
(define_insn_and_split "*concat<mode><dwi>3_4"
- [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
+ [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
(any_or_plus:<DWI>
- (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "r"))
+ (zero_extend:<DWI>
+ (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
(ashift:<DWI>
- (zero_extend:<DWI> (match_operand:DWIH 2 "register_operand" "r"))
+ (zero_extend:<DWI>
+ (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
(match_operand:<DWI> 3 "const_int_operand"))))]
"INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
"#"
@@ -11457,6 +11468,80 @@
split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
DONE;
})
+
+(define_insn_and_split "*concat<half><mode>3_5"
+ [(set (match_operand:DWI 0 "nonimmediate_operand" "=ro")
+ (any_or_plus:DWI
+ (ashift:DWI (match_operand:DWI 1 "register_operand" "r")
+ (match_operand:DWI 2 "const_int_operand"))
+ (match_operand:DWI 3 "const_scalar_int_operand")))]
+ "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
+ && (<MODE>mode == DImode
+ ? CONST_INT_P (operands[3])
+ && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
+ : CONST_INT_P (operands[3])
+ ? INTVAL (operands[3]) >= 0
+ : CONST_WIDE_INT_NUNITS (operands[3]) == 2
+ && CONST_WIDE_INT_ELT (operands[3], 1) == 0)"
+ "#"
+ "&& reload_completed"
+ [(clobber (const_int 0))]
+{
+ rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
+ split_double_concat (<MODE>mode, operands[0], op3,
+ gen_lowpart (<HALF>mode, operands[1]));
+ DONE;
+})
+
+(define_insn_and_split "*concat<mode><dwi>3_6"
+ [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
+ (any_or_plus:<DWI>
+ (ashift:<DWI>
+ (zero_extend:<DWI>
+ (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
+ (match_operand:<DWI> 2 "const_int_operand"))
+ (match_operand:<DWI> 3 "const_scalar_int_operand")))]
+ "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
+ && (<DWI>mode == DImode
+ ? CONST_INT_P (operands[3])
+ && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
+ : CONST_INT_P (operands[3])
+ ? INTVAL (operands[3]) >= 0
+ : CONST_WIDE_INT_NUNITS (operands[3]) == 2
+ && CONST_WIDE_INT_ELT (operands[3], 1) == 0)"
+ "#"
+ "&& reload_completed"
+ [(clobber (const_int 0))]
+{
+ rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
+ split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
+ DONE;
+})
+
+(define_insn_and_split "*concat<mode><dwi>3_7"
+ [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
+ (any_or_plus:<DWI>
+ (zero_extend:<DWI>
+ (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
+ (match_operand:<DWI> 2 "const_scalar_int_operand")))]
+ "<DWI>mode == DImode
+ ? CONST_INT_P (operands[2])
+ && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
+ : CONST_WIDE_INT_P (operands[2])
+ && CONST_WIDE_INT_NUNITS (operands[2]) == 2
+ && CONST_WIDE_INT_ELT (operands[2], 0) == 0"
+ "#"
+ "&& reload_completed"
+ [(clobber (const_int 0))]
+{
+ rtx op2;
+ if (<DWI>mode == DImode)
+ op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
+ else
+ op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
+ split_double_concat (<DWI>mode, operands[0], operands[1], op2);
+ DONE;
+})
;; Negation instructions
@@ -21800,7 +21885,8 @@
&& REGNO (operands[2]) != REGNO (operands[1])
&& peep2_reg_dead_p (2, operands[1])
&& peep2_reg_dead_p (4, operands[2])
- && !reg_overlap_mentioned_p (operands[0], operands[3])"
+ && !reg_overlap_mentioned_p (operands[0], operands[3])
+ && !reg_mentioned_p (operands[2], operands[6])"
[(parallel [(set (match_dup 7) (match_dup 8))
(set (match_dup 1) (match_dup 9))])
(set (match_dup 0) (match_dup 3))
@@ -23960,6 +24046,26 @@
(symbol_ref "memory_address_length (operands[0], false)"))
(set_attr "memory" "none")])
+(define_insn "prefetchi"
+ [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
+ (match_operand:SI 1 "const_int_operand")]
+ UNSPECV_PREFETCHI)]
+ "TARGET_PREFETCHI && TARGET_64BIT"
+{
+ static const char * const patterns[2] = {
+ "prefetchit1\t%0", "prefetchit0\t%0"
+ };
+
+ int locality = INTVAL (operands[1]);
+ gcc_assert (IN_RANGE (locality, 2, 3));
+
+ return patterns[locality - 2];
+}
+ [(set_attr "type" "sse")
+ (set (attr "length_address")
+ (symbol_ref "memory_address_length (operands[0], false)"))
+ (set_attr "memory" "none")])
+
(define_expand "stack_protect_set"
[(match_operand 0 "memory_operand")
(match_operand 1 "memory_operand")]
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 6e07b89..fb4e57a 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -109,8 +109,8 @@ TargetVariable
enum cmodel ix86_cmodel = CM_32
;; -mabi=
-TargetSave
-enum calling_abi x_ix86_abi
+TargetVariable
+enum calling_abi ix86_abi = SYSV_ABI
;; -masm=
TargetSave
@@ -1229,3 +1229,40 @@ mavxneconvert
Target Mask(ISA2_AVXNECONVERT) Var(ix86_isa_flags2) Save
Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, and
AVXNECONVERT build-in functions and code generation.
+
+mcmpccxadd
+Target Mask(ISA2_CMPCCXADD) Var(ix86_isa_flags2) Save
+Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, and
+CMPCCXADD build-in functions and code generation.
+
+mamx-fp16
+Target Mask(ISA2_AMX_FP16) Var(ix86_isa_flags2) Save
+Support AMX-FP16 built-in functions and code generation.
+
+mprefetchi
+Target Mask(ISA2_PREFETCHI) Var(ix86_isa_flags2) Save
+Support PREFETCHI built-in functions and code generation.
+
+mraoint
+Target Mask(ISA2_RAOINT) Var(ix86_isa_flags2) Save
+Support RAOINT built-in functions and code generation.
+
+munroll-only-small-loops
+Target Var(ix86_unroll_only_small_loops) Init(0) Save
+Enable conservative small loop unrolling.
+
+mlam=
+Target RejectNegative Joined Enum(lam_type) Var(ix86_lam_type) Init(lam_none)
+-mlam=[none|u48|u57] Instrument meta data position in user data pointers.
+
+Enum
+Name(lam_type) Type(enum lam_type) UnknownError(unknown lam type %qs)
+
+EnumValue
+Enum(lam_type) String(none) Value(lam_none)
+
+EnumValue
+Enum(lam_type) String(u48) Value(lam_u48)
+
+EnumValue
+Enum(lam_type) String(u57) Value(lam_u57)
diff --git a/gcc/config/i386/immintrin.h b/gcc/config/i386/immintrin.h
index 8629aba..da0f0bc 100644
--- a/gcc/config/i386/immintrin.h
+++ b/gcc/config/i386/immintrin.h
@@ -136,4 +136,6 @@
#include <keylockerintrin.h>
+#include <amxfp16intrin.h>
+
#endif /* _IMMINTRIN_H_INCLUDED */
diff --git a/gcc/config/i386/intelmic-mkoffload.cc b/gcc/config/i386/intelmic-mkoffload.cc
deleted file mode 100644
index 5deddff..0000000
--- a/gcc/config/i386/intelmic-mkoffload.cc
+++ /dev/null
@@ -1,728 +0,0 @@
-/* Offload image generation tool for Intel MIC devices.
-
- Copyright (C) 2014-2022 Free Software Foundation, Inc.
-
- Contributed by Ilya Verbin <ilya.verbin@intel.com>.
-
- This file is part of GCC.
-
- GCC is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- GCC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
-
-#define IN_TARGET_CODE 1
-
-#include "config.h"
-#include <libgen.h>
-#include "system.h"
-#include "coretypes.h"
-#include "obstack.h"
-#include "intl.h"
-#include "diagnostic.h"
-#include "collect-utils.h"
-#include "intelmic-offload.h"
-
-const char tool_name[] = "intelmic mkoffload";
-
-const char image_section_name[] = ".gnu.offload_images";
-const char *symbols[3] = { "__offload_image_intelmic_start",
- "__offload_image_intelmic_end",
- "__offload_image_intelmic_size" };
-const char *out_obj_filename = NULL;
-
-int num_temps = 0;
-const int MAX_NUM_TEMPS = 10;
-const char *temp_files[MAX_NUM_TEMPS];
-
-enum offload_abi offload_abi = OFFLOAD_ABI_UNSET;
-
-/* Delete tempfiles and exit function. */
-
-void
-tool_cleanup (bool from_signal ATTRIBUTE_UNUSED)
-{
- for (int i = 0; i < num_temps; i++)
- maybe_unlink (temp_files[i]);
-}
-
-static void
-mkoffload_cleanup (void)
-{
- tool_cleanup (false);
-}
-
-/* Unlink FILE unless requested otherwise. */
-
-void
-maybe_unlink (const char *file)
-{
- if (!save_temps)
- {
- if (unlink_if_ordinary (file)
- && errno != ENOENT)
- fatal_error (input_location, "deleting file %s: %m", file);
- }
- else if (verbose)
- fprintf (stderr, "[Leaving %s]\n", file);
-}
-
-/* Add or change the value of an environment variable, outputting the
- change to standard error if in verbose mode. */
-static void
-xputenv (const char *string)
-{
- if (verbose)
- fprintf (stderr, "%s\n", string);
- putenv (CONST_CAST (char *, string));
-}
-
-/* Parse STR, saving found tokens into PVALUES and return their number.
- Tokens are assumed to be delimited by ':'. */
-static unsigned
-parse_env_var (const char *str, char ***pvalues)
-{
- const char *curval, *nextval;
- char **values;
- unsigned num = 1, i;
-
- curval = strchr (str, ':');
- while (curval)
- {
- num++;
- curval = strchr (curval + 1, ':');
- }
-
- values = (char **) xmalloc (num * sizeof (char *));
- curval = str;
- nextval = strchr (curval, ':');
- if (nextval == NULL)
- nextval = strchr (curval, '\0');
-
- for (i = 0; i < num; i++)
- {
- int l = nextval - curval;
- values[i] = (char *) xmalloc (l + 1);
- memcpy (values[i], curval, l);
- values[i][l] = 0;
- curval = nextval + 1;
- nextval = strchr (curval, ':');
- if (nextval == NULL)
- nextval = strchr (curval, '\0');
- }
- *pvalues = values;
- return num;
-}
-
-/* Auxiliary function that frees elements of PTR and PTR itself.
- N is number of elements to be freed. If PTR is NULL, nothing is freed.
- If an element is NULL, subsequent elements are not freed. */
-static void
-free_array_of_ptrs (void **ptr, unsigned n)
-{
- unsigned i;
- if (!ptr)
- return;
- for (i = 0; i < n; i++)
- {
- if (!ptr[i])
- break;
- free (ptr[i]);
- }
- free (ptr);
- return;
-}
-
-/* Check whether NAME can be accessed in MODE. This is like access,
- except that it never considers directories to be executable. */
-static int
-access_check (const char *name, int mode)
-{
- if (mode == X_OK)
- {
- struct stat st;
-
- if (stat (name, &st) < 0 || S_ISDIR (st.st_mode))
- return -1;
- }
-
- return access (name, mode);
-}
-
-/* Find target compiler using a path from COLLECT_GCC or COMPILER_PATH. */
-static char *
-find_target_compiler (const char *name)
-{
- bool found = false;
- char **paths = NULL;
- unsigned n_paths, i;
- char *target_compiler;
- const char *collect_gcc = getenv ("COLLECT_GCC");
- const char *gcc_path = dirname (ASTRDUP (collect_gcc));
- const char *gcc_exec = basename (ASTRDUP (collect_gcc));
-
- if (strcmp (gcc_exec, collect_gcc) == 0)
- {
- /* collect_gcc has no path, so it was found in PATH. Make sure we also
- find accel-gcc in PATH. */
- target_compiler = XDUPVEC (char, name, strlen (name) + 1);
- found = true;
- goto out;
- }
-
- target_compiler = concat (gcc_path, "/", name, NULL);
- if (access_check (target_compiler, X_OK) == 0)
- {
- found = true;
- goto out;
- }
-
- n_paths = parse_env_var (getenv ("COMPILER_PATH"), &paths);
- for (i = 0; i < n_paths; i++)
- {
- size_t len = strlen (paths[i]) + 1 + strlen (name) + 1;
- target_compiler = XRESIZEVEC (char, target_compiler, len);
- sprintf (target_compiler, "%s/%s", paths[i], name);
- if (access_check (target_compiler, X_OK) == 0)
- {
- found = true;
- break;
- }
- }
-
-out:
- free_array_of_ptrs ((void **) paths, n_paths);
- return found ? target_compiler : NULL;
-}
-
-static void
-compile_for_target (struct obstack *argv_obstack)
-{
- switch (offload_abi)
- {
- case OFFLOAD_ABI_LP64:
- obstack_ptr_grow (argv_obstack, "-m64");
- break;
- case OFFLOAD_ABI_ILP32:
- obstack_ptr_grow (argv_obstack, "-m32");
- break;
- default:
- gcc_unreachable ();
- }
- obstack_ptr_grow (argv_obstack, NULL);
- char **argv = XOBFINISH (argv_obstack, char **);
-
- /* Save environment variables. */
- const char *epath = getenv ("GCC_EXEC_PREFIX");
- const char *cpath = getenv ("COMPILER_PATH");
- const char *lpath = getenv ("LIBRARY_PATH");
- const char *rpath = getenv ("LD_RUN_PATH");
- unsetenv ("GCC_EXEC_PREFIX");
- unsetenv ("COMPILER_PATH");
- unsetenv ("LIBRARY_PATH");
- unsetenv ("LD_RUN_PATH");
-
- fork_execute (argv[0], argv, false, NULL);
- obstack_free (argv_obstack, NULL);
-
- /* Restore environment variables. */
- xputenv (concat ("GCC_EXEC_PREFIX=", epath, NULL));
- xputenv (concat ("COMPILER_PATH=", cpath, NULL));
- xputenv (concat ("LIBRARY_PATH=", lpath, NULL));
- xputenv (concat ("LD_RUN_PATH=", rpath, NULL));
-}
-
-/* Generates object file with the descriptor for the target library. */
-static const char *
-generate_target_descr_file (const char *target_compiler)
-{
- char *dump_filename = concat (dumppfx, "_target_descr.c", NULL);
- const char *src_filename = save_temps
- ? dump_filename
- : make_temp_file ("_target_descr.c");
- const char *obj_filename = save_temps
- ? concat (dumppfx, "_target_descr.o", NULL)
- : make_temp_file ("_target_descr.o");
- temp_files[num_temps++] = src_filename;
- temp_files[num_temps++] = obj_filename;
- FILE *src_file = fopen (src_filename, "w");
-
- if (!src_file)
- fatal_error (input_location, "cannot open '%s'", src_filename);
-
- fprintf (src_file,
- "extern const void *const __offload_funcs_end[];\n"
- "extern const void *const __offload_vars_end[];\n\n"
-
- "const void *const __offload_func_table[0]\n"
- "__attribute__ ((__used__, visibility (\"hidden\"),\n"
- "section (\".gnu.offload_funcs\"))) = { };\n\n"
-
- "const void *const __offload_var_table[0]\n"
- "__attribute__ ((__used__, visibility (\"hidden\"),\n"
- "section (\".gnu.offload_vars\"))) = { };\n\n"
-
- "const void *const __OFFLOAD_TARGET_TABLE__[]\n"
- "__attribute__ ((__used__, visibility (\"hidden\"))) = {\n"
- " &__offload_func_table, &__offload_funcs_end,\n"
- " &__offload_var_table, &__offload_vars_end\n"
- "};\n\n");
-
- fprintf (src_file,
- "#ifdef __cplusplus\n"
- "extern \"C\"\n"
- "#endif\n"
- "void target_register_lib (const void *);\n\n"
-
- "__attribute__((constructor))\n"
- "static void\n"
- "init (void)\n"
- "{\n"
- " target_register_lib (__OFFLOAD_TARGET_TABLE__);\n"
- "}\n");
- fclose (src_file);
-
- struct obstack argv_obstack;
- obstack_init (&argv_obstack);
- obstack_ptr_grow (&argv_obstack, target_compiler);
- if (save_temps)
- obstack_ptr_grow (&argv_obstack, "-save-temps");
- if (verbose)
- obstack_ptr_grow (&argv_obstack, "-v");
- obstack_ptr_grow (&argv_obstack, "-dumpdir");
- obstack_ptr_grow (&argv_obstack, "");
- obstack_ptr_grow (&argv_obstack, "-dumpbase");
- obstack_ptr_grow (&argv_obstack, dump_filename);
- obstack_ptr_grow (&argv_obstack, "-dumpbase-ext");
- obstack_ptr_grow (&argv_obstack, ".c");
- obstack_ptr_grow (&argv_obstack, "-c");
- obstack_ptr_grow (&argv_obstack, "-shared");
- obstack_ptr_grow (&argv_obstack, "-fPIC");
- obstack_ptr_grow (&argv_obstack, src_filename);
- obstack_ptr_grow (&argv_obstack, "-o");
- obstack_ptr_grow (&argv_obstack, obj_filename);
- compile_for_target (&argv_obstack);
-
- return obj_filename;
-}
-
-/* Generates object file with __offload_*_end symbols for the target
- library. */
-static const char *
-generate_target_offloadend_file (const char *target_compiler)
-{
- char *dump_filename = concat (dumppfx, "_target_offloadend.c", NULL);
- const char *src_filename = save_temps
- ? dump_filename
- : make_temp_file ("_target_offloadend.c");
- const char *obj_filename = save_temps
- ? concat (dumppfx, "_target_offloadend.o", NULL)
- : make_temp_file ("_target_offloadend.o");
- temp_files[num_temps++] = src_filename;
- temp_files[num_temps++] = obj_filename;
- FILE *src_file = fopen (src_filename, "w");
-
- if (!src_file)
- fatal_error (input_location, "cannot open '%s'", src_filename);
-
- fprintf (src_file,
- "const void *const __offload_funcs_end[0]\n"
- "__attribute__ ((__used__, visibility (\"hidden\"),\n"
- "section (\".gnu.offload_funcs\"))) = { };\n\n"
-
- "const void *const __offload_vars_end[0]\n"
- "__attribute__ ((__used__, visibility (\"hidden\"),\n"
- "section (\".gnu.offload_vars\"))) = { };\n");
- fclose (src_file);
-
- struct obstack argv_obstack;
- obstack_init (&argv_obstack);
- obstack_ptr_grow (&argv_obstack, target_compiler);
- if (save_temps)
- obstack_ptr_grow (&argv_obstack, "-save-temps");
- if (verbose)
- obstack_ptr_grow (&argv_obstack, "-v");
- obstack_ptr_grow (&argv_obstack, "-dumpdir");
- obstack_ptr_grow (&argv_obstack, "");
- obstack_ptr_grow (&argv_obstack, "-dumpbase");
- obstack_ptr_grow (&argv_obstack, dump_filename);
- obstack_ptr_grow (&argv_obstack, "-dumpbase-ext");
- obstack_ptr_grow (&argv_obstack, ".c");
- obstack_ptr_grow (&argv_obstack, "-c");
- obstack_ptr_grow (&argv_obstack, "-shared");
- obstack_ptr_grow (&argv_obstack, "-fPIC");
- obstack_ptr_grow (&argv_obstack, src_filename);
- obstack_ptr_grow (&argv_obstack, "-o");
- obstack_ptr_grow (&argv_obstack, obj_filename);
- compile_for_target (&argv_obstack);
-
- return obj_filename;
-}
-
-/* Generates object file with the host side descriptor. */
-static const char *
-generate_host_descr_file (const char *host_compiler, uint32_t omp_requires)
-{
- char *dump_filename = concat (dumppfx, "_host_descr.c", NULL);
- const char *src_filename = save_temps
- ? dump_filename
- : make_temp_file ("_host_descr.c");
- const char *obj_filename = save_temps
- ? concat (dumppfx, "_host_descr.o", NULL)
- : make_temp_file ("_host_descr.o");
- temp_files[num_temps++] = src_filename;
- temp_files[num_temps++] = obj_filename;
- FILE *src_file = fopen (src_filename, "w");
-
- if (!src_file)
- fatal_error (input_location, "cannot open '%s'", src_filename);
-
- fprintf (src_file, "#include <stdint.h>\n\n");
-
- fprintf (src_file,
- "extern const void *const __OFFLOAD_TABLE__;\n"
- "extern const void *const __offload_image_intelmic_start;\n"
- "extern const void *const __offload_image_intelmic_end;\n\n"
-
- "static const struct intelmic_data {\n"
- " uintptr_t omp_requires_mask;\n"
- " const void *const image_start;\n"
- " const void *const image_end;\n"
- "} intelmic_data = {\n"
- " %d,\n"
- " &__offload_image_intelmic_start, &__offload_image_intelmic_end\n"
- "};\n\n", omp_requires);
-
- fprintf (src_file,
- "#ifdef __cplusplus\n"
- "extern \"C\"\n"
- "#endif\n"
- "void GOMP_offload_register_ver (unsigned, const void *, int, const void *);\n"
- "#ifdef __cplusplus\n"
- "extern \"C\"\n"
- "#endif\n"
- "void GOMP_offload_unregister_ver (unsigned, const void *, int, const void *);\n\n"
-
- "__attribute__((constructor))\n"
- "static void\n"
- "init (void)\n"
- "{\n"
- " GOMP_offload_register_ver (%#x, &__OFFLOAD_TABLE__, %d, &intelmic_data);\n"
- "}\n\n",
- GOMP_VERSION_PACK (GOMP_VERSION, GOMP_VERSION_INTEL_MIC),
- GOMP_DEVICE_INTEL_MIC);
-
- fprintf (src_file,
- "__attribute__((destructor))\n"
- "static void\n"
- "fini (void)\n"
- "{\n"
- " GOMP_offload_unregister_ver (%#x, &__OFFLOAD_TABLE__, %d, &intelmic_data);\n"
- "}\n",
- GOMP_VERSION_PACK (GOMP_VERSION, GOMP_VERSION_INTEL_MIC),
- GOMP_DEVICE_INTEL_MIC);
-
- fclose (src_file);
-
- struct obstack argv_obstack;
- obstack_init (&argv_obstack);
- obstack_ptr_grow (&argv_obstack, host_compiler);
- if (save_temps)
- obstack_ptr_grow (&argv_obstack, "-save-temps");
- if (verbose)
- obstack_ptr_grow (&argv_obstack, "-v");
- obstack_ptr_grow (&argv_obstack, "-dumpdir");
- obstack_ptr_grow (&argv_obstack, "");
- obstack_ptr_grow (&argv_obstack, "-dumpbase");
- obstack_ptr_grow (&argv_obstack, dump_filename);
- obstack_ptr_grow (&argv_obstack, "-dumpbase-ext");
- obstack_ptr_grow (&argv_obstack, ".c");
- obstack_ptr_grow (&argv_obstack, "-c");
- obstack_ptr_grow (&argv_obstack, "-fPIC");
- obstack_ptr_grow (&argv_obstack, "-shared");
- switch (offload_abi)
- {
- case OFFLOAD_ABI_LP64:
- obstack_ptr_grow (&argv_obstack, "-m64");
- break;
- case OFFLOAD_ABI_ILP32:
- obstack_ptr_grow (&argv_obstack, "-m32");
- break;
- default:
- gcc_unreachable ();
- }
- obstack_ptr_grow (&argv_obstack, src_filename);
- obstack_ptr_grow (&argv_obstack, "-o");
- obstack_ptr_grow (&argv_obstack, obj_filename);
- obstack_ptr_grow (&argv_obstack, NULL);
-
- char **argv = XOBFINISH (&argv_obstack, char **);
- fork_execute (argv[0], argv, false, NULL);
- obstack_free (&argv_obstack, NULL);
-
- return obj_filename;
-}
-
-static const char *
-prepare_target_image (const char *target_compiler, int argc, char **argv, uint32_t *omp_requires)
-{
- const char *target_descr_filename
- = generate_target_descr_file (target_compiler);
- const char *target_offloadend_filename
- = generate_target_offloadend_file (target_compiler);
-
- char *opt1
- = XALLOCAVEC (char, sizeof ("-Wl,") + strlen (target_descr_filename));
- char *opt2
- = XALLOCAVEC (char, sizeof ("-Wl,") + strlen (target_offloadend_filename));
- sprintf (opt1, "-Wl,%s", target_descr_filename);
- sprintf (opt2, "-Wl,%s", target_offloadend_filename);
-
- char *dump_filename = concat (dumppfx, ".mkoffload", NULL);
- const char *target_so_filename = save_temps
- ? concat (dumppfx, "_offload_intelmic.so", NULL)
- : make_temp_file ("_offload_intelmic.so");
- temp_files[num_temps++] = target_so_filename;
- struct obstack argv_obstack;
- obstack_init (&argv_obstack);
- obstack_ptr_grow (&argv_obstack, target_compiler);
- if (save_temps)
- obstack_ptr_grow (&argv_obstack, "-save-temps");
- if (verbose)
- obstack_ptr_grow (&argv_obstack, "-v");
- obstack_ptr_grow (&argv_obstack, "-xlto");
- obstack_ptr_grow (&argv_obstack, opt1);
- for (int i = 1; i < argc; i++)
- {
- if (!strcmp (argv[i], "-o") && i + 1 != argc)
- ++i;
- else
- obstack_ptr_grow (&argv_obstack, argv[i]);
- }
- obstack_ptr_grow (&argv_obstack, opt2);
- /* NB: Put -fPIC and -shared the last to create shared library. */
- obstack_ptr_grow (&argv_obstack, "-fPIC");
- obstack_ptr_grow (&argv_obstack, "-shared");
- obstack_ptr_grow (&argv_obstack, "-dumpdir");
- obstack_ptr_grow (&argv_obstack, "");
- obstack_ptr_grow (&argv_obstack, "-dumpbase");
- obstack_ptr_grow (&argv_obstack, dump_filename);
- obstack_ptr_grow (&argv_obstack, "-dumpbase-ext");
- obstack_ptr_grow (&argv_obstack, "");
- obstack_ptr_grow (&argv_obstack, "-o");
- obstack_ptr_grow (&argv_obstack, target_so_filename);
-
- char *omp_requires_file;
- if (save_temps)
- omp_requires_file = concat (dumppfx, ".mkoffload.omp_requires", NULL);
- else
- omp_requires_file = make_temp_file (".mkoffload.omp_requires");
- temp_files[num_temps++] = omp_requires_file;
- xputenv (concat ("GCC_OFFLOAD_OMP_REQUIRES_FILE=", omp_requires_file, NULL));
-
- compile_for_target (&argv_obstack);
-
- unsetenv("GCC_OFFLOAD_OMP_REQUIRES_FILE");
- FILE *in = fopen (omp_requires_file, "rb");
- if (!in)
- fatal_error (input_location, "cannot open omp_requires file %qs",
- omp_requires_file);
- if (fread (omp_requires, sizeof (*omp_requires), 1, in) != 1)
- fatal_error (input_location, "cannot read omp_requires file %qs",
- omp_requires_file);
- fclose (in);
-
- /* Run objcopy. */
- char *rename_section_opt
- = XALLOCAVEC (char, sizeof (".data=") + strlen (image_section_name));
- sprintf (rename_section_opt, ".data=%s", image_section_name);
- obstack_init (&argv_obstack);
- obstack_ptr_grow (&argv_obstack, "objcopy");
- obstack_ptr_grow (&argv_obstack, "-B");
- obstack_ptr_grow (&argv_obstack, "i386");
- obstack_ptr_grow (&argv_obstack, "-I");
- obstack_ptr_grow (&argv_obstack, "binary");
- obstack_ptr_grow (&argv_obstack, "-O");
- switch (offload_abi)
- {
- case OFFLOAD_ABI_LP64:
- obstack_ptr_grow (&argv_obstack, "elf64-x86-64");
- break;
- case OFFLOAD_ABI_ILP32:
- obstack_ptr_grow (&argv_obstack, "elf32-i386");
- break;
- default:
- gcc_unreachable ();
- }
- obstack_ptr_grow (&argv_obstack, target_so_filename);
- obstack_ptr_grow (&argv_obstack, "--rename-section");
- obstack_ptr_grow (&argv_obstack, rename_section_opt);
- obstack_ptr_grow (&argv_obstack, NULL);
- char **new_argv = XOBFINISH (&argv_obstack, char **);
- fork_execute (new_argv[0], new_argv, false, NULL);
- obstack_free (&argv_obstack, NULL);
-
- /* Objcopy has created symbols, containing the input file name with
- non-alphanumeric characters replaced by underscores.
- We are going to rename these new symbols. */
- size_t symbol_name_len = strlen (target_so_filename);
- char *symbol_name = XALLOCAVEC (char, symbol_name_len + 1);
- for (size_t i = 0; i < symbol_name_len; i++)
- {
- char c = target_so_filename[i];
- if (!ISALNUM (c))
- c = '_';
- symbol_name[i] = c;
- }
- symbol_name[symbol_name_len] = '\0';
-
- char *opt_for_objcopy[3];
- opt_for_objcopy[0] = XALLOCAVEC (char, sizeof ("_binary__start=")
- + symbol_name_len
- + strlen (symbols[0]));
- opt_for_objcopy[1] = XALLOCAVEC (char, sizeof ("_binary__end=")
- + symbol_name_len
- + strlen (symbols[1]));
- opt_for_objcopy[2] = XALLOCAVEC (char, sizeof ("_binary__size=")
- + symbol_name_len
- + strlen (symbols[2]));
- sprintf (opt_for_objcopy[0], "_binary_%s_start=%s", symbol_name, symbols[0]);
- sprintf (opt_for_objcopy[1], "_binary_%s_end=%s", symbol_name, symbols[1]);
- sprintf (opt_for_objcopy[2], "_binary_%s_size=%s", symbol_name, symbols[2]);
-
- obstack_init (&argv_obstack);
- obstack_ptr_grow (&argv_obstack, "objcopy");
- obstack_ptr_grow (&argv_obstack, target_so_filename);
- obstack_ptr_grow (&argv_obstack, "--redefine-sym");
- obstack_ptr_grow (&argv_obstack, opt_for_objcopy[0]);
- obstack_ptr_grow (&argv_obstack, "--redefine-sym");
- obstack_ptr_grow (&argv_obstack, opt_for_objcopy[1]);
- obstack_ptr_grow (&argv_obstack, "--redefine-sym");
- obstack_ptr_grow (&argv_obstack, opt_for_objcopy[2]);
- obstack_ptr_grow (&argv_obstack, NULL);
- new_argv = XOBFINISH (&argv_obstack, char **);
- fork_execute (new_argv[0], new_argv, false, NULL);
- obstack_free (&argv_obstack, NULL);
-
- return target_so_filename;
-}
-
-int
-main (int argc, char **argv)
-{
- progname = "mkoffload-intelmic";
- gcc_init_libintl ();
- diagnostic_initialize (global_dc, 0);
-
- if (atexit (mkoffload_cleanup) != 0)
- fatal_error (input_location, "atexit failed");
-
- const char *host_compiler = getenv ("COLLECT_GCC");
- if (!host_compiler)
- fatal_error (input_location, "COLLECT_GCC must be set");
-
- const char *target_driver_name = GCC_INSTALL_NAME;
- char *target_compiler = find_target_compiler (target_driver_name);
- if (target_compiler == NULL)
- fatal_error (input_location, "offload compiler %s not found",
- target_driver_name);
-
- /* We may be called with all the arguments stored in some file and
- passed with @file. Expand them into argv before processing. */
- expandargv (&argc, &argv);
-
- /* Scan the argument vector. */
- for (int i = 1; i < argc; i++)
- {
-#define STR "-foffload-abi="
- if (startswith (argv[i], STR))
- {
- if (strcmp (argv[i] + strlen (STR), "lp64") == 0)
- offload_abi = OFFLOAD_ABI_LP64;
- else if (strcmp (argv[i] + strlen (STR), "ilp32") == 0)
- offload_abi = OFFLOAD_ABI_ILP32;
- else
- fatal_error (input_location,
- "unrecognizable argument of option " STR);
- }
-#undef STR
- else if (strcmp (argv[i], "-save-temps") == 0)
- save_temps = true;
- else if (strcmp (argv[i], "-v") == 0)
- verbose = true;
- else if (strcmp (argv[i], "-dumpbase") == 0
- && i + 1 < argc)
- dumppfx = argv[++i];
- else if (strcmp (argv[i], "-o") == 0
- && i + 1 < argc)
- out_obj_filename = argv[++i];
- }
-
- if (!out_obj_filename)
- fatal_error (input_location, "output file not specified");
-
- if (!dumppfx)
- dumppfx = out_obj_filename;
-
- uint32_t omp_requires;
-
- const char *target_so_filename
- = prepare_target_image (target_compiler, argc, argv, &omp_requires);
-
- const char *host_descr_filename
- = generate_host_descr_file (host_compiler, omp_requires);
-
- /* Perform partial linking for the target image and host side descriptor.
- As a result we'll get a finalized object file with all offload data. */
- struct obstack argv_obstack;
- obstack_init (&argv_obstack);
- obstack_ptr_grow (&argv_obstack, "ld");
- obstack_ptr_grow (&argv_obstack, "-m");
- switch (offload_abi)
- {
- case OFFLOAD_ABI_LP64:
- obstack_ptr_grow (&argv_obstack, "elf_x86_64");
- break;
- case OFFLOAD_ABI_ILP32:
- obstack_ptr_grow (&argv_obstack, "elf_i386");
- break;
- default:
- gcc_unreachable ();
- }
- obstack_ptr_grow (&argv_obstack, "--relocatable");
- obstack_ptr_grow (&argv_obstack, host_descr_filename);
- obstack_ptr_grow (&argv_obstack, target_so_filename);
- obstack_ptr_grow (&argv_obstack, "-o");
- obstack_ptr_grow (&argv_obstack, out_obj_filename);
- obstack_ptr_grow (&argv_obstack, NULL);
- char **new_argv = XOBFINISH (&argv_obstack, char **);
- fork_execute (new_argv[0], new_argv, false, NULL);
- obstack_free (&argv_obstack, NULL);
-
- /* Run objcopy on the resultant object file to localize generated symbols
- to avoid conflicting between different DSO and an executable. */
- obstack_init (&argv_obstack);
- obstack_ptr_grow (&argv_obstack, "objcopy");
- obstack_ptr_grow (&argv_obstack, "-L");
- obstack_ptr_grow (&argv_obstack, symbols[0]);
- obstack_ptr_grow (&argv_obstack, "-L");
- obstack_ptr_grow (&argv_obstack, symbols[1]);
- obstack_ptr_grow (&argv_obstack, "-L");
- obstack_ptr_grow (&argv_obstack, symbols[2]);
- obstack_ptr_grow (&argv_obstack, out_obj_filename);
- obstack_ptr_grow (&argv_obstack, NULL);
- new_argv = XOBFINISH (&argv_obstack, char **);
- fork_execute (new_argv[0], new_argv, false, NULL);
- obstack_free (&argv_obstack, NULL);
-
- return 0;
-}
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index d5134cc..c3afc6b 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -133,7 +133,8 @@
(match_operand:MMXMODE 1 "nonimm_or_0_operand"
"rCo,rC,C,rm,rC,C ,!y,m ,?!y,?!y,r ,C,v,m,v,v,r,*x,!y"))]
"(TARGET_MMX || TARGET_MMX_WITH_SSE)
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ && !(MEM_P (operands[0]) && MEM_P (operands[1]))
+ && ix86_hardreg_mov_ok (operands[0], operands[1])"
{
switch (get_attr_type (insn))
{
@@ -286,7 +287,8 @@
"=r ,m ,v,v,v,m,r,v")
(match_operand:V_32 1 "general_operand"
"rmC,rC,C,v,m,v,v,r"))]
- "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ "!(MEM_P (operands[0]) && MEM_P (operands[1]))
+ && ix86_hardreg_mov_ok (operands[0], operands[1])"
{
switch (get_attr_type (insn))
{
@@ -1707,7 +1709,8 @@
[(match_operand:V2SF 1 "register_operand")
(match_dup 2)]
UNSPEC_ROUND))]
- "TARGET_SSE4_1 && !flag_trapping_math"
+ "TARGET_SSE4_1 && !flag_trapping_math
+ && TARGET_MMX_WITH_SSE"
"operands[2] = GEN_INT (ROUND_TRUNC | ROUND_NO_EXC);")
(define_insn "*mmx_roundv2sf2"
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index c4141a9..f995503 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -610,6 +610,21 @@
return false;
})
+(define_predicate "local_func_symbolic_operand"
+ (match_operand 0 "local_symbolic_operand")
+{
+ if (GET_CODE (op) == CONST
+ && GET_CODE (XEXP (op, 0)) == PLUS
+ && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
+ op = XEXP (XEXP (op, 0), 0);
+
+ if (GET_CODE (op) == SYMBOL_REF
+ && !SYMBOL_REF_FUNCTION_P (op))
+ return false;
+
+ return true;
+})
+
;; Test for a legitimate @GOTOFF operand.
;;
;; VxWorks does not impose a fixed gap between segments; the run-time
@@ -1220,6 +1235,13 @@
(ior (match_operand 0 "register_operand")
(match_operand 0 "vector_memory_operand")))
+; Return true when OP is register_operand, vector_memory_operand
+; or const_vector.
+(define_predicate "vector_or_const_vector_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "vector_memory_operand")
+ (match_code "const_vector")))
+
(define_predicate "bcst_mem_operand"
(and (match_code "vec_duplicate")
(and (match_test "TARGET_AVX512F")
diff --git a/gcc/config/i386/prfchiintrin.h b/gcc/config/i386/prfchiintrin.h
new file mode 100644
index 0000000..996a4be
--- /dev/null
+++ b/gcc/config/i386/prfchiintrin.h
@@ -0,0 +1,61 @@
+/* Copyright (C) 2022 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#if !defined _X86GPRINTRIN_H_INCLUDED
+# error "Never use <prfchiintrin.h> directly; include <x86gprintrin.h> instead."
+#endif
+
+#ifndef _PRFCHIINTRIN_H_INCLUDED
+#define _PRFCHIINTRIN_H_INCLUDED
+
+#ifdef __x86_64__
+
+
+#ifndef __PREFETCHI__
+#pragma GCC push_options
+#pragma GCC target("prefetchi")
+#define __DISABLE_PREFETCHI__
+#endif /* __PREFETCHI__ */
+
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_m_prefetchit0 (void* __P)
+{
+ __builtin_ia32_prefetchi (__P, 3);
+}
+
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_m_prefetchit1 (void* __P)
+{
+ __builtin_ia32_prefetchi (__P, 2);
+}
+
+#ifdef __DISABLE_PREFETCHI__
+#undef __DISABLE_PREFETCHI__
+#pragma GCC pop_options
+#endif /* __DISABLE_PREFETCHI__ */
+
+#endif /* __x86_64__ */
+
+#endif /* _PRFCHIINTRIN_H_INCLUDED */
diff --git a/gcc/config/i386/raointintrin.h b/gcc/config/i386/raointintrin.h
new file mode 100644
index 0000000..76506af4
--- /dev/null
+++ b/gcc/config/i386/raointintrin.h
@@ -0,0 +1,100 @@
+/* Copyright (C) 2019-2022 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _X86GPRINTRIN_H_INCLUDED
+#error "Never use <raointintrin.h> directly; include <x86gprintrin.h> instead."
+#endif // _X86GPRINTRIN_H_INCLUDED
+
+#ifndef __RAOINTINTRIN_H_INCLUDED
+#define __RAOINTINTRIN_H_INCLUDED
+
+#ifndef __RAOINT__
+#pragma GCC push_options
+#pragma GCC target("raoint")
+#define __DISABLE_RAOINT__
+#endif /* __RAOINT__ */
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_aadd_i32 (int *__A, int __B)
+{
+ __builtin_ia32_aadd32 ((int *)__A, __B);
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_aand_i32 (int *__A, int __B)
+{
+ __builtin_ia32_aand32 ((int *)__A, __B);
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_aor_i32 (int *__A, int __B)
+{
+ __builtin_ia32_aor32 ((int *)__A, __B);
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_axor_i32 (int *__A, int __B)
+{
+ __builtin_ia32_axor32 ((int *)__A, __B);
+}
+
+#ifdef __x86_64__
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_aadd_i64 (long long *__A, long long __B)
+{
+ __builtin_ia32_aadd64 ((long long *)__A, __B);
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_aand_i64 (long long *__A, long long __B)
+{
+ __builtin_ia32_aand64 ((long long *)__A, __B);
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_aor_i64 (long long *__A, long long __B)
+{
+ __builtin_ia32_aor64 ((long long *)__A, __B);
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_axor_i64 (long long *__A, long long __B)
+{
+ __builtin_ia32_axor64 ((long long *)__A, __B);
+}
+#endif /* __x86_64__ */
+
+#ifdef __DISABLE_RAOINT__
+#undef __DISABLE_RAOINT__
+#pragma GCC pop_options
+#endif /* __DISABLE_RAOINT__ */
+
+#endif /* __RAOINTINTRIN_H_INCLUDED */
diff --git a/gcc/config/i386/smmintrin.h b/gcc/config/i386/smmintrin.h
index eb6a451..47fd9b8 100644
--- a/gcc/config/i386/smmintrin.h
+++ b/gcc/config/i386/smmintrin.h
@@ -365,17 +365,18 @@ _mm_insert_ps (__m128 __D, __m128 __S, const int __N)
extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_extract_ps (__m128 __X, const int __N)
{
- union { int i; float f; } __tmp;
- __tmp.f = __builtin_ia32_vec_ext_v4sf ((__v4sf)__X, __N);
- return __tmp.i;
+ union { int __i; float __f; } __tmp;
+ __tmp.__f = __builtin_ia32_vec_ext_v4sf ((__v4sf)__X, __N);
+ return __tmp.__i;
}
#else
#define _mm_extract_ps(X, N) \
(__extension__ \
({ \
- union { int i; float f; } __tmp; \
- __tmp.f = __builtin_ia32_vec_ext_v4sf ((__v4sf)(__m128)(X), (int)(N)); \
- __tmp.i; \
+ union { int __i; float __f; } __tmp; \
+ __tmp.__f = __builtin_ia32_vec_ext_v4sf ((__v4sf)(__m128)(X), \
+ (int)(N)); \
+ __tmp.__i; \
}))
#endif
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index fa93ae7..de632b2 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -4311,7 +4311,7 @@
[(set (match_operand:<sseintvecmode> 0 "register_operand")
(match_operator:<sseintvecmode> 1 ""
[(match_operand:VI_256 2 "register_operand")
- (match_operand:VI_256 3 "nonimmediate_operand")]))]
+ (match_operand:VI_256 3 "nonimmediate_or_const_vector_operand")]))]
"TARGET_AVX2"
{
bool ok = ix86_expand_int_vec_cmp (operands);
@@ -4323,7 +4323,7 @@
[(set (match_operand:<sseintvecmode> 0 "register_operand")
(match_operator:<sseintvecmode> 1 ""
[(match_operand:VI124_128 2 "register_operand")
- (match_operand:VI124_128 3 "vector_operand")]))]
+ (match_operand:VI124_128 3 "vector_or_const_vector_operand")]))]
"TARGET_SSE2"
{
bool ok = ix86_expand_int_vec_cmp (operands);
@@ -4335,7 +4335,7 @@
[(set (match_operand:V2DI 0 "register_operand")
(match_operator:V2DI 1 ""
[(match_operand:V2DI 2 "register_operand")
- (match_operand:V2DI 3 "vector_operand")]))]
+ (match_operand:V2DI 3 "vector_or_const_vector_operand")]))]
"TARGET_SSE4_2"
{
bool ok = ix86_expand_int_vec_cmp (operands);
@@ -4397,7 +4397,7 @@
[(set (match_operand:<sseintvecmode> 0 "register_operand")
(match_operator:<sseintvecmode> 1 ""
[(match_operand:VI_256 2 "register_operand")
- (match_operand:VI_256 3 "nonimmediate_operand")]))]
+ (match_operand:VI_256 3 "nonimmediate_or_const_vector_operand")]))]
"TARGET_AVX2"
{
bool ok = ix86_expand_int_vec_cmp (operands);
@@ -4409,7 +4409,7 @@
[(set (match_operand:<sseintvecmode> 0 "register_operand")
(match_operator:<sseintvecmode> 1 ""
[(match_operand:VI124_128 2 "register_operand")
- (match_operand:VI124_128 3 "vector_operand")]))]
+ (match_operand:VI124_128 3 "vector_or_const_vector_operand")]))]
"TARGET_SSE2"
{
bool ok = ix86_expand_int_vec_cmp (operands);
@@ -4421,7 +4421,7 @@
[(set (match_operand:V2DI 0 "register_operand")
(match_operator:V2DI 1 ""
[(match_operand:V2DI 2 "register_operand")
- (match_operand:V2DI 3 "vector_operand")]))]
+ (match_operand:V2DI 3 "vector_or_const_vector_operand")]))]
"TARGET_SSE4_2"
{
bool ok = ix86_expand_int_vec_cmp (operands);
@@ -12203,7 +12203,7 @@
(const_int 6) (const_int 14)])))]
"TARGET_AVX512F"
"vmovddup\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
- [(set_attr "type" "sselog")
+ [(set_attr "type" "sselog1")
(set_attr "prefix" "evex")
(set_attr "mode" "V8DF")])
@@ -12234,7 +12234,7 @@
(const_int 2) (const_int 6)])))]
"TARGET_AVX && <mask_avx512vl_condition>"
"vmovddup\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
- [(set_attr "type" "sselog")
+ [(set_attr "type" "sselog1")
(set_attr "prefix" "<mask_prefix>")
(set_attr "mode" "V4DF")])
diff --git a/gcc/config/i386/sync.md b/gcc/config/i386/sync.md
index 92634d5..e6543a5 100644
--- a/gcc/config/i386/sync.md
+++ b/gcc/config/i386/sync.md
@@ -37,6 +37,12 @@
UNSPECV_CMPXCHG
UNSPECV_XCHG
UNSPECV_LOCK
+
+ ;; For CMPccXADD support
+ UNSPECV_CMPCCXADD
+
+ ;; For RAOINT support
+ UNSPECV_RAOINT
])
(define_expand "sse2_lfence"
@@ -782,6 +788,19 @@
""
"%K3xchg{<imodesuffix>}\t{%1, %0|%0, %1}")
+(define_code_iterator any_plus_logic [and ior xor plus])
+(define_code_attr plus_logic [(and "and") (ior "or") (xor "xor") (plus "add")])
+
+(define_insn "rao_a<plus_logic><mode>"
+ [(set (match_operand:SWI48 0 "memory_operand" "+m")
+ (unspec_volatile:SWI48
+ [(any_plus_logic:SWI48 (match_dup 0)
+ (match_operand:SWI48 1 "register_operand" "r"))
+ (const_int 0)] ;; MEMMODEL_RELAXED
+ UNSPECV_RAOINT))]
+ "TARGET_RAOINT"
+ "a<plus_logic>\t{%1, %0|%0, %1}")
+
(define_insn "atomic_add<mode>"
[(set (match_operand:SWI 0 "memory_operand" "+m")
(unspec_volatile:SWI
@@ -1061,3 +1080,28 @@
(any_logic:SWI (match_dup 0) (match_dup 1)))]
""
"lock{%;} %K2<logic>{<imodesuffix>}\t{%1, %0|%0, %1}")
+
+;; CMPCCXADD
+
+(define_insn "cmpccxadd_<mode>"
+ [(set (match_operand:SWI48x 0 "register_operand" "=r")
+ (unspec_volatile:SWI48x
+ [(match_operand:SWI48x 1 "memory_operand" "+m")
+ (match_operand:SWI48x 2 "register_operand" "0")
+ (match_operand:SWI48x 3 "register_operand" "r")
+ (match_operand:SI 4 "const_0_to_15_operand" "n")]
+ UNSPECV_CMPCCXADD))
+ (set (match_dup 1)
+ (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_CMPCCXADD))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_CMPCCXADD && TARGET_64BIT"
+{
+ char buf[128];
+ const char *ops = "cmp%sxadd\t{%%3, %%0, %%1|%%1, %%0, %%3}";
+ char const *cc[16] = {"o" ,"no", "b", "nb", "z", "nz", "be", "nbe",
+ "s", "ns", "p", "np", "l", "nl", "le", "nle"};
+
+ snprintf (buf, sizeof (buf), ops, cc[INTVAL (operands[4])]);
+ output_asm_insn (buf, operands);
+ return "";
+})
diff --git a/gcc/config/i386/t-intelmic b/gcc/config/i386/t-intelmic
deleted file mode 100644
index 95d7e53..0000000
--- a/gcc/config/i386/t-intelmic
+++ /dev/null
@@ -1,10 +0,0 @@
-CFLAGS-mkoffload.o += $(DRIVER_DEFINES) -DGCC_INSTALL_NAME=\"$(GCC_INSTALL_NAME)\"
-
-mkoffload.o: $(srcdir)/config/i386/intelmic-mkoffload.cc
- $(COMPILE) $<
- $(POSTCOMPILE)
-ALL_HOST_OBJS += mkoffload.o
-
-mkoffload$(exeext): mkoffload.o collect-utils.o libcommon-target.a $(LIBIBERTY) $(LIBDEPS)
- $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
- mkoffload.o collect-utils.o libcommon-target.a $(LIBIBERTY) $(LIBS)
diff --git a/gcc/config/i386/t-omp-device b/gcc/config/i386/t-omp-device
deleted file mode 100644
index cfb41ed..0000000
--- a/gcc/config/i386/t-omp-device
+++ /dev/null
@@ -1,6 +0,0 @@
-omp-device-properties-i386: $(srcdir)/config/i386/i386-options.cc
- echo kind: cpu > $@
- echo arch: intel_mic x86 x86_64 i386 i486 i586 i686 ia32 >> $@
- echo isa: sse4 `sed -n '/^static struct ix86_target_opts isa2\?_opts\[\] =/,/^};/p' \
- $(srcdir)/config/i386/i386-options.cc | \
- sed -n 's/",.*$$//;s/^ { "-m//p'` >> $@
diff --git a/gcc/config/i386/x86-tune-costs.h b/gcc/config/i386/x86-tune-costs.h
index aeaa7eb0..f01b8ee 100644
--- a/gcc/config/i386/x86-tune-costs.h
+++ b/gcc/config/i386/x86-tune-costs.h
@@ -135,6 +135,8 @@ struct processor_costs ix86_size_cost = {/* costs for tuning for size */
NULL, /* Jump alignment. */
NULL, /* Label alignment. */
NULL, /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
/* Processor costs (relative to an add) */
@@ -244,6 +246,8 @@ struct processor_costs i386_cost = { /* 386 specific costs */
"4", /* Jump alignment. */
NULL, /* Label alignment. */
"4", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
static stringop_algs i486_memcpy[2] = {
@@ -354,6 +358,8 @@ struct processor_costs i486_cost = { /* 486 specific costs */
"16", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
static stringop_algs pentium_memcpy[2] = {
@@ -462,6 +468,8 @@ struct processor_costs pentium_cost = {
"16:8:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
static const
@@ -563,6 +571,8 @@ struct processor_costs lakemont_cost = {
"16:8:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
/* PentiumPro has optimized rep instructions for blocks aligned by 8 bytes
@@ -679,6 +689,8 @@ struct processor_costs pentiumpro_cost = {
"16:11:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
static stringop_algs geode_memcpy[2] = {
@@ -786,6 +798,8 @@ struct processor_costs geode_cost = {
NULL, /* Jump alignment. */
NULL, /* Label alignment. */
NULL, /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
static stringop_algs k6_memcpy[2] = {
@@ -896,6 +910,8 @@ struct processor_costs k6_cost = {
"32:8:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"32", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
/* For some reason, Athlon deals better with REP prefix (relative to loops)
@@ -1007,6 +1023,8 @@ struct processor_costs athlon_cost = {
"16:8:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
/* K8 has optimized REP instruction for medium sized blocks, but for very
@@ -1127,6 +1145,8 @@ struct processor_costs k8_cost = {
"16:8:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
/* AMDFAM10 has optimized REP instruction for medium sized blocks, but for
@@ -1255,6 +1275,8 @@ struct processor_costs amdfam10_cost = {
"32:8:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"32", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
/* BDVER has optimized REP instruction for medium sized blocks, but for
@@ -1376,6 +1398,8 @@ const struct processor_costs bdver_cost = {
"16:8:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"11", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
@@ -1529,6 +1553,8 @@ struct processor_costs znver1_cost = {
"16", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
/* ZNVER2 has optimized REP instruction for medium sized blocks, but for
@@ -1686,6 +1712,8 @@ struct processor_costs znver2_cost = {
"16", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
struct processor_costs znver3_cost = {
@@ -1818,6 +1846,8 @@ struct processor_costs znver3_cost = {
"16", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
/* This table currently replicates znver3_cost table. */
@@ -1951,6 +1981,8 @@ struct processor_costs znver4_cost = {
"16", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
/* skylake_cost should produce code tuned for Skylake familly of CPUs. */
@@ -2075,6 +2107,8 @@ struct processor_costs skylake_cost = {
"16:11:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
/* icelake_cost should produce code tuned for Icelake family of CPUs.
@@ -2201,6 +2235,8 @@ struct processor_costs icelake_cost = {
"16:11:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
/* alderlake_cost should produce code tuned for alderlake family of CPUs. */
@@ -2321,6 +2357,8 @@ struct processor_costs alderlake_cost = {
"16:11:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
/* BTVER1 has optimized REP instruction for medium sized blocks, but for
@@ -2434,6 +2472,8 @@ const struct processor_costs btver1_cost = {
"16:8:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"11", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
static stringop_algs btver2_memcpy[2] = {
@@ -2544,6 +2584,8 @@ const struct processor_costs btver2_cost = {
"16:8:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"11", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
static stringop_algs pentium4_memcpy[2] = {
@@ -2653,6 +2695,8 @@ struct processor_costs pentium4_cost = {
NULL, /* Jump alignment. */
NULL, /* Label alignment. */
NULL, /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
static stringop_algs nocona_memcpy[2] = {
@@ -2765,6 +2809,8 @@ struct processor_costs nocona_cost = {
NULL, /* Jump alignment. */
NULL, /* Label alignment. */
NULL, /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
static stringop_algs atom_memcpy[2] = {
@@ -2875,6 +2921,8 @@ struct processor_costs atom_cost = {
"16:8:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
static stringop_algs slm_memcpy[2] = {
@@ -2985,6 +3033,8 @@ struct processor_costs slm_cost = {
"16:8:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
static stringop_algs tremont_memcpy[2] = {
@@ -3109,6 +3159,8 @@ struct processor_costs tremont_cost = {
"16:11:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
static stringop_algs intel_memcpy[2] = {
@@ -3219,6 +3271,8 @@ struct processor_costs intel_cost = {
"16:8:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
/* lujiazui_cost should produce code tuned for ZHAOXIN lujiazui CPU. */
@@ -3334,6 +3388,8 @@ struct processor_costs lujiazui_cost = {
"16:11:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
/* Generic should produce code tuned for Core-i7 (and newer chips)
@@ -3453,6 +3509,8 @@ struct processor_costs generic_cost = {
"16:11:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
/* core_cost should produce code tuned for Core familly of CPUs. */
@@ -3579,5 +3637,7 @@ struct processor_costs core_cost = {
"16:11:8", /* Jump alignment. */
"0:0:8", /* Label alignment. */
"16", /* Func alignment. */
+ 4, /* Small unroll limit. */
+ 2, /* Small unroll factor. */
};
diff --git a/gcc/config/i386/x86-tune.def b/gcc/config/i386/x86-tune.def
index 540e45d..db85de2 100644
--- a/gcc/config/i386/x86-tune.def
+++ b/gcc/config/i386/x86-tune.def
@@ -42,7 +42,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
DEF_TUNE (X86_TUNE_SCHEDULE, "schedule",
m_PENT | m_LAKEMONT | m_PPRO | m_CORE_ALL | m_BONNELL | m_SILVERMONT
| m_INTEL | m_KNL | m_KNM | m_K6_GEODE | m_AMD_MULTIPLE | m_LUJIAZUI
- | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE | m_GENERIC)
+ | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE | m_CORE_ATOM
+ | m_GENERIC)
/* X86_TUNE_PARTIAL_REG_DEPENDENCY: Enable more register renaming
on modern chips. Prefer stores affecting whole integer register
@@ -52,7 +53,7 @@ DEF_TUNE (X86_TUNE_PARTIAL_REG_DEPENDENCY, "partial_reg_dependency",
m_P4_NOCONA | m_CORE2 | m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2
| m_BONNELL | m_SILVERMONT | m_GOLDMONT | m_GOLDMONT_PLUS | m_INTEL
| m_KNL | m_KNM | m_AMD_MULTIPLE | m_LUJIAZUI | m_TREMONT
- | m_ALDERLAKE | m_GENERIC)
+ | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY: This knob promotes all store
destinations to be 128bit to allow register renaming on 128bit SSE units,
@@ -63,7 +64,7 @@ DEF_TUNE (X86_TUNE_PARTIAL_REG_DEPENDENCY, "partial_reg_dependency",
DEF_TUNE (X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY, "sse_partial_reg_dependency",
m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_AMDFAM10
| m_BDVER | m_ZNVER | m_LUJIAZUI | m_TREMONT | m_ALDERLAKE
- | m_GENERIC)
+ | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY: This knob avoids
partial write to the destination in scalar SSE conversion from FP
@@ -71,20 +72,23 @@ DEF_TUNE (X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY, "sse_partial_reg_dependency",
DEF_TUNE (X86_TUNE_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY,
"sse_partial_reg_fp_converts_dependency",
m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_AMDFAM10
- | m_BDVER | m_ZNVER | m_LUJIAZUI | m_ALDERLAKE | m_GENERIC)
+ | m_BDVER | m_ZNVER | m_LUJIAZUI | m_ALDERLAKE | m_CORE_ATOM
+ | m_GENERIC)
/* X86_TUNE_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY: This knob avoids partial
write to the destination in scalar SSE conversion from integer to FP. */
DEF_TUNE (X86_TUNE_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY,
"sse_partial_reg_converts_dependency",
m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_AMDFAM10
- | m_BDVER | m_ZNVER | m_LUJIAZUI | m_ALDERLAKE | m_GENERIC)
+ | m_BDVER | m_ZNVER | m_LUJIAZUI | m_ALDERLAKE | m_CORE_ATOM
+ | m_GENERIC)
/* X86_TUNE_DEST_FALSE_DEP_FOR_GLC: This knob inserts zero-idiom before
several insns to break false dependency on the dest register for GLC
micro-architecture. */
DEF_TUNE (X86_TUNE_DEST_FALSE_DEP_FOR_GLC,
- "dest_false_dep_for_glc", m_SAPPHIRERAPIDS | m_ALDERLAKE)
+ "dest_false_dep_for_glc", m_SAPPHIRERAPIDS | m_ALDERLAKE
+ | m_CORE_ATOM)
/* X86_TUNE_SSE_SPLIT_REGS: Set for machines where the type and dependencies
are resolved on SSE register parts instead of whole registers, so we may
@@ -110,14 +114,14 @@ DEF_TUNE (X86_TUNE_MOVX, "movx",
m_PPRO | m_P4_NOCONA | m_CORE2 | m_NEHALEM | m_SANDYBRIDGE
| m_BONNELL | m_SILVERMONT | m_GOLDMONT | m_KNL | m_KNM | m_INTEL
| m_GOLDMONT_PLUS | m_GEODE | m_AMD_MULTIPLE | m_LUJIAZUI
- | m_CORE_AVX2 | m_TREMONT | m_ALDERLAKE | m_GENERIC)
+ | m_CORE_AVX2 | m_TREMONT | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_MEMORY_MISMATCH_STALL: Avoid partial stores that are followed by
full sized loads. */
DEF_TUNE (X86_TUNE_MEMORY_MISMATCH_STALL, "memory_mismatch_stall",
m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_SILVERMONT | m_INTEL
| m_KNL | m_KNM | m_GOLDMONT | m_GOLDMONT_PLUS | m_AMD_MULTIPLE
- | m_LUJIAZUI | m_TREMONT | m_ALDERLAKE | m_GENERIC)
+ | m_LUJIAZUI | m_TREMONT | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_FUSE_CMP_AND_BRANCH_32: Fuse compare with a subsequent
conditional jump instruction for 32 bit TARGET. */
@@ -173,14 +177,14 @@ DEF_TUNE (X86_TUNE_EPILOGUE_USING_MOVE, "epilogue_using_move",
/* X86_TUNE_USE_LEAVE: Use "leave" instruction in epilogues where it fits. */
DEF_TUNE (X86_TUNE_USE_LEAVE, "use_leave",
m_386 | m_CORE_ALL | m_K6_GEODE | m_AMD_MULTIPLE | m_LUJIAZUI
- | m_TREMONT | m_ALDERLAKE | m_GENERIC)
+ | m_TREMONT | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_PUSH_MEMORY: Enable generation of "push mem" instructions.
Some chips, like 486 and Pentium works faster with separate load
and push instructions. */
DEF_TUNE (X86_TUNE_PUSH_MEMORY, "push_memory",
m_386 | m_P4_NOCONA | m_CORE_ALL | m_K6_GEODE | m_AMD_MULTIPLE
- | m_LUJIAZUI | m_TREMONT | m_ALDERLAKE | m_GENERIC)
+ | m_LUJIAZUI | m_TREMONT | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_SINGLE_PUSH: Enable if single push insn is preferred
over esp subtraction. */
@@ -250,15 +254,16 @@ DEF_TUNE (X86_TUNE_READ_MODIFY, "read_modify", ~(m_PENT | m_LAKEMONT | m_PPRO))
DEF_TUNE (X86_TUNE_USE_INCDEC, "use_incdec",
~(m_P4_NOCONA | m_CORE2 | m_NEHALEM | m_SANDYBRIDGE
| m_BONNELL | m_SILVERMONT | m_INTEL | m_KNL | m_KNM | m_GOLDMONT
- | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE | m_LUJIAZUI
- | m_GENERIC))
+ | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE | m_CORE_ATOM
+ | m_LUJIAZUI | m_GENERIC))
/* X86_TUNE_INTEGER_DFMODE_MOVES: Enable if integer moves are preferred
for DFmode copies */
DEF_TUNE (X86_TUNE_INTEGER_DFMODE_MOVES, "integer_dfmode_moves",
~(m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_SILVERMONT
| m_KNL | m_KNM | m_INTEL | m_GEODE | m_AMD_MULTIPLE | m_LUJIAZUI
- | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE | m_GENERIC))
+ | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE
+ | m_CORE_ATOM | m_GENERIC))
/* X86_TUNE_OPT_AGU: Optimize for Address Generation Unit. This flag
will impact LEA instruction selection. */
@@ -296,7 +301,8 @@ DEF_TUNE (X86_TUNE_SINGLE_STRINGOP, "single_stringop", m_386 | m_P4_NOCONA)
move/set sequences of bytes with known size. */
DEF_TUNE (X86_TUNE_PREFER_KNOWN_REP_MOVSB_STOSB,
"prefer_known_rep_movsb_stosb",
- m_SKYLAKE | m_ALDERLAKE | m_TREMONT | m_CORE_AVX512 | m_LUJIAZUI)
+ m_SKYLAKE | m_ALDERLAKE | m_CORE_ATOM | m_TREMONT | m_CORE_AVX512
+ | m_LUJIAZUI)
/* X86_TUNE_MISALIGNED_MOVE_STRING_PRO_EPILOGUES: Enable generation of
compact prologues and epilogues by issuing a misaligned moves. This
@@ -306,14 +312,14 @@ DEF_TUNE (X86_TUNE_PREFER_KNOWN_REP_MOVSB_STOSB,
DEF_TUNE (X86_TUNE_MISALIGNED_MOVE_STRING_PRO_EPILOGUES,
"misaligned_move_string_pro_epilogues",
m_386 | m_486 | m_CORE_ALL | m_AMD_MULTIPLE | m_LUJIAZUI | m_TREMONT
- | m_ALDERLAKE | m_GENERIC)
+ | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_USE_SAHF: Controls use of SAHF. */
DEF_TUNE (X86_TUNE_USE_SAHF, "use_sahf",
m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_SILVERMONT
| m_KNL | m_KNM | m_INTEL | m_K6_GEODE | m_K8 | m_AMDFAM10 | m_BDVER
| m_BTVER | m_ZNVER | m_LUJIAZUI | m_GOLDMONT | m_GOLDMONT_PLUS
- | m_TREMONT | m_ALDERLAKE | m_GENERIC)
+ | m_TREMONT | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_USE_CLTD: Controls use of CLTD and CTQO instructions. */
DEF_TUNE (X86_TUNE_USE_CLTD, "use_cltd",
@@ -324,13 +330,13 @@ DEF_TUNE (X86_TUNE_USE_CLTD, "use_cltd",
DEF_TUNE (X86_TUNE_USE_BT, "use_bt",
m_CORE_ALL | m_BONNELL | m_SILVERMONT | m_KNL | m_KNM | m_INTEL
| m_LAKEMONT | m_AMD_MULTIPLE | m_LUJIAZUI | m_GOLDMONT
- | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE | m_GENERIC)
+ | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_AVOID_FALSE_DEP_FOR_BMI: Avoid false dependency
for bit-manipulation instructions. */
DEF_TUNE (X86_TUNE_AVOID_FALSE_DEP_FOR_BMI, "avoid_false_dep_for_bmi",
- m_SANDYBRIDGE | m_CORE_AVX2 | m_TREMONT | m_ALDERLAKE | m_LUJIAZUI
- | m_GENERIC)
+ m_SANDYBRIDGE | m_CORE_AVX2 | m_TREMONT | m_ALDERLAKE | m_CORE_ATOM
+ | m_LUJIAZUI | m_GENERIC)
/* X86_TUNE_ADJUST_UNROLL: This enables adjusting the unroll factor based
on hardware capabilities. Bdver3 hardware has a loop buffer which makes
@@ -342,12 +348,13 @@ DEF_TUNE (X86_TUNE_ADJUST_UNROLL, "adjust_unroll_factor", m_BDVER3 | m_BDVER4)
if-converted sequence to one. */
DEF_TUNE (X86_TUNE_ONE_IF_CONV_INSN, "one_if_conv_insn",
m_SILVERMONT | m_KNL | m_KNM | m_INTEL | m_CORE_ALL | m_GOLDMONT
- | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE | m_LUJIAZUI | m_GENERIC)
+ | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE | m_CORE_ATOM | m_LUJIAZUI
+ | m_GENERIC)
/* X86_TUNE_AVOID_MFENCE: Use lock prefixed instructions instead of mfence. */
DEF_TUNE (X86_TUNE_AVOID_MFENCE, "avoid_mfence",
m_CORE_ALL | m_BDVER | m_ZNVER | m_LUJIAZUI | m_TREMONT | m_ALDERLAKE
- | m_GENERIC)
+ | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_EXPAND_ABS: This enables a new abs pattern by
generating instructions for abs (x) = (((signed) x >> (W-1) ^ x) -
@@ -372,7 +379,7 @@ DEF_TUNE (X86_TUNE_USE_SIMODE_FIOP, "use_simode_fiop",
~(m_PENT | m_LAKEMONT | m_PPRO | m_CORE_ALL | m_BONNELL
| m_SILVERMONT | m_KNL | m_KNM | m_INTEL | m_AMD_MULTIPLE
| m_LUJIAZUI | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT
- | m_ALDERLAKE | m_GENERIC))
+ | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC))
/* X86_TUNE_USE_FFREEP: Use freep instruction instead of fstp. */
DEF_TUNE (X86_TUNE_USE_FFREEP, "use_ffreep", m_AMD_MULTIPLE | m_LUJIAZUI)
@@ -381,7 +388,8 @@ DEF_TUNE (X86_TUNE_USE_FFREEP, "use_ffreep", m_AMD_MULTIPLE | m_LUJIAZUI)
DEF_TUNE (X86_TUNE_EXT_80387_CONSTANTS, "ext_80387_constants",
m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_SILVERMONT
| m_KNL | m_KNM | m_INTEL | m_K6_GEODE | m_ATHLON_K8 | m_LUJIAZUI
- | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE | m_GENERIC)
+ | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE | m_CORE_ATOM
+ | m_GENERIC)
/*****************************************************************************/
/* SSE instruction selection tuning */
@@ -397,14 +405,15 @@ DEF_TUNE (X86_TUNE_GENERAL_REGS_SSE_SPILL, "general_regs_sse_spill",
DEF_TUNE (X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL, "sse_unaligned_load_optimal",
m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_SILVERMONT | m_KNL | m_KNM
| m_INTEL | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE
- | m_AMDFAM10 | m_BDVER | m_BTVER | m_ZNVER | m_LUJIAZUI | m_GENERIC)
+ | m_CORE_ATOM | m_AMDFAM10 | m_BDVER | m_BTVER | m_ZNVER | m_LUJIAZUI
+ | m_GENERIC)
/* X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL: Use movups for misaligned stores
instead of a sequence loading registers by parts. */
DEF_TUNE (X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL, "sse_unaligned_store_optimal",
m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_SILVERMONT | m_KNL | m_KNM
| m_INTEL | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE
- | m_BDVER | m_ZNVER | m_LUJIAZUI | m_GENERIC)
+ | m_CORE_ATOM | m_BDVER | m_ZNVER | m_LUJIAZUI | m_GENERIC)
/* X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL: Use packed single
precision 128bit instructions instead of double where possible. */
@@ -414,13 +423,13 @@ DEF_TUNE (X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL, "sse_packed_single_insn_optim
/* X86_TUNE_SSE_TYPELESS_STORES: Always movaps/movups for 128bit stores. */
DEF_TUNE (X86_TUNE_SSE_TYPELESS_STORES, "sse_typeless_stores",
m_AMD_MULTIPLE | m_LUJIAZUI | m_CORE_ALL | m_TREMONT | m_ALDERLAKE
- | m_GENERIC)
+ | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_SSE_LOAD0_BY_PXOR: Always use pxor to load0 as opposed to
xorps/xorpd and other variants. */
DEF_TUNE (X86_TUNE_SSE_LOAD0_BY_PXOR, "sse_load0_by_pxor",
m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BDVER | m_BTVER | m_ZNVER
- | m_LUJIAZUI | m_TREMONT | m_ALDERLAKE | m_GENERIC)
+ | m_LUJIAZUI | m_TREMONT | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC)
/* X86_TUNE_INTER_UNIT_MOVES_TO_VEC: Enable moves in from integer
to SSE registers. If disabled, the moves will be done by storing
@@ -467,22 +476,22 @@ DEF_TUNE (X86_TUNE_SLOW_PSHUFB, "slow_pshufb",
/* X86_TUNE_AVOID_4BYTE_PREFIXES: Avoid instructions requiring 4+ bytes of prefixes. */
DEF_TUNE (X86_TUNE_AVOID_4BYTE_PREFIXES, "avoid_4byte_prefixes",
m_SILVERMONT | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE
- | m_INTEL)
+ | m_CORE_ATOM | m_INTEL)
/* X86_TUNE_USE_GATHER_2PARTS: Use gather instructions for vectors with 2
elements. */
DEF_TUNE (X86_TUNE_USE_GATHER_2PARTS, "use_gather_2parts",
- ~(m_ZNVER1 | m_ZNVER2 | m_ZNVER3 | m_ALDERLAKE | m_GENERIC))
+ ~(m_ZNVER1 | m_ZNVER2 | m_ZNVER3 | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC))
/* X86_TUNE_USE_GATHER_4PARTS: Use gather instructions for vectors with 4
elements. */
DEF_TUNE (X86_TUNE_USE_GATHER_4PARTS, "use_gather_4parts",
- ~(m_ZNVER1 | m_ZNVER2 | m_ZNVER3 | m_ALDERLAKE | m_GENERIC))
+ ~(m_ZNVER1 | m_ZNVER2 | m_ZNVER3 | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC))
/* X86_TUNE_USE_GATHER: Use gather instructions for vectors with 8 or more
elements. */
DEF_TUNE (X86_TUNE_USE_GATHER, "use_gather",
- ~(m_ZNVER1 | m_ZNVER2 | m_ALDERLAKE | m_GENERIC))
+ ~(m_ZNVER1 | m_ZNVER2 | m_ALDERLAKE | m_CORE_ATOM | m_GENERIC))
/* X86_TUNE_AVOID_128FMA_CHAINS: Avoid creating loops with tight 128bit or
smaller FMA chain. */
@@ -490,7 +499,8 @@ DEF_TUNE (X86_TUNE_AVOID_128FMA_CHAINS, "avoid_fma_chains", m_ZNVER)
/* X86_TUNE_AVOID_256FMA_CHAINS: Avoid creating loops with tight 256bit or
smaller FMA chain. */
-DEF_TUNE (X86_TUNE_AVOID_256FMA_CHAINS, "avoid_fma256_chains", m_ZNVER2 | m_ZNVER3)
+DEF_TUNE (X86_TUNE_AVOID_256FMA_CHAINS, "avoid_fma256_chains", m_ZNVER2 | m_ZNVER3
+ | m_ALDERLAKE | m_SAPPHIRERAPIDS | m_CORE_ATOM)
/* X86_TUNE_V2DF_REDUCTION_PREFER_PHADDPD: Prefer haddpd
for v2df vector reduction. */
@@ -527,12 +537,12 @@ DEF_TUNE (X86_TUNE_AVX256_OPTIMAL, "avx256_optimal", m_CORE_AVX512)
/* X86_TUNE_AVX256_MOVE_BY_PIECES: Optimize move_by_pieces with 256-bit
AVX instructions. */
DEF_TUNE (X86_TUNE_AVX256_MOVE_BY_PIECES, "avx256_move_by_pieces",
- m_CORE_AVX512)
+ m_ALDERLAKE | m_CORE_AVX2)
/* X86_TUNE_AVX256_STORE_BY_PIECES: Optimize store_by_pieces with 256-bit
AVX instructions. */
DEF_TUNE (X86_TUNE_AVX256_STORE_BY_PIECES, "avx256_store_by_pieces",
- m_CORE_AVX512)
+ m_ALDERLAKE | m_CORE_AVX2)
/* X86_TUNE_AVX512_MOVE_BY_PIECES: Optimize move_by_pieces with 512-bit
AVX instructions. */
diff --git a/gcc/config/i386/x86gprintrin.h b/gcc/config/i386/x86gprintrin.h
index e0be01d..abbeef8 100644
--- a/gcc/config/i386/x86gprintrin.h
+++ b/gcc/config/i386/x86gprintrin.h
@@ -52,6 +52,8 @@
#include <clzerointrin.h>
+#include <cmpccxaddintrin.h>
+
#include <enqcmdintrin.h>
#include <fxsrintrin.h>
@@ -72,6 +74,10 @@
#include <pkuintrin.h>
+#include <prfchiintrin.h>
+
+#include <raointintrin.h>
+
#include <rdseedintrin.h>
#include <rtmintrin.h>
diff --git a/gcc/config/i386/xmmintrin.h b/gcc/config/i386/xmmintrin.h
index 6265908..ab65c43 100644
--- a/gcc/config/i386/xmmintrin.h
+++ b/gcc/config/i386/xmmintrin.h
@@ -36,6 +36,8 @@
/* Constants for use with _mm_prefetch. */
enum _mm_hint
{
+ _MM_HINT_IT0 = 19,
+ _MM_HINT_IT1 = 18,
/* _MM_HINT_ET is _MM_HINT_T with set 3rd bit. */
_MM_HINT_ET0 = 7,
_MM_HINT_ET1 = 6,
@@ -51,11 +53,12 @@ enum _mm_hint
extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_prefetch (const void *__P, enum _mm_hint __I)
{
- __builtin_prefetch (__P, (__I & 0x4) >> 2, __I & 0x3);
+ __builtin_ia32_prefetch (__P, (__I & 0x4) >> 2,
+ __I & 0x3, (__I & 0x10) >> 4);
}
#else
#define _mm_prefetch(P, I) \
- __builtin_prefetch ((P), ((I & 0x4) >> 2), (I & 0x3))
+ __builtin_ia32_prefetch ((P), ((I) & 0x4) >> 2, ((I) & 0x3), ((I) & 0x10) >> 4)
#endif
#ifndef __SSE__
diff --git a/gcc/config/i386/znver.md b/gcc/config/i386/znver.md
index 4aa098f..882f250 100644
--- a/gcc/config/i386/znver.md
+++ b/gcc/config/i386/znver.md
@@ -24,7 +24,7 @@
;; AMD znver1, znver2 and znver3 Scheduling
;; Modeling automatons for zen decoders, integer execution pipes,
;; SIMD/FP domain, AGU pipes, and dividers.
-(define_automaton "znver1, znver1_ieu, znver1_fp, znver1_agu, znver1_idiv")
+(define_automaton "znver1, znver1_ieu, znver1_fp, znver1_agu, znver1_idiv, znver1_fdiv")
;; Decoders unit has 4 decoders and all of them can decode fast path
;; and vector type instructions.
@@ -95,6 +95,7 @@
;; Dividers
(define_cpu_unit "znver1-idiv" "znver1_idiv")
+(define_cpu_unit "znver1-fdiv" "znver1_fdiv")
;; Call instruction
(define_insn_reservation "znver1_call" 1
@@ -572,13 +573,13 @@
(and (eq_attr "cpu" "znver1,znver2,znver3")
(and (eq_attr "type" "fop,fmul")
(eq_attr "memory" "none")))
- "znver1-direct,znver1-fp0*5")
+ "znver1-direct,znver1-fp0")
(define_insn_reservation "znver1_fp_op_mul_load" 12
(and (eq_attr "cpu" "znver1,znver2,znver3")
(and (eq_attr "type" "fop,fmul")
(eq_attr "memory" "load")))
- "znver1-direct,znver1-load,znver1-fp0*5")
+ "znver1-direct,znver1-load,znver1-fp0")
(define_insn_reservation "znver1_fp_op_imul_load" 16
(and (eq_attr "cpu" "znver1,znver2,znver3")
@@ -591,27 +592,27 @@
(and (eq_attr "cpu" "znver1,znver2,znver3")
(and (eq_attr "type" "fdiv")
(eq_attr "memory" "none")))
- "znver1-direct,znver1-fp3*15")
+ "znver1-direct,znver1-fdiv*6")
(define_insn_reservation "znver1_fp_op_div_load" 22
(and (eq_attr "cpu" "znver1,znver2,znver3")
(and (eq_attr "type" "fdiv")
(eq_attr "memory" "load")))
- "znver1-direct,znver1-load,znver1-fp3*15")
+ "znver1-direct,znver1-load,znver1-fdiv*6")
(define_insn_reservation "znver1_fp_op_idiv_load" 27
(and (eq_attr "cpu" "znver1")
(and (eq_attr "type" "fdiv")
(and (eq_attr "fp_int_src" "true")
(eq_attr "memory" "load"))))
- "znver1-double,znver1-load,znver1-fp3*19")
+ "znver1-double,znver1-load,znver1-fdiv*6")
(define_insn_reservation "znver2_fp_op_idiv_load" 26
(and (eq_attr "cpu" "znver2,znver3")
(and (eq_attr "type" "fdiv")
(and (eq_attr "fp_int_src" "true")
(eq_attr "memory" "load"))))
- "znver1-double,znver1-load,znver1-fp3*19")
+ "znver1-double,znver1-load,znver1-fdiv*6")
;; MMX, SSE, SSEn.n, AVX, AVX2 instructions
@@ -683,13 +684,13 @@
(and (eq_attr "cpu" "znver1,znver2,znver3")
(and (eq_attr "type" "mmxmul")
(eq_attr "memory" "none")))
- "znver1-direct,znver1-fp0*3")
+ "znver1-direct,znver1-fp0")
(define_insn_reservation "znver1_mmx_load" 10
(and (eq_attr "cpu" "znver1,znver2,znver3")
(and (eq_attr "type" "mmxmul")
(eq_attr "memory" "load")))
- "znver1-direct,znver1-load,znver1-fp0*3")
+ "znver1-direct,znver1-load,znver1-fp0")
;; TODO
(define_insn_reservation "znver1_avx256_log" 1
@@ -1088,7 +1089,7 @@
(eq_attr "mode" "V8SF,V4SF,SF")))
(and (eq_attr "type" "ssediv")
(eq_attr "memory" "none")))
- "znver1-direct,znver1-fp3*10")
+ "znver1-direct,znver1-fdiv*4")
(define_insn_reservation "znver1_ssediv_ss_ps_load" 17
(and (ior (and (eq_attr "cpu" "znver1")
@@ -1099,7 +1100,7 @@
(eq_attr "mode" "V8SF,V4SF,SF")))
(and (eq_attr "type" "ssediv")
(eq_attr "memory" "load")))
- "znver1-direct,znver1-load,znver1-fp3*10")
+ "znver1-direct,znver1-load,znver1-fdiv*4")
(define_insn_reservation "znver1_ssediv_sd_pd" 13
(and (ior (and (eq_attr "cpu" "znver1")
@@ -1110,7 +1111,7 @@
(eq_attr "mode" "V4DF,V2DF,DF")))
(and (eq_attr "type" "ssediv")
(eq_attr "memory" "none")))
- "znver1-direct,znver1-fp3*13")
+ "znver1-direct,znver1-fdiv*5")
(define_insn_reservation "znver1_ssediv_sd_pd_load" 20
(and (ior (and (eq_attr "cpu" "znver1")
@@ -1121,35 +1122,35 @@
(eq_attr "mode" "V4DF,V2DF,DF")))
(and (eq_attr "type" "ssediv")
(eq_attr "memory" "load")))
- "znver1-direct,znver1-load,znver1-fp3*13")
+ "znver1-direct,znver1-load,znver1-fdiv*5")
(define_insn_reservation "znver1_ssediv_avx256_ps" 12
(and (eq_attr "cpu" "znver1")
(and (eq_attr "mode" "V8SF")
(and (eq_attr "memory" "none")
(eq_attr "type" "ssediv"))))
- "znver1-double,znver1-fp3*12")
+ "znver1-double,znver1-fdiv*8")
(define_insn_reservation "znver1_ssediv_avx256_ps_load" 19
(and (eq_attr "cpu" "znver1")
(and (eq_attr "mode" "V8SF")
(and (eq_attr "type" "ssediv")
(eq_attr "memory" "load"))))
- "znver1-double,znver1-load,znver1-fp3*12")
+ "znver1-double,znver1-load,znver1-fdiv*8")
(define_insn_reservation "znver1_ssediv_avx256_pd" 15
(and (eq_attr "cpu" "znver1")
(and (eq_attr "mode" "V4DF")
(and (eq_attr "type" "ssediv")
(eq_attr "memory" "none"))))
- "znver1-double,znver1-fp3*15")
+ "znver1-double,znver1-fdiv*10")
(define_insn_reservation "znver1_ssediv_avx256_pd_load" 22
(and (eq_attr "cpu" "znver1")
(and (eq_attr "mode" "V4DF")
(and (eq_attr "type" "ssediv")
(eq_attr "memory" "load"))))
- "znver1-double,znver1-load,znver1-fp3*15")
+ "znver1-double,znver1-load,znver1-fdiv*10")
;; SSE MUL
(define_insn_reservation "znver1_ssemul_ss_ps" 3
(and (ior (and (eq_attr "cpu" "znver1")
@@ -1160,7 +1161,7 @@
(eq_attr "mode" "V8SF,V4SF,SF,V4DF,V2DF,DF")))
(and (eq_attr "type" "ssemul")
(eq_attr "memory" "none")))
- "znver1-direct,(znver1-fp0|znver1-fp1)*3")
+ "znver1-direct,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver1_ssemul_ss_ps_load" 10
(and (ior (and (eq_attr "cpu" "znver1")
@@ -1171,47 +1172,47 @@
(eq_attr "mode" "V8SF,V4SF,SF")))
(and (eq_attr "type" "ssemul")
(eq_attr "memory" "load")))
- "znver1-direct,znver1-load,(znver1-fp0|znver1-fp1)*3")
+ "znver1-direct,znver1-load,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver1_ssemul_avx256_ps" 3
(and (eq_attr "cpu" "znver1")
(and (eq_attr "mode" "V8SF")
(and (eq_attr "type" "ssemul")
(eq_attr "memory" "none"))))
- "znver1-double,(znver1-fp0|znver1-fp1)*3")
+ "znver1-double,znver1-fp0*2|znver1-fp1*2")
(define_insn_reservation "znver1_ssemul_avx256_ps_load" 10
(and (eq_attr "cpu" "znver1")
(and (eq_attr "mode" "V8SF")
(and (eq_attr "type" "ssemul")
(eq_attr "memory" "load"))))
- "znver1-double,znver1-load,(znver1-fp0|znver1-fp1)*3")
+ "znver1-double,znver1-load,znver1-fp0*2|znver1-fp1*2")
(define_insn_reservation "znver1_ssemul_sd_pd" 4
(and (eq_attr "cpu" "znver1")
(and (eq_attr "mode" "V2DF,DF")
(and (eq_attr "type" "ssemul")
(eq_attr "memory" "none"))))
- "znver1-direct,(znver1-fp0|znver1-fp1)*4")
+ "znver1-direct,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver1_ssemul_sd_pd_load" 11
(and (eq_attr "cpu" "znver1")
(and (eq_attr "mode" "V2DF,DF")
(and (eq_attr "type" "ssemul")
(eq_attr "memory" "load"))))
- "znver1-direct,znver1-load,(znver1-fp0|znver1-fp1)*4")
+ "znver1-direct,znver1-load,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver2_ssemul_sd_pd" 3
(and (eq_attr "cpu" "znver2,znver3")
(and (eq_attr "type" "ssemul")
(eq_attr "memory" "none")))
- "znver1-direct,(znver1-fp0|znver1-fp1)*3")
+ "znver1-direct,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver2_ssemul_sd_pd_load" 10
(and (eq_attr "cpu" "znver2,znver3")
(and (eq_attr "type" "ssemul")
(eq_attr "memory" "load")))
- "znver1-direct,znver1-load,(znver1-fp0|znver1-fp1)*3")
+ "znver1-direct,znver1-load,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver1_ssemul_avx256_pd" 5
@@ -1219,14 +1220,14 @@
(and (eq_attr "mode" "V4DF")
(and (eq_attr "type" "ssemul")
(eq_attr "memory" "none"))))
- "znver1-double,(znver1-fp0|znver1-fp1)*4")
+ "znver1-double,znver1-fp0*2|znver1-fp1*2")
(define_insn_reservation "znver1_ssemul_avx256_pd_load" 12
(and (eq_attr "cpu" "znver1")
(and (eq_attr "mode" "V4DF")
(and (eq_attr "type" "ssemul")
(eq_attr "memory" "load"))))
- "znver1-double,znver1-load,(znver1-fp0|znver1-fp1)*4")
+ "znver1-double,znver1-load,znver1-fp0*2|znver1-fp1*2")
;;SSE imul
(define_insn_reservation "znver1_sseimul" 3
@@ -1238,14 +1239,14 @@
(eq_attr "mode" "TI,OI")))
(and (eq_attr "type" "sseimul")
(eq_attr "memory" "none")))
- "znver1-direct,znver1-fp0*3")
+ "znver1-direct,znver1-fp0")
(define_insn_reservation "znver1_sseimul_avx256" 4
(and (eq_attr "cpu" "znver1,znver2,znver3")
(and (eq_attr "mode" "OI")
(and (eq_attr "type" "sseimul")
(eq_attr "memory" "none"))))
- "znver1-double,znver1-fp0*4")
+ "znver1-double,znver1-fp0*2")
(define_insn_reservation "znver1_sseimul_load" 10
(and (ior (and (eq_attr "cpu" "znver1")
@@ -1256,28 +1257,28 @@
(eq_attr "mode" "TI,OI")))
(and (eq_attr "type" "sseimul")
(eq_attr "memory" "load")))
- "znver1-direct,znver1-load,znver1-fp0*3")
+ "znver1-direct,znver1-load,znver1-fp0")
(define_insn_reservation "znver1_sseimul_avx256_load" 11
(and (eq_attr "cpu" "znver1,znver2,znver3")
(and (eq_attr "mode" "OI")
(and (eq_attr "type" "sseimul")
(eq_attr "memory" "load"))))
- "znver1-double,znver1-load,znver1-fp0*4")
+ "znver1-double,znver1-load,znver1-fp0*2")
(define_insn_reservation "znver1_sseimul_di" 3
(and (eq_attr "cpu" "znver1,znver2,znver3")
(and (eq_attr "mode" "DI")
(and (eq_attr "memory" "none")
(eq_attr "type" "sseimul"))))
- "znver1-direct,znver1-fp0*3")
+ "znver1-direct,znver1-fp0")
(define_insn_reservation "znver1_sseimul_load_di" 10
(and (eq_attr "cpu" "znver1,znver2,znver3")
(and (eq_attr "mode" "DI")
(and (eq_attr "type" "sseimul")
(eq_attr "memory" "load"))))
- "znver1-direct,znver1-load,znver1-fp0*3")
+ "znver1-direct,znver1-load,znver1-fp0")
;; SSE compares
(define_insn_reservation "znver1_sse_cmp" 1
diff --git a/gcc/config/loongarch/constraints.md b/gcc/config/loongarch/constraints.md
index 43cb7b5..46f7f63 100644
--- a/gcc/config/loongarch/constraints.md
+++ b/gcc/config/loongarch/constraints.md
@@ -86,6 +86,10 @@
;; "ZB"
;; "An address that is held in a general-purpose register.
;; The offset is zero"
+;; "ZD"
+;; "An address operand whose address is formed by a base register
+;; and offset that is suitable for use in instructions with the same
+;; addressing mode as @code{preld}."
;; "<" "Matches a pre-dec or post-dec operand." (Global non-architectural)
;; ">" "Matches a pre-inc or post-inc operand." (Global non-architectural)
@@ -190,3 +194,9 @@
The offset is zero"
(and (match_code "mem")
(match_test "REG_P (XEXP (op, 0))")))
+
+(define_address_constraint "ZD"
+ "An address operand whose address is formed by a base register
+ and offset that is suitable for use in instructions with the same
+ addressing mode as @code{preld}."
+ (match_test "loongarch_12bit_offset_address_p (op, mode)"))
diff --git a/gcc/config/loongarch/linux.h b/gcc/config/loongarch/linux.h
index 110d0fa..00039ac 100644
--- a/gcc/config/loongarch/linux.h
+++ b/gcc/config/loongarch/linux.h
@@ -48,3 +48,6 @@ along with GCC; see the file COPYING3. If not see
#define STACK_CHECK_PROTECT (TARGET_64BIT ? 16 * 1024 : 12 * 1024)
#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
+
+/* The stack pointer needs to be moved while checking the stack. */
+#define STACK_CHECK_MOVING_SP 1
diff --git a/gcc/config/loongarch/loongarch-def.c b/gcc/config/loongarch/loongarch-def.c
index cbf995d..80ab10a 100644
--- a/gcc/config/loongarch/loongarch-def.c
+++ b/gcc/config/loongarch/loongarch-def.c
@@ -62,11 +62,13 @@ loongarch_cpu_cache[N_TUNE_TYPES] = {
.l1d_line_size = 64,
.l1d_size = 64,
.l2d_size = 256,
+ .simultaneous_prefetches = 4,
},
[CPU_LA464] = {
.l1d_line_size = 64,
.l1d_size = 64,
.l2d_size = 256,
+ .simultaneous_prefetches = 4,
},
};
diff --git a/gcc/config/loongarch/loongarch-tune.h b/gcc/config/loongarch/loongarch-tune.h
index 6f3530f..8e3eb29 100644
--- a/gcc/config/loongarch/loongarch-tune.h
+++ b/gcc/config/loongarch/loongarch-tune.h
@@ -45,6 +45,7 @@ struct loongarch_cache {
int l1d_line_size; /* bytes */
int l1d_size; /* KiB */
int l2d_size; /* kiB */
+ int simultaneous_prefetches; /* number of parallel prefetch */
};
#endif /* LOONGARCH_TUNE_H */
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index f54c233..c6b03fc 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -63,6 +63,7 @@ along with GCC; see the file COPYING3. If not see
#include "context.h"
#include "builtins.h"
#include "rtl-iter.h"
+#include "opts.h"
/* This file should be included last. */
#include "target-def.h"
@@ -138,22 +139,21 @@ struct loongarch_address_info
METHOD_LU52I:
Load 52-63 bit of the immediate number.
-
- METHOD_INSV:
- immediate like 0xfff00000fffffxxx
- */
+*/
enum loongarch_load_imm_method
{
METHOD_NORMAL,
METHOD_LU32I,
- METHOD_LU52I,
- METHOD_INSV
+ METHOD_LU52I
};
struct loongarch_integer_op
{
enum rtx_code code;
HOST_WIDE_INT value;
+ /* Represent the result of the immediate count of the load instruction at
+ each step. */
+ HOST_WIDE_INT curr_value;
enum loongarch_load_imm_method method;
};
@@ -257,6 +257,10 @@ const char *const
loongarch_fp_conditions[16]= {LARCH_FP_CONDITIONS (STRINGIFY)};
#undef STRINGIFY
+/* Size of guard page. */
+#define STACK_CLASH_PROTECTION_GUARD_SIZE \
+ (1 << param_stack_clash_protection_guard_size)
+
/* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at
least PARM_BOUNDARY bits of alignment, but will be given anything up
to PREFERRED_STACK_BOUNDARY bits if the type requires it. */
@@ -1070,11 +1074,20 @@ loongarch_restore_reg (rtx reg, rtx mem)
static HOST_WIDE_INT
loongarch_first_stack_step (struct loongarch_frame_info *frame)
{
+ HOST_WIDE_INT min_first_step
+ = LARCH_STACK_ALIGN (frame->total_size - frame->fp_sp_offset);
+
+ /* When stack checking is required, if the sum of frame->total_size
+ and stack_check_protect is greater than stack clash protection guard
+ size, then return min_first_step. */
+ if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK
+ || (flag_stack_clash_protection
+ && frame->total_size > STACK_CLASH_PROTECTION_GUARD_SIZE))
+ return min_first_step;
+
if (IMM12_OPERAND (frame->total_size))
return frame->total_size;
- HOST_WIDE_INT min_first_step
- = LARCH_STACK_ALIGN (frame->total_size - frame->fp_sp_offset);
HOST_WIDE_INT max_first_step = IMM_REACH / 2 - PREFERRED_STACK_BOUNDARY / 8;
HOST_WIDE_INT min_second_step = frame->total_size - max_first_step;
gcc_assert (min_first_step <= max_first_step);
@@ -1107,103 +1120,109 @@ loongarch_emit_stack_tie (void)
static void
loongarch_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
{
- /* See if we have a constant small number of probes to generate. If so,
- that's the easy case. */
- if ((TARGET_64BIT && (first + size <= 32768))
- || (!TARGET_64BIT && (first + size <= 2048)))
- {
- HOST_WIDE_INT i;
+ HOST_WIDE_INT rounded_size;
+ HOST_WIDE_INT interval;
- /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
- it exceeds SIZE. If only one probe is needed, this will not
- generate any code. Then probe at FIRST + SIZE. */
- for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
- emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
- -(first + i)));
+ if (flag_stack_clash_protection)
+ interval = STACK_CLASH_PROTECTION_GUARD_SIZE;
+ else
+ interval = PROBE_INTERVAL;
- emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
- -(first + size)));
- }
+ rtx r12 = LARCH_PROLOGUE_TEMP2 (Pmode);
+ rtx r14 = LARCH_PROLOGUE_TEMP3 (Pmode);
- /* Otherwise, do the same as above, but in a loop. Note that we must be
- extra careful with variables wrapping around because we might be at
- the very top (or the very bottom) of the address space and we have
- to be able to handle this case properly; in particular, we use an
- equality test for the loop condition. */
- else
- {
- HOST_WIDE_INT rounded_size;
- rtx r13 = LARCH_PROLOGUE_TEMP (Pmode);
- rtx r12 = LARCH_PROLOGUE_TEMP2 (Pmode);
- rtx r14 = LARCH_PROLOGUE_TEMP3 (Pmode);
+ size = size + first;
- /* Sanity check for the addressing mode we're going to use. */
- gcc_assert (first <= 16384);
+ /* Sanity check for the addressing mode we're going to use. */
+ gcc_assert (first <= 16384);
+ /* Step 1: round SIZE to the previous multiple of the interval. */
- /* Step 1: round SIZE to the previous multiple of the interval. */
+ rounded_size = ROUND_DOWN (size, interval);
- rounded_size = ROUND_DOWN (size, PROBE_INTERVAL);
+ /* Step 2: compute initial and final value of the loop counter. */
- /* TEST_ADDR = SP + FIRST */
- if (first != 0)
- {
- emit_move_insn (r14, GEN_INT (first));
- emit_insn (gen_rtx_SET (r13, gen_rtx_MINUS (Pmode,
- stack_pointer_rtx,
- r14)));
- }
- else
- emit_move_insn (r13, stack_pointer_rtx);
+ emit_move_insn (r14, GEN_INT (interval));
+
+ /* If rounded_size is zero, it means that the space requested by
+ the local variable is less than the interval, and there is no
+ need to display and detect the allocated space. */
+ if (rounded_size != 0)
+ {
+ /* Step 3: the loop
+
+ do
+ {
+ TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
+ probe at TEST_ADDR
+ }
+ while (TEST_ADDR != LAST_ADDR)
- /* Step 2: compute initial and final value of the loop counter. */
+ probes at FIRST + N * PROBE_INTERVAL for values of N from 1
+ until it is equal to ROUNDED_SIZE. */
- emit_move_insn (r14, GEN_INT (PROBE_INTERVAL));
- /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
- if (rounded_size == 0)
- emit_move_insn (r12, r13);
+ if (rounded_size <= STACK_CLASH_MAX_UNROLL_PAGES * interval)
+ {
+ for (HOST_WIDE_INT i = 0; i < rounded_size; i += interval)
+ {
+ emit_insn (gen_rtx_SET (stack_pointer_rtx,
+ gen_rtx_MINUS (Pmode,
+ stack_pointer_rtx,
+ r14)));
+ emit_move_insn (gen_rtx_MEM (Pmode,
+ gen_rtx_PLUS (Pmode,
+ stack_pointer_rtx,
+ const0_rtx)),
+ const0_rtx);
+ emit_insn (gen_blockage ());
+ }
+ dump_stack_clash_frame_info (PROBE_INLINE, size != rounded_size);
+ }
else
{
emit_move_insn (r12, GEN_INT (rounded_size));
- emit_insn (gen_rtx_SET (r12, gen_rtx_MINUS (Pmode, r13, r12)));
- /* Step 3: the loop
-
- do
- {
- TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
- probe at TEST_ADDR
- }
- while (TEST_ADDR != LAST_ADDR)
-
- probes at FIRST + N * PROBE_INTERVAL for values of N from 1
- until it is equal to ROUNDED_SIZE. */
-
- emit_insn (gen_probe_stack_range (Pmode, r13, r13, r12, r14));
+ emit_insn (gen_rtx_SET (r12,
+ gen_rtx_MINUS (Pmode,
+ stack_pointer_rtx,
+ r12)));
+
+ emit_insn (gen_probe_stack_range (Pmode, stack_pointer_rtx,
+ stack_pointer_rtx, r12, r14));
+ emit_insn (gen_blockage ());
+ dump_stack_clash_frame_info (PROBE_LOOP, size != rounded_size);
}
+ }
+ else
+ dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true);
- /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
- that SIZE is equal to ROUNDED_SIZE. */
- if (size != rounded_size)
+ /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
+ that SIZE is equal to ROUNDED_SIZE. */
+
+ if (size != rounded_size)
+ {
+ if (size - rounded_size >= 2048)
{
- if (TARGET_64BIT)
- emit_stack_probe (plus_constant (Pmode, r12, rounded_size - size));
- else
- {
- HOST_WIDE_INT i;
- for (i = 2048; i < (size - rounded_size); i += 2048)
- {
- emit_stack_probe (plus_constant (Pmode, r12, -i));
- emit_insn (gen_rtx_SET (r12,
- plus_constant (Pmode, r12, -2048)));
- }
- rtx r1 = plus_constant (Pmode, r12,
- -(size - rounded_size - i + 2048));
- emit_stack_probe (r1);
- }
+ emit_move_insn (r14, GEN_INT (size - rounded_size));
+ emit_insn (gen_rtx_SET (stack_pointer_rtx,
+ gen_rtx_MINUS (Pmode,
+ stack_pointer_rtx,
+ r14)));
}
+ else
+ emit_insn (gen_rtx_SET (stack_pointer_rtx,
+ gen_rtx_PLUS (Pmode,
+ stack_pointer_rtx,
+ GEN_INT (rounded_size - size))));
}
+ if (first)
+ {
+ emit_move_insn (r12, GEN_INT (first));
+ emit_insn (gen_rtx_SET (stack_pointer_rtx,
+ gen_rtx_PLUS (Pmode,
+ stack_pointer_rtx, r12)));
+ }
/* Make sure nothing is scheduled before we are done. */
emit_insn (gen_blockage ());
}
@@ -1224,7 +1243,6 @@ loongarch_output_probe_stack_range (rtx reg1, rtx reg2, rtx reg3)
/* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
xops[0] = reg1;
- xops[1] = GEN_INT (-PROBE_INTERVAL);
xops[2] = reg3;
if (TARGET_64BIT)
output_asm_insn ("sub.d\t%0,%0,%2", xops);
@@ -1250,28 +1268,11 @@ loongarch_expand_prologue (void)
{
struct loongarch_frame_info *frame = &cfun->machine->frame;
HOST_WIDE_INT size = frame->total_size;
- HOST_WIDE_INT tmp;
rtx insn;
if (flag_stack_usage_info)
current_function_static_stack_size = size;
- if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK
- || flag_stack_clash_protection)
- {
- if (crtl->is_leaf && !cfun->calls_alloca)
- {
- if (size > PROBE_INTERVAL && size > get_stack_check_protect ())
- {
- tmp = size - get_stack_check_protect ();
- loongarch_emit_probe_stack_range (get_stack_check_protect (),
- tmp);
- }
- }
- else if (size > 0)
- loongarch_emit_probe_stack_range (get_stack_check_protect (), size);
- }
-
/* Save the registers. */
if ((frame->mask | frame->fmask) != 0)
{
@@ -1284,7 +1285,6 @@ loongarch_expand_prologue (void)
loongarch_for_each_saved_reg (size, loongarch_save_reg);
}
-
/* Set up the frame pointer, if we're using one. */
if (frame_pointer_needed)
{
@@ -1295,7 +1295,45 @@ loongarch_expand_prologue (void)
loongarch_emit_stack_tie ();
}
- /* Allocate the rest of the frame. */
+ if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK
+ || flag_stack_clash_protection)
+ {
+ HOST_WIDE_INT first = get_stack_check_protect ();
+
+ if (frame->total_size == 0)
+ {
+ /* do nothing. */
+ dump_stack_clash_frame_info (NO_PROBE_NO_FRAME, false);
+ return;
+ }
+
+ if (crtl->is_leaf && !cfun->calls_alloca)
+ {
+ HOST_WIDE_INT interval;
+
+ if (flag_stack_clash_protection)
+ interval = STACK_CLASH_PROTECTION_GUARD_SIZE;
+ else
+ interval = PROBE_INTERVAL;
+
+ if (size > interval && size > first)
+ loongarch_emit_probe_stack_range (first, size - first);
+ else
+ loongarch_emit_probe_stack_range (first, size);
+ }
+ else
+ loongarch_emit_probe_stack_range (first, size);
+
+ if (size > 0)
+ {
+ /* Describe the effect of the previous instructions. */
+ insn = plus_constant (Pmode, stack_pointer_rtx, -size);
+ insn = gen_rtx_SET (stack_pointer_rtx, insn);
+ loongarch_set_frame_expr (insn);
+ }
+ return;
+ }
+
if (size > 0)
{
if (IMM12_OPERAND (-size))
@@ -1306,7 +1344,8 @@ loongarch_expand_prologue (void)
}
else
{
- loongarch_emit_move (LARCH_PROLOGUE_TEMP (Pmode), GEN_INT (-size));
+ loongarch_emit_move (LARCH_PROLOGUE_TEMP (Pmode),
+ GEN_INT (-size));
emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
LARCH_PROLOGUE_TEMP (Pmode)));
@@ -1474,24 +1513,27 @@ loongarch_build_integer (struct loongarch_integer_op *codes,
{
/* The value of the lower 32 bit be loaded with one instruction.
lu12i.w. */
- codes[0].code = UNKNOWN;
- codes[0].method = METHOD_NORMAL;
- codes[0].value = low_part;
+ codes[cost].code = UNKNOWN;
+ codes[cost].method = METHOD_NORMAL;
+ codes[cost].value = low_part;
+ codes[cost].curr_value = low_part;
cost++;
}
else
{
/* lu12i.w + ior. */
- codes[0].code = UNKNOWN;
- codes[0].method = METHOD_NORMAL;
- codes[0].value = low_part & ~(IMM_REACH - 1);
+ codes[cost].code = UNKNOWN;
+ codes[cost].method = METHOD_NORMAL;
+ codes[cost].value = low_part & ~(IMM_REACH - 1);
+ codes[cost].curr_value = codes[cost].value;
cost++;
HOST_WIDE_INT iorv = low_part & (IMM_REACH - 1);
if (iorv != 0)
{
- codes[1].code = IOR;
- codes[1].method = METHOD_NORMAL;
- codes[1].value = iorv;
+ codes[cost].code = IOR;
+ codes[cost].method = METHOD_NORMAL;
+ codes[cost].value = iorv;
+ codes[cost].curr_value = low_part;
cost++;
}
}
@@ -1514,11 +1556,14 @@ loongarch_build_integer (struct loongarch_integer_op *codes,
{
codes[cost].method = METHOD_LU52I;
codes[cost].value = value & LU52I_B;
+ codes[cost].curr_value = value;
return cost + 1;
}
codes[cost].method = METHOD_LU32I;
codes[cost].value = (value & LU32I_B) | (sign51 ? LU52I_B : 0);
+ codes[cost].curr_value = (value & 0xfffffffffffff)
+ | (sign51 ? LU52I_B : 0);
cost++;
/* Determine whether the 52-61 bits are sign-extended from the low order,
@@ -1527,6 +1572,7 @@ loongarch_build_integer (struct loongarch_integer_op *codes,
{
codes[cost].method = METHOD_LU52I;
codes[cost].value = value & LU52I_B;
+ codes[cost].curr_value = value;
cost++;
}
}
@@ -2910,6 +2956,9 @@ loongarch_move_integer (rtx temp, rtx dest, unsigned HOST_WIDE_INT value)
else
x = force_reg (mode, x);
+ set_unique_reg_note (get_last_insn (), REG_EQUAL,
+ GEN_INT (codes[i-1].curr_value));
+
switch (codes[i].method)
{
case METHOD_NORMAL:
@@ -2917,22 +2966,17 @@ loongarch_move_integer (rtx temp, rtx dest, unsigned HOST_WIDE_INT value)
GEN_INT (codes[i].value));
break;
case METHOD_LU32I:
- emit_insn (
- gen_rtx_SET (x,
- gen_rtx_IOR (DImode,
- gen_rtx_ZERO_EXTEND (
- DImode, gen_rtx_SUBREG (SImode, x, 0)),
- GEN_INT (codes[i].value))));
+ gcc_assert (mode == DImode);
+ x = gen_rtx_IOR (DImode,
+ gen_rtx_ZERO_EXTEND (DImode,
+ gen_rtx_SUBREG (SImode, x, 0)),
+ GEN_INT (codes[i].value));
break;
case METHOD_LU52I:
- emit_insn (gen_lu52i_d (x, x, GEN_INT (0xfffffffffffff),
- GEN_INT (codes[i].value)));
- break;
- case METHOD_INSV:
- emit_insn (
- gen_rtx_SET (gen_rtx_ZERO_EXTRACT (DImode, x, GEN_INT (20),
- GEN_INT (32)),
- gen_rtx_REG (DImode, 0)));
+ gcc_assert (mode == DImode);
+ x = gen_rtx_IOR (DImode,
+ gen_rtx_AND (DImode, x, GEN_INT (0xfffffffffffff)),
+ GEN_INT (codes[i].value));
break;
default:
gcc_unreachable ();
@@ -4178,10 +4222,13 @@ loongarch_emit_int_compare (enum rtx_code *code, rtx *op0, rtx *op1)
if (!increment && !decrement)
continue;
+ if ((increment && rhs == HOST_WIDE_INT_MAX)
+ || (decrement && rhs == HOST_WIDE_INT_MIN))
+ break;
+
new_rhs = rhs + (increment ? 1 : -1);
if (loongarch_integer_cost (new_rhs)
- < loongarch_integer_cost (rhs)
- && (rhs < 0) == (new_rhs < 0))
+ < loongarch_integer_cost (rhs))
{
*op1 = GEN_INT (new_rhs);
*code = mag_comparisons[i][increment];
@@ -6097,6 +6144,33 @@ loongarch_option_override_internal (struct gcc_options *opts)
if (loongarch_branch_cost == 0)
loongarch_branch_cost = loongarch_cost->branch_cost;
+ /* Set up parameters to be used in prefetching algorithm. */
+ int simultaneous_prefetches
+ = loongarch_cpu_cache[LARCH_ACTUAL_TUNE].simultaneous_prefetches;
+
+ SET_OPTION_IF_UNSET (opts, &global_options_set,
+ param_simultaneous_prefetches,
+ simultaneous_prefetches);
+
+ SET_OPTION_IF_UNSET (opts, &global_options_set,
+ param_l1_cache_line_size,
+ loongarch_cpu_cache[LARCH_ACTUAL_TUNE].l1d_line_size);
+
+ SET_OPTION_IF_UNSET (opts, &global_options_set,
+ param_l1_cache_size,
+ loongarch_cpu_cache[LARCH_ACTUAL_TUNE].l1d_size);
+
+ SET_OPTION_IF_UNSET (opts, &global_options_set,
+ param_l2_cache_size,
+ loongarch_cpu_cache[LARCH_ACTUAL_TUNE].l2d_size);
+
+
+ /* Enable sw prefetching at -O3 and higher. */
+ if (opts->x_flag_prefetch_loop_arrays < 0
+ && (opts->x_optimize >= 3 || opts->x_flag_profile_use)
+ && !opts->x_optimize_size)
+ opts->x_flag_prefetch_loop_arrays = 1;
+
if (TARGET_DIRECT_EXTERN_ACCESS && flag_shlib)
error ("%qs cannot be used for compiling a shared library",
"-mdirect-extern-access");
@@ -6128,6 +6202,15 @@ loongarch_option_override_internal (struct gcc_options *opts)
gcc_unreachable ();
}
+ /* Validate the guard size. */
+ int guard_size = param_stack_clash_protection_guard_size;
+
+ /* Enforce that interval is the same size as size so the mid-end does the
+ right thing. */
+ SET_OPTION_IF_UNSET (opts, &global_options_set,
+ param_stack_clash_protection_probe_interval,
+ guard_size);
+
loongarch_init_print_operand_punct ();
/* Set up array to map GCC register number to debug register number.
diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h
index f4a9c32..a402d3b 100644
--- a/gcc/config/loongarch/loongarch.h
+++ b/gcc/config/loongarch/loongarch.h
@@ -668,6 +668,10 @@ enum reg_class
#define STACK_BOUNDARY (TARGET_ABI_LP64 ? 128 : 64)
+/* This value controls how many pages we manually unroll the loop for when
+ generating stack clash probes. */
+#define STACK_CLASH_MAX_UNROLL_PAGES 4
+
/* Symbolic macros for the registers used to return integer and floating
point values. */
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index 214b14b..f61db66 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -37,6 +37,12 @@
UNSPEC_FCLASS
UNSPEC_FMAX
UNSPEC_FMIN
+ UNSPEC_FCOPYSIGN
+ UNSPEC_FTINT
+ UNSPEC_FTINTRM
+ UNSPEC_FTINTRP
+ UNSPEC_FSCALEB
+ UNSPEC_FLOGB
;; Override return address for exception handling.
UNSPEC_EH_RETURN
@@ -212,9 +218,12 @@
;; fdiv floating point divide
;; frdiv floating point reciprocal divide
;; fabs floating point absolute value
+;; flogb floating point exponent extract
;; fneg floating point negation
;; fcmp floating point compare
+;; fcopysign floating point copysign
;; fcvt floating point convert
+;; fscaleb floating point scale
;; fsqrt floating point square root
;; frsqrt floating point reciprocal square root
;; multi multiword sequence (or user asm statements)
@@ -226,8 +235,8 @@
"unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,
prefetch,prefetchx,condmove,mgtf,mftg,const,arith,logical,
shift,slt,signext,clz,trap,imul,idiv,move,
- fmove,fadd,fmul,fmadd,fdiv,frdiv,fabs,fneg,fcmp,fcvt,fsqrt,
- frsqrt,accext,accmod,multi,atomic,syncloop,nop,ghost"
+ fmove,fadd,fmul,fmadd,fdiv,frdiv,fabs,flogb,fneg,fcmp,fcopysign,fcvt,
+ fscaleb,fsqrt,frsqrt,accext,accmod,multi,atomic,syncloop,nop,ghost"
(cond [(eq_attr "jirl" "!unset") (const_string "call")
(eq_attr "got" "load") (const_string "load")
@@ -372,6 +381,11 @@
(define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
(DF "TARGET_DOUBLE_FLOAT")])
+;; Iterator for fixed-point modes which can be hold by a hardware
+;; floating-point register.
+(define_mode_iterator ANYFI [(SI "TARGET_HARD_FLOAT")
+ (DI "TARGET_DOUBLE_FLOAT")])
+
;; A mode for which moves involving FPRs may need to be split.
(define_mode_iterator SPLITF
[(DF "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
@@ -408,6 +422,10 @@
;; the controlling mode.
(define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
+;; This attribute gives the integer mode that has the same size of a
+;; floating-point mode.
+(define_mode_attr IMODE [(SF "SI") (DF "DI")])
+
;; This code iterator allows signed and unsigned widening multiplications
;; to use the same template.
(define_code_iterator any_extend [sign_extend zero_extend])
@@ -513,6 +531,19 @@
(define_code_attr sel [(eq "masknez") (ne "maskeqz")])
(define_code_attr selinv [(eq "maskeqz") (ne "masknez")])
+;; Iterator and attributes for floating-point to fixed-point conversion
+;; instructions.
+(define_int_iterator LRINT [UNSPEC_FTINT UNSPEC_FTINTRM UNSPEC_FTINTRP])
+(define_int_attr lrint_pattern [(UNSPEC_FTINT "lrint")
+ (UNSPEC_FTINTRM "lfloor")
+ (UNSPEC_FTINTRP "lceil")])
+(define_int_attr lrint_submenmonic [(UNSPEC_FTINT "")
+ (UNSPEC_FTINTRM "rm")
+ (UNSPEC_FTINTRP "rp")])
+(define_int_attr lrint_allow_inexact [(UNSPEC_FTINT "1")
+ (UNSPEC_FTINTRM "0")
+ (UNSPEC_FTINTRP "0")])
+
;;
;; ....................
;;
@@ -976,6 +1007,69 @@
(set_attr "mode" "<UNITMODE>")])
;;
+;; ....................
+;;
+;; FLOATING POINT COPYSIGN
+;;
+;; ....................
+
+(define_insn "copysign<mode>3"
+ [(set (match_operand:ANYF 0 "register_operand" "=f")
+ (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")
+ (match_operand:ANYF 2 "register_operand" "f")]
+ UNSPEC_FCOPYSIGN))]
+ "TARGET_HARD_FLOAT"
+ "fcopysign.<fmt>\t%0,%1,%2"
+ [(set_attr "type" "fcopysign")
+ (set_attr "mode" "<UNITMODE>")])
+
+;;
+;; ....................
+;;
+;; FLOATING POINT SCALE
+;;
+;; ....................
+
+(define_insn "ldexp<mode>3"
+ [(set (match_operand:ANYF 0 "register_operand" "=f")
+ (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")
+ (match_operand:<IMODE> 2 "register_operand" "f")]
+ UNSPEC_FSCALEB))]
+ "TARGET_HARD_FLOAT"
+ "fscaleb.<fmt>\t%0,%1,%2"
+ [(set_attr "type" "fscaleb")
+ (set_attr "mode" "<UNITMODE>")])
+
+;;
+;; ....................
+;;
+;; FLOATING POINT EXPONENT EXTRACT
+;;
+;; ....................
+
+(define_insn "logb_non_negative<mode>2"
+ [(set (match_operand:ANYF 0 "register_operand" "=f")
+ (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")]
+ UNSPEC_FLOGB))]
+ "TARGET_HARD_FLOAT"
+ "flogb.<fmt>\t%0,%1"
+ [(set_attr "type" "flogb")
+ (set_attr "mode" "<UNITMODE>")])
+
+(define_expand "logb<mode>2"
+ [(set (match_operand:ANYF 0 "register_operand")
+ (unspec:ANYF [(abs:ANYF (match_operand:ANYF 1 "register_operand"))]
+ UNSPEC_FLOGB))]
+ "TARGET_HARD_FLOAT"
+{
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+
+ emit_insn (gen_abs<mode>2 (tmp, operands[1]));
+ emit_insn (gen_logb_non_negative<mode>2 (operands[0], tmp));
+ DONE;
+})
+
+;;
;; ...................
;;
;; Count leading zeroes.
@@ -1624,23 +1718,41 @@
DONE;
})
-(define_insn "*movdi_32bit"
+(define_insn_and_split "*movdi_32bit"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,w,*f,*f,*r,*m")
(match_operand:DI 1 "move_operand" "r,i,w,r,*J*r,*m,*f,*f"))]
"!TARGET_64BIT
&& (register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))"
{ return loongarch_output_move (operands[0], operands[1]); }
+ "CONST_INT_P (operands[1]) && REG_P (operands[0]) && GP_REG_P (REGNO
+ (operands[0]))"
+ [(const_int 0)]
+ "
+{
+ loongarch_move_integer (operands[0], operands[0], INTVAL (operands[1]));
+ DONE;
+}
+ "
[(set_attr "move_type" "move,const,load,store,mgtf,fpload,mftg,fpstore")
(set_attr "mode" "DI")])
-(define_insn "*movdi_64bit"
+(define_insn_and_split "*movdi_64bit"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,w,*f,*f,*r,*m")
(match_operand:DI 1 "move_operand" "r,Yd,w,rJ,*r*J,*m,*f,*f"))]
"TARGET_64BIT
&& (register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))"
{ return loongarch_output_move (operands[0], operands[1]); }
+ "CONST_INT_P (operands[1]) && REG_P (operands[0]) && GP_REG_P (REGNO
+ (operands[0]))"
+ [(const_int 0)]
+ "
+{
+ loongarch_move_integer (operands[0], operands[0], INTVAL (operands[1]));
+ DONE;
+}
+ "
[(set_attr "move_type" "move,const,load,store,mgtf,fpload,mftg,fpstore")
(set_attr "mode" "DI")])
@@ -1655,12 +1767,21 @@
DONE;
})
-(define_insn "*movsi_internal"
+(define_insn_and_split "*movsi_internal"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,w,*f,*f,*r,*m,*r,*z")
(match_operand:SI 1 "move_operand" "r,Yd,w,rJ,*r*J,*m,*f,*f,*z,*r"))]
"(register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
{ return loongarch_output_move (operands[0], operands[1]); }
+ "CONST_INT_P (operands[1]) && REG_P (operands[0]) && GP_REG_P (REGNO
+ (operands[0]))"
+ [(const_int 0)]
+ "
+{
+ loongarch_move_integer (operands[0], operands[0], INTVAL (operands[1]));
+ DONE;
+}
+ "
[(set_attr "move_type" "move,const,load,store,mgtf,fpload,mftg,fpstore,mftg,mgtf")
(set_attr "mode" "SI")])
@@ -1680,12 +1801,21 @@
DONE;
})
-(define_insn "*movhi_internal"
+(define_insn_and_split "*movhi_internal"
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,m,r,k")
(match_operand:HI 1 "move_operand" "r,Yd,I,m,rJ,k,rJ"))]
"(register_operand (operands[0], HImode)
|| reg_or_0_operand (operands[1], HImode))"
{ return loongarch_output_move (operands[0], operands[1]); }
+ "CONST_INT_P (operands[1]) && REG_P (operands[0]) && GP_REG_P (REGNO
+ (operands[0]))"
+ [(const_int 0)]
+ "
+{
+ loongarch_move_integer (operands[0], operands[0], INTVAL (operands[1]));
+ DONE;
+}
+ "
[(set_attr "move_type" "move,const,const,load,store,load,store")
(set_attr "mode" "HI")])
@@ -1992,8 +2122,8 @@
[(set_attr "type" "move")]
)
-;; Convert floating-point numbers to integers
-(define_insn "frint_<fmt>"
+;; Round floating-point numbers to integers
+(define_insn "rint<mode>2"
[(set (match_operand:ANYF 0 "register_operand" "=f")
(unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")]
UNSPEC_FRINT))]
@@ -2002,6 +2132,19 @@
[(set_attr "type" "fcvt")
(set_attr "mode" "<MODE>")])
+;; Convert floating-point numbers to integers
+(define_insn "<lrint_pattern><ANYF:mode><ANYFI:mode>2"
+ [(set (match_operand:ANYFI 0 "register_operand" "=f")
+ (unspec:ANYFI [(match_operand:ANYF 1 "register_operand" "f")]
+ LRINT))]
+ "TARGET_HARD_FLOAT &&
+ (<lrint_allow_inexact>
+ || flag_fp_int_builtin_inexact
+ || !flag_trapping_math)"
+ "ftint<lrint_submenmonic>.<ANYFI:ifmt>.<ANYF:fmt> %0,%1"
+ [(set_attr "type" "fcvt")
+ (set_attr "mode" "<ANYF:MODE>")])
+
;; Load the low word of operand 0 with operand 1.
(define_insn "load_low<mode>"
[(set (match_operand:SPLITF 0 "register_operand" "=f,f")
@@ -3175,6 +3318,20 @@
;; ....................
;;
+(define_insn "prefetch"
+ [(prefetch (match_operand 0 "address_operand" "ZD")
+ (match_operand 1 "const_int_operand" "n")
+ (match_operand 2 "const_int_operand" "n"))]
+ ""
+{
+ switch (INTVAL (operands[1]))
+ {
+ case 0: return "preld\t0,%a0";
+ case 1: return "preld\t8,%a0";
+ default: gcc_unreachable ();
+ }
+})
+
(define_insn "nop"
[(const_int 0)]
""
diff --git a/gcc/config/loongarch/predicates.md b/gcc/config/loongarch/predicates.md
index 8bd0c13..58c3dc2 100644
--- a/gcc/config/loongarch/predicates.md
+++ b/gcc/config/loongarch/predicates.md
@@ -226,7 +226,7 @@
switch (GET_CODE (op))
{
case CONST_INT:
- return !splittable_const_int_operand (op, mode);
+ return true;
case CONST:
case SYMBOL_REF:
diff --git a/gcc/config/loongarch/sync.md b/gcc/config/loongarch/sync.md
index 0c4f198..45be144 100644
--- a/gcc/config/loongarch/sync.md
+++ b/gcc/config/loongarch/sync.md
@@ -448,6 +448,29 @@
}
[(set (attr "length") (const_int 32))])
+(define_insn "atomic_cas_value_exchange_7_<mode>"
+ [(set (match_operand:GPR 0 "register_operand" "=&r")
+ (match_operand:GPR 1 "memory_operand" "+ZC"))
+ (set (match_dup 1)
+ (unspec_volatile:GPR [(match_operand:GPR 2 "reg_or_0_operand" "rJ")
+ (match_operand:GPR 3 "reg_or_0_operand" "rJ")
+ (match_operand:GPR 4 "reg_or_0_operand" "rJ")
+ (match_operand:GPR 5 "reg_or_0_operand" "rJ")
+ (match_operand:SI 6 "const_int_operand")] ;; model
+ UNSPEC_SYNC_EXCHANGE))
+ (clobber (match_scratch:GPR 7 "=&r"))]
+ ""
+{
+ return "%G6\\n\\t"
+ "1:\\n\\t"
+ "ll.<amo>\\t%0,%1\\n\\t"
+ "and\\t%7,%0,%z3\\n\\t"
+ "or%i5\\t%7,%7,%5\\n\\t"
+ "sc.<amo>\\t%7,%1\\n\\t"
+ "beqz\\t%7,1b\\n\\t";
+}
+ [(set (attr "length") (const_int 20))])
+
(define_expand "atomic_exchange<mode>"
[(set (match_operand:SHORT 0 "register_operand")
(unspec_volatile:SHORT
@@ -459,9 +482,9 @@
""
{
union loongarch_gen_fn_ptrs generator;
- generator.fn_7 = gen_atomic_cas_value_cmp_and_7_si;
+ generator.fn_7 = gen_atomic_cas_value_exchange_7_si;
loongarch_expand_atomic_qihi (generator, operands[0], operands[1],
- operands[1], operands[2], operands[3]);
+ const0_rtx, operands[2], operands[3]);
DONE;
})
diff --git a/gcc/config/m68k/predicates.md b/gcc/config/m68k/predicates.md
index f8dedd9..094a189 100644
--- a/gcc/config/m68k/predicates.md
+++ b/gcc/config/m68k/predicates.md
@@ -141,6 +141,8 @@
case CONST:
op = XEXP (op, 0);
+ if (GET_CODE (op) == UNSPEC)
+ return false;
return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
|| GET_CODE (XEXP (op, 0)) == LABEL_REF)
&& GET_CODE (XEXP (op, 1)) == CONST_INT);
diff --git a/gcc/config/mn10300/mn10300.cc b/gcc/config/mn10300/mn10300.cc
index 2a58dd9..f887d9e 100644
--- a/gcc/config/mn10300/mn10300.cc
+++ b/gcc/config/mn10300/mn10300.cc
@@ -285,12 +285,12 @@ mn10300_print_operand (FILE *file, rtx x, int code)
REAL_VALUE_TO_TARGET_DOUBLE
(*CONST_DOUBLE_REAL_VALUE (x), val);
fprintf (file, "0x%lx", val[0]);
- break;;
+ break;
case E_SFmode:
REAL_VALUE_TO_TARGET_SINGLE
(*CONST_DOUBLE_REAL_VALUE (x), val[0]);
fprintf (file, "0x%lx", val[0]);
- break;;
+ break;
case E_VOIDmode:
case E_DImode:
mn10300_print_operand_address (file,
@@ -344,7 +344,7 @@ mn10300_print_operand (FILE *file, rtx x, int code)
REAL_VALUE_TO_TARGET_DOUBLE
(*CONST_DOUBLE_REAL_VALUE (x), val);
fprintf (file, "0x%lx", val[1]);
- break;;
+ break;
case E_SFmode:
gcc_unreachable ();
case E_VOIDmode:
diff --git a/gcc/config/nvptx/mkoffload.cc b/gcc/config/nvptx/mkoffload.cc
index 854cd72..5d89ba8 100644
--- a/gcc/config/nvptx/mkoffload.cc
+++ b/gcc/config/nvptx/mkoffload.cc
@@ -364,7 +364,8 @@ process (FILE *in, FILE *out, uint32_t omp_requires)
Alternatively, besides searching for 'BEGIN FUNCTION DECL',
checking for '.visible .entry ' + id->ptx_name would be
required. */
- if (!endswith (id->ptx_name, "$nohost"))
+ if (!endswith (id->ptx_name, "$nohost")
+ && !strstr (id->ptx_name, "$nohost$"))
continue;
fprintf (out, "\t\".extern ");
const char *p = input + file_idx[fidx];
@@ -402,7 +403,8 @@ process (FILE *in, FILE *out, uint32_t omp_requires)
"$offload_func_table[] = {");
for (comma = "", id = func_ids; id; comma = ",", id = id->next)
fprintf (out, "%s\"\n\t\t\"%s", comma,
- endswith (id->ptx_name, "$nohost") ? id->ptx_name : "0");
+ (endswith (id->ptx_name, "$nohost")
+ || strstr (id->ptx_name, "$nohost$")) ? id->ptx_name : "0");
fprintf (out, "};\\n\";\n\n");
}
diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc
index 2fe120b..ed3807b 100644
--- a/gcc/config/nvptx/nvptx.cc
+++ b/gcc/config/nvptx/nvptx.cc
@@ -7043,7 +7043,7 @@ nvptx_goacc_reduction_fini (gcall *call, offload_attrs *oa)
enum tree_code op
= (enum tree_code)TREE_INT_CST_LOW (gimple_call_arg (call, 4));
gimple_seq seq = NULL;
- tree r = NULL_TREE;;
+ tree r = NULL_TREE;
push_gimplify_context (true);
diff --git a/gcc/config/nvptx/nvptx.h b/gcc/config/nvptx/nvptx.h
index 0afc83b..dc676dc 100644
--- a/gcc/config/nvptx/nvptx.h
+++ b/gcc/config/nvptx/nvptx.h
@@ -35,7 +35,7 @@
'../../gcc.cc:asm_options', 'HAVE_GNU_AS'. */
#define ASM_SPEC "%{v}"
-#define STARTFILE_SPEC "%{mmainkernel:crt0.o}"
+#define STARTFILE_SPEC "%{mmainkernel:crt0.o%s}"
#define TARGET_CPU_CPP_BUILTINS() nvptx_cpu_cpp_builtins ()
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 76ae35d..4138227 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -5071,23 +5071,25 @@
(match_dup 2))))
(const_int 0))])]
""
- "")
+ "
+{
+ if (TARGET_64BIT)
+ operands[2] = force_reg (DImode, operands[2]);
+}")
(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM,rM")
- (match_operand:DI 2 "arith11_operand" "r,I")))
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM")
+ (match_operand:DI 2 "register_operand" "r")))
(trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
(sign_extend:TI (match_dup 2)))
(sign_extend:TI (plus:DI (match_dup 1)
(match_dup 2))))
(const_int 0))]
"TARGET_64BIT"
- "@
- add,tsv,* %2,%1,%0
- addi,tsv,* %2,%1,%0"
- [(set_attr "type" "binary,binary")
- (set_attr "length" "4,4")])
+ "add,tsv,* %2,%1,%0"
+ [(set_attr "type" "binary")
+ (set_attr "length" "4")])
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -5262,23 +5264,25 @@
(match_dup 2))))
(const_int 0))])]
""
- "")
+ "
+{
+ if (TARGET_64BIT)
+ operands[1] = force_reg (DImode, operands[1]);
+}")
(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
- (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (minus:DI (match_operand:DI 1 "register_operand" "r")
+ (match_operand:DI 2 "reg_or_0_operand" "rM")))
(trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
(sign_extend:TI (match_dup 2)))
(sign_extend:TI (minus:DI (match_dup 1)
(match_dup 2))))
(const_int 0))]
"TARGET_64BIT"
- "@
- {subo|sub,tsv} %1,%2,%0
- {subio|subi,tsv} %1,%2,%0"
- [(set_attr "type" "binary,binary")
- (set_attr "length" "4,4")])
+ "sub,tsv,* %1,%2,%0"
+ [(set_attr "type" "binary")
+ (set_attr "length" "4")])
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r,&r")
diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index b44fb95..d17133d 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -39,6 +39,72 @@
[(set_attr "type" "bitmanip")
(set_attr "mode" "<X:MODE>")])
+; When using strength-reduction, we will reduce a multiplication to a
+; sequence of shifts and adds. If this is performed with 32-bit types
+; and followed by a division, the lack of w-form sh[123]add will make
+; combination impossible and lead to a slli + addw being generated.
+; Split the sequence with the knowledge that a w-form div will perform
+; implicit sign-extensions.
+(define_split
+ [(set (match_operand:DI 0 "register_operand")
+ (sign_extend:DI (div:SI (plus:SI (subreg:SI (ashift:DI (match_operand:DI 1 "register_operand")
+ (match_operand:QI 2 "imm123_operand")) 0)
+ (subreg:SI (match_operand:DI 3 "register_operand") 0))
+ (subreg:SI (match_operand:DI 4 "register_operand") 0))))
+ (clobber (match_operand:DI 5 "register_operand"))]
+ "TARGET_64BIT && TARGET_ZBA"
+ [(set (match_dup 5) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
+ (set (match_dup 0) (sign_extend:DI (div:SI (subreg:SI (match_dup 5) 0) (subreg:SI (match_dup 4) 0))))])
+
+; Zba does not provide W-forms of sh[123]add(.uw)?, which leads to an
+; interesting irregularity: we can generate a signed 32-bit result
+; using slli(.uw)?+ addw, but a unsigned 32-bit result can be more
+; efficiently be generated as sh[123]add+zext.w (the .uw can be
+; dropped, if we zero-extend the output anyway).
+;
+; To enable this optimization, we split [ slli(.uw)?, addw, zext.w ]
+; into [ sh[123]add, zext.w ] for use during combine.
+(define_split
+ [(set (match_operand:DI 0 "register_operand")
+ (zero_extend:DI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0)
+ (match_operand:QI 2 "imm123_operand"))
+ (subreg:SI (match_operand:DI 3 "register_operand") 0))))]
+ "TARGET_64BIT && TARGET_ZBA"
+ [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
+ (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))])
+
+(define_split
+ [(set (match_operand:DI 0 "register_operand")
+ (zero_extend:DI (plus:SI (subreg:SI (and:DI (ashift:DI (match_operand:DI 1 "register_operand")
+ (match_operand:QI 2 "imm123_operand"))
+ (match_operand:DI 3 "consecutive_bits_operand")) 0)
+ (subreg:SI (match_operand:DI 4 "register_operand") 0))))]
+ "TARGET_64BIT && TARGET_ZBA
+ && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3]))"
+ [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4)))
+ (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))])
+
+; Make sure that an andi followed by a sh[123]add remains a two instruction
+; sequence--and is not torn apart into slli, slri, add.
+(define_insn_and_split "*andi_add.uw"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
+ (match_operand:QI 2 "imm123_operand" "Ds3"))
+ (match_operand:DI 3 "consecutive_bits_operand" ""))
+ (match_operand:DI 4 "register_operand" "r")))
+ (clobber (match_scratch:DI 5 "=&r"))]
+ "TARGET_64BIT && TARGET_ZBA
+ && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3]))
+ && SMALL_OPERAND (INTVAL (operands[3]) >> INTVAL (operands[2]))"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 5) (and:DI (match_dup 1) (match_dup 3)))
+ (set (match_dup 0) (plus:DI (ashift:DI (match_dup 5) (match_dup 2))
+ (match_dup 4)))]
+{
+ operands[3] = GEN_INT (INTVAL (operands[3]) >> INTVAL (operands[2]));
+})
+
(define_insn "*shNadduw"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI
@@ -128,6 +194,19 @@
[(set_attr "type" "bitmanip")
(set_attr "mode" "<X:MODE>")])
+;; '(a >= 0) ? b : 0' is emitted branchless (from if-conversion). Without a
+;; bit of extra help for combine (i.e., the below split), we end up emitting
+;; not/srai/and instead of combining the not into an andn.
+(define_split
+ [(set (match_operand:DI 0 "register_operand")
+ (and:DI (neg:DI (ge:DI (match_operand:DI 1 "register_operand")
+ (const_int 0)))
+ (match_operand:DI 2 "register_operand")))
+ (clobber (match_operand:DI 3 "register_operand"))]
+ "TARGET_ZBB"
+ [(set (match_dup 3) (ashiftrt:DI (match_dup 1) (const_int 63)))
+ (set (match_dup 0) (and:DI (not:DI (match_dup 3)) (match_dup 2)))])
+
(define_insn "*xor_not<mode>"
[(set (match_operand:X 0 "register_operand" "=r")
(not:X (xor:X (match_operand:X 1 "register_operand" "r")
@@ -242,6 +321,14 @@
"rolw\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
+;; orc.b (or-combine) is added as an unspec for the benefit of the support
+;; for optimized string functions (such as strcmp).
+(define_insn "orcb<mode>2"
+ [(set (match_operand:X 0 "register_operand" "=r")
+ (unspec:X [(match_operand:X 1 "register_operand" "r")] UNSPEC_ORC_B))]
+ "TARGET_ZBB"
+ "orc.b\t%0,%1")
+
(define_insn "bswap<mode>2"
[(set (match_operand:X 0 "register_operand" "=r")
(bswap:X (match_operand:X 1 "register_operand" "r")))]
@@ -281,6 +368,24 @@
"<bitmanip_insn>\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
+;; Optimize the common case of a SImode min/max against a constant
+;; that is safe both for sign- and zero-extension.
+(define_insn_and_split "*minmax"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI
+ (subreg:SI
+ (bitmanip_minmax:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:DI 2 "immediate_operand" "i"))
+ 0)))
+ (clobber (match_scratch:DI 3 "=&r"))
+ (clobber (match_scratch:DI 4 "=&r"))]
+ "TARGET_64BIT && TARGET_ZBB && sext_hwi (INTVAL (operands[2]), 32) >= 0"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
+ (set (match_dup 4) (match_dup 2))
+ (set (match_dup 0) (<minmax_optab>:DI (match_dup 3) (match_dup 4)))])
+
;; ZBS extension.
(define_insn "*bset<mode>"
@@ -329,6 +434,18 @@
"bseti\t%0,%1,%S2"
[(set_attr "type" "bitmanip")])
+;; As long as the SImode operand is not a partial subreg, we can use a
+;; bseti without postprocessing, as the middle end is smart enough to
+;; stay away from the signbit.
+(define_insn "*bsetidisi"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (ior:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand 2 "single_bit_mask_operand" "i")))]
+ "TARGET_ZBS && TARGET_64BIT
+ && !partial_subreg_p (operands[2])"
+ "bseti\t%0,%1,%S2"
+ [(set_attr "type" "bitmanip")])
+
(define_insn "*bclr<mode>"
[(set (match_operand:X 0 "register_operand" "=r")
(and:X (rotate:X (const_int -2)
@@ -346,6 +463,44 @@
"bclri\t%0,%1,%T2"
[(set_attr "type" "bitmanip")])
+;; In case we have "val & ~IMM" where ~IMM has 2 bits set.
+(define_insn_and_split "*bclri<mode>_nottwobits"
+ [(set (match_operand:X 0 "register_operand" "=r")
+ (and:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:X 2 "const_nottwobits_operand" "i")))]
+ "TARGET_ZBS && !paradoxical_subreg_p (operands[1])"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (and:X (match_dup 1) (match_dup 3)))
+ (set (match_dup 0) (and:X (match_dup 0) (match_dup 4)))]
+{
+ unsigned HOST_WIDE_INT bits = ~UINTVAL (operands[2]);
+ unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
+
+ operands[3] = GEN_INT (~bits | topbit);
+ operands[4] = GEN_INT (~topbit);
+})
+
+;; In case of a paradoxical subreg, the sign bit and the high bits are
+;; not allowed to be changed
+(define_insn_and_split "*bclridisi_nottwobits"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (and:DI (match_operand:DI 1 "register_operand" "r")
+ (match_operand:DI 2 "const_nottwobits_operand" "i")))]
+ "TARGET_64BIT && TARGET_ZBS
+ && clz_hwi (~UINTVAL (operands[2])) > 33"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
+ (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
+{
+ unsigned HOST_WIDE_INT bits = ~UINTVAL (operands[2]);
+ unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
+
+ operands[3] = GEN_INT (~bits | topbit);
+ operands[4] = GEN_INT (~topbit);
+})
+
(define_insn "*binv<mode>"
[(set (match_operand:X 0 "register_operand" "=r")
(xor:X (ashift:X (const_int 1)
@@ -373,6 +528,18 @@
"bext\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
+;; When performing `(a & (1UL << bitno)) ? 0 : -1` the combiner
+;; usually has the `bitno` typed as X-mode (i.e. no further
+;; zero-extension is performed around the bitno).
+(define_insn "*bext<mode>"
+ [(set (match_operand:X 0 "register_operand" "=r")
+ (zero_extract:X (match_operand:X 1 "register_operand" "r")
+ (const_int 1)
+ (match_operand:X 2 "register_operand" "r")))]
+ "TARGET_ZBS"
+ "bext\t%0,%1,%2"
+ [(set_attr "type" "bitmanip")])
+
(define_insn "*bexti"
[(set (match_operand:X 0 "register_operand" "=r")
(zero_extract:X (match_operand:X 1 "register_operand" "r")
@@ -381,3 +548,110 @@
"TARGET_ZBS && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
"bexti\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
+
+;; Split for "(a & (1 << BIT_NO)) ? 0 : 1":
+;; We avoid reassociating "(~(a >> BIT_NO)) & 1" into "((~a) >> BIT_NO) & 1",
+;; so we don't have to use a temporary. Instead we extract the bit and then
+;; invert bit 0 ("a ^ 1") only.
+(define_split
+ [(set (match_operand:X 0 "register_operand")
+ (and:X (not:X (lshiftrt:X (match_operand:X 1 "register_operand")
+ (subreg:QI (match_operand:X 2 "register_operand") 0)))
+ (const_int 1)))]
+ "TARGET_ZBS"
+ [(set (match_dup 0) (zero_extract:X (match_dup 1)
+ (const_int 1)
+ (match_dup 2)))
+ (set (match_dup 0) (xor:X (match_dup 0) (const_int 1)))])
+
+;; We can create a polarity-reversed mask (i.e. bit N -> { set = 0, clear = -1 })
+;; using a bext(i) followed by an addi instruction.
+;; This splits the canonical representation of "(a & (1 << BIT_NO)) ? 0 : -1".
+(define_split
+ [(set (match_operand:GPR 0 "register_operand")
+ (neg:GPR (eq:GPR (zero_extract:GPR (match_operand:GPR 1 "register_operand")
+ (const_int 1)
+ (match_operand 2))
+ (const_int 0))))]
+ "TARGET_ZBS"
+ [(set (match_dup 0) (zero_extract:GPR (match_dup 1) (const_int 1) (match_dup 2)))
+ (set (match_dup 0) (plus:GPR (match_dup 0) (const_int -1)))])
+
+;; Catch those cases where we can use a bseti/binvi + ori/xori or
+;; bseti/binvi + bseti/binvi instead of a lui + addi + or/xor sequence.
+(define_insn_and_split "*<or_optab>i<mode>_extrabit"
+ [(set (match_operand:X 0 "register_operand" "=r")
+ (any_or:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:X 2 "uimm_extra_bit_or_twobits" "i")))]
+ "TARGET_ZBS"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (<or_optab>:X (match_dup 1) (match_dup 3)))
+ (set (match_dup 0) (<or_optab>:X (match_dup 0) (match_dup 4)))]
+{
+ unsigned HOST_WIDE_INT bits = UINTVAL (operands[2]);
+ unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
+
+ operands[3] = GEN_INT (bits &~ topbit);
+ operands[4] = GEN_INT (topbit);
+})
+
+;; Same to use blcri + andi and blcri + bclri
+(define_insn_and_split "*andi<mode>_extrabit"
+ [(set (match_operand:X 0 "register_operand" "=r")
+ (and:X (match_operand:X 1 "register_operand" "r")
+ (match_operand:X 2 "not_uimm_extra_bit_or_nottwobits" "i")))]
+ "TARGET_ZBS"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (and:X (match_dup 1) (match_dup 3)))
+ (set (match_dup 0) (and:X (match_dup 0) (match_dup 4)))]
+{
+ unsigned HOST_WIDE_INT bits = UINTVAL (operands[2]);
+ unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (~bits);
+
+ operands[3] = GEN_INT (bits | topbit);
+ operands[4] = GEN_INT (~topbit);
+})
+
+;; IF_THEN_ELSE: test for 2 bits of opposite polarity
+(define_insn_and_split "*branch<X:mode>_mask_twobits_equals_singlebit"
+ [(set (pc)
+ (if_then_else
+ (match_operator 1 "equality_operator"
+ [(and:X (match_operand:X 2 "register_operand" "r")
+ (match_operand:X 3 "const_twobits_not_arith_operand" "i"))
+ (match_operand:X 4 "single_bit_mask_operand" "i")])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))
+ (clobber (match_scratch:X 5 "=&r"))
+ (clobber (match_scratch:X 6 "=&r"))]
+ "TARGET_ZBS && TARGET_ZBB"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 5) (zero_extract:X (match_dup 2)
+ (const_int 1)
+ (match_dup 8)))
+ (set (match_dup 6) (zero_extract:X (match_dup 2)
+ (const_int 1)
+ (match_dup 9)))
+ (set (match_dup 6) (and:X (not:X (match_dup 6)) (match_dup 5)))
+ (set (pc) (if_then_else (match_op_dup 1 [(match_dup 6) (const_int 0)])
+ (label_ref (match_dup 0))
+ (pc)))]
+{
+ unsigned HOST_WIDE_INT twobits_mask = UINTVAL (operands[3]);
+ unsigned HOST_WIDE_INT singlebit_mask = UINTVAL (operands[4]);
+
+ /* We should never see an unsatisfiable condition. */
+ gcc_assert (twobits_mask & singlebit_mask);
+
+ int setbit = ctz_hwi (singlebit_mask);
+ int clearbit = ctz_hwi (twobits_mask & ~singlebit_mask);
+
+ operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE ? EQ : NE,
+ <X:MODE>mode, operands[6], GEN_INT(0));
+
+ operands[8] = GEN_INT (setbit);
+ operands[9] = GEN_INT (clearbit);
+})
diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index 4088c48..51cffb2 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -151,3 +151,8 @@
A constraint that matches a vector of immediate all ones."
(and (match_code "const_vector")
(match_test "op == CONSTM1_RTX (GET_MODE (op))")))
+
+(define_constraint "Wdm"
+ "Vector duplicate memory operand"
+ (and (match_operand 0 "memory_operand")
+ (match_code "reg" "0")))
diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index 50380ec..efdd3cc 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -136,6 +136,10 @@
;; from the same template.
(define_code_iterator any_bitwise [and ior xor])
+;; This code iterator allows ior and xor instructions to be generated
+;; from the same template.
+(define_code_iterator any_or [ior xor])
+
;; This code iterator allows unsigned and signed division to be generated
;; from the same template.
(define_code_iterator any_div [div udiv mod umod])
@@ -194,6 +198,10 @@
(plus "add")
(minus "sub")])
+;; <or_optab> code attributes
+(define_code_attr or_optab [(ior "ior")
+ (xor "xor")])
+
;; <insn> expands to the name of the insn that implements a particular code.
(define_code_attr insn [(ashift "sll")
(ashiftrt "sra")
@@ -213,6 +221,10 @@
[(plus "add") (ior "or") (xor "xor") (and "and")])
; bitmanip code attributes
+(define_code_attr minmax_optab [(smin "smin")
+ (smax "smax")
+ (umin "umin")
+ (umax "umax")])
(define_code_attr bitmanip_optab [(smin "smin")
(smax "smax")
(umin "umin")
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index c2ff41b..5a5a49b 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -285,3 +285,60 @@
(ior (match_operand 0 "register_operand")
(match_test "GET_CODE (op) == UNSPEC
&& (XINT (op, 1) == UNSPEC_VUNDEF)"))))
+
+;; The scalar operand can be directly broadcast by RVV instructions.
+(define_predicate "direct_broadcast_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_test "satisfies_constraint_Wdm (op)")))
+
+;; A CONST_INT operand that has exactly two bits cleared.
+(define_predicate "const_nottwobits_operand"
+ (and (match_code "const_int")
+ (match_test "popcount_hwi (~UINTVAL (op)) == 2")))
+
+;; A CONST_INT operand that consists of a single run of 32 consecutive
+;; set bits.
+(define_predicate "consecutive_bits32_operand"
+ (and (match_operand 0 "consecutive_bits_operand")
+ (match_test "popcount_hwi (UINTVAL (op)) == 32")))
+
+;; A CONST_INT operand that, if shifted down to start with its least
+;; significant non-zero bit, is a SMALL_OPERAND (suitable as an
+;; immediate to logical and arithmetic instructions).
+(define_predicate "shifted_const_arith_operand"
+ (and (match_code "const_int")
+ (match_test "ctz_hwi (INTVAL (op)) > 0")
+ (match_test "SMALL_OPERAND (INTVAL (op) >> ctz_hwi (INTVAL (op)))")))
+
+;; A CONST_INT operand that has exactly two bits set.
+(define_predicate "const_twobits_operand"
+ (and (match_code "const_int")
+ (match_test "popcount_hwi (UINTVAL (op)) == 2")))
+
+(define_predicate "const_twobits_not_arith_operand"
+ (and (match_code "const_int")
+ (and (not (match_operand 0 "arith_operand"))
+ (match_operand 0 "const_twobits_operand"))))
+
+;; A CONST_INT operand that fits into the unsigned half of a
+;; signed-immediate after the top bit has been cleared
+(define_predicate "uimm_extra_bit_operand"
+ (and (match_code "const_int")
+ (match_test "UIMM_EXTRA_BIT_OPERAND (UINTVAL (op))")))
+
+(define_predicate "uimm_extra_bit_or_twobits"
+ (and (match_code "const_int")
+ (ior (match_operand 0 "uimm_extra_bit_operand")
+ (match_operand 0 "const_twobits_operand"))))
+
+;; A CONST_INT operand that fits into the negative half of a
+;; signed-immediate after a single cleared top bit has been
+;; set: i.e., a bitwise-negated uimm_extra_bit_operand
+(define_predicate "not_uimm_extra_bit_operand"
+ (and (match_code "const_int")
+ (match_test "UIMM_EXTRA_BIT_OPERAND (~UINTVAL (op))")))
+
+(define_predicate "not_uimm_extra_bit_or_nottwobits"
+ (and (match_code "const_int")
+ (ior (match_operand 0 "not_uimm_extra_bit_operand")
+ (match_operand 0 "const_nottwobits_operand"))))
diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc
index 021f6c6..24ae22c 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -88,8 +88,6 @@ struct riscv_builtin_description {
};
AVAIL (hard_float, TARGET_HARD_FLOAT || TARGET_ZFINX)
-
-
AVAIL (clean32, TARGET_ZICBOM && !TARGET_64BIT)
AVAIL (clean64, TARGET_ZICBOM && TARGET_64BIT)
AVAIL (flush32, TARGET_ZICBOM && !TARGET_64BIT)
@@ -100,6 +98,7 @@ AVAIL (zero32, TARGET_ZICBOZ && !TARGET_64BIT)
AVAIL (zero64, TARGET_ZICBOZ && TARGET_64BIT)
AVAIL (prefetchi32, TARGET_ZICBOP && !TARGET_64BIT)
AVAIL (prefetchi64, TARGET_ZICBOP && TARGET_64BIT)
+AVAIL (always, (!0))
/* Construct a riscv_builtin_description from the given arguments.
@@ -148,7 +147,8 @@ static const struct riscv_builtin_description riscv_builtins[] = {
#include "riscv-cmo.def"
DIRECT_BUILTIN (frflags, RISCV_USI_FTYPE, hard_float),
- DIRECT_NO_TARGET_BUILTIN (fsflags, RISCV_VOID_FTYPE_USI, hard_float)
+ DIRECT_NO_TARGET_BUILTIN (fsflags, RISCV_VOID_FTYPE_USI, hard_float),
+ DIRECT_NO_TARGET_BUILTIN (pause, RISCV_VOID_FTYPE, always),
};
/* Index I is the function declaration for riscv_builtins[I], or null if the
diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def
index b84ad99..31ad346 100644
--- a/gcc/config/riscv/riscv-cores.def
+++ b/gcc/config/riscv/riscv-cores.def
@@ -36,7 +36,7 @@
RISCV_TUNE("rocket", generic, rocket_tune_info)
RISCV_TUNE("sifive-3-series", generic, rocket_tune_info)
RISCV_TUNE("sifive-5-series", generic, rocket_tune_info)
-RISCV_TUNE("sifive-7-series", generic, sifive_7_tune_info)
+RISCV_TUNE("sifive-7-series", sifive_7, sifive_7_tune_info)
RISCV_TUNE("thead-c906", generic, thead_c906_tune_info)
RISCV_TUNE("size", generic, optimize_size_tune_info)
diff --git a/gcc/config/riscv/riscv-ftypes.def b/gcc/config/riscv/riscv-ftypes.def
index c2b45c6..bf2d307 100644
--- a/gcc/config/riscv/riscv-ftypes.def
+++ b/gcc/config/riscv/riscv-ftypes.def
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
argument type. */
DEF_RISCV_FTYPE (0, (USI))
+DEF_RISCV_FTYPE (0, (VOID))
DEF_RISCV_FTYPE (1, (VOID, USI))
DEF_RISCV_FTYPE (1, (VOID, VOID_PTR))
DEF_RISCV_FTYPE (1, (SI, SI))
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 1dfe8c8..25fd85b 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -73,6 +73,9 @@ enum stack_protector_guard {
#define TARGET_ZICSR ((riscv_zi_subext & MASK_ZICSR) != 0)
#define TARGET_ZIFENCEI ((riscv_zi_subext & MASK_ZIFENCEI) != 0)
+#define MASK_ZAWRS (1 << 0)
+#define TARGET_ZAWRS ((riscv_za_subext & MASK_ZAWRS) != 0)
+
#define MASK_ZBA (1 << 0)
#define MASK_ZBB (1 << 1)
#define MASK_ZBC (1 << 2)
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 5a718bb..e17e003 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -77,6 +77,7 @@ extern bool riscv_gpr_save_operation_p (rtx);
extern void riscv_reinit (void);
extern poly_uint64 riscv_regmode_natural_size (machine_mode);
extern bool riscv_v_ext_vector_mode_p (machine_mode);
+extern bool riscv_shamt_matches_mask_p (int, HOST_WIDE_INT);
/* Routines implemented in riscv-c.cc. */
void riscv_cpu_cpp_builtins (cpp_reader *);
@@ -118,6 +119,18 @@ extern void riscv_run_selftests (void);
#endif
namespace riscv_vector {
+#define RVV_VLMAX gen_rtx_REG (Pmode, X0_REGNUM)
+enum vlmul_type
+{
+ LMUL_1 = 0,
+ LMUL_2 = 1,
+ LMUL_4 = 2,
+ LMUL_8 = 3,
+ LMUL_RESERVED = 4,
+ LMUL_F8 = 5,
+ LMUL_F4 = 6,
+ LMUL_F2 = 7,
+};
/* Routines implemented in riscv-vector-builtins.cc. */
extern void init_builtins (void);
extern const char *mangle_builtin_type (const_tree);
@@ -129,6 +142,9 @@ extern tree builtin_decl (unsigned, bool);
extern rtx expand_builtin (unsigned int, tree, rtx);
extern bool const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
extern bool legitimize_move (rtx, rtx, machine_mode);
+extern void emit_pred_op (unsigned, rtx, rtx, machine_mode);
+extern enum vlmul_type get_vlmul (machine_mode);
+extern unsigned int get_ratio (machine_mode);
enum tail_policy
{
TAIL_UNDISTURBED = 0,
diff --git a/gcc/config/riscv/riscv-selftests.cc b/gcc/config/riscv/riscv-selftests.cc
index 636874e..1bf1a64 100644
--- a/gcc/config/riscv/riscv-selftests.cc
+++ b/gcc/config/riscv/riscv-selftests.cc
@@ -33,6 +33,9 @@ along with GCC; see the file COPYING3. If not see
#include "expr.h"
#include "selftest.h"
#include "selftest-rtl.h"
+#include "insn-attr.h"
+#include "target.h"
+#include "optabs.h"
#if CHECKING_P
using namespace selftest;
@@ -230,12 +233,136 @@ run_poly_int_selftests (void)
run_poly_int_selftest ("rv32imafd_zve32x1p0", ABI_ILP32D, POLY_TEST_DIMODE,
worklist);
}
+
+static void
+run_const_vector_selftests (void)
+{
+ /* We dont't need to do the redundant tests in different march && mabi.
+ Just pick up the march && mabi which fully support all RVV modes. */
+ riscv_selftest_arch_abi_setter rv ("rv64imafdcv", ABI_LP64D);
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("riscv/empty-func.rtl"));
+ set_new_first_and_last_insn (NULL, NULL);
+
+ machine_mode mode;
+ std::vector<HOST_WIDE_INT> worklist = {-111, -17, -16, 7, 15, 16, 111};
+
+ FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
+ {
+ if (riscv_v_ext_vector_mode_p (mode))
+ {
+ for (const HOST_WIDE_INT &val : worklist)
+ {
+ start_sequence ();
+ rtx dest = gen_reg_rtx (mode);
+ rtx dup = gen_const_vec_duplicate (mode, GEN_INT (val));
+ emit_move_insn (dest, dup);
+ rtx_insn *insn = get_last_insn ();
+ rtx src = XEXP (SET_SRC (PATTERN (insn)), 1);
+ /* 1. Should be vmv.v.i for in rang of -16 ~ 15.
+ 2. Should be vmv.v.x for exceed -16 ~ 15. */
+ if (IN_RANGE (val, -16, 15))
+ ASSERT_TRUE (rtx_equal_p (src, dup));
+ else
+ ASSERT_TRUE (
+ rtx_equal_p (src,
+ gen_rtx_VEC_DUPLICATE (mode, XEXP (src, 0))));
+ end_sequence ();
+ }
+ }
+ }
+
+ FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_FLOAT)
+ {
+ if (riscv_v_ext_vector_mode_p (mode))
+ {
+ scalar_mode inner_mode = GET_MODE_INNER (mode);
+ REAL_VALUE_TYPE f = REAL_VALUE_ATOF ("0.2928932", inner_mode);
+ rtx ele = const_double_from_real_value (f, inner_mode);
+
+ start_sequence ();
+ rtx dest = gen_reg_rtx (mode);
+ rtx dup = gen_const_vec_duplicate (mode, ele);
+ emit_move_insn (dest, dup);
+ rtx_insn *insn = get_last_insn ();
+ rtx src = XEXP (SET_SRC (PATTERN (insn)), 1);
+ /* Should always be vfmv.v.f. */
+ ASSERT_TRUE (
+ rtx_equal_p (src, gen_rtx_VEC_DUPLICATE (mode, XEXP (src, 0))));
+ end_sequence ();
+ }
+ }
+
+ FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_BOOL)
+ {
+ /* Test vmset.m. */
+ if (riscv_v_ext_vector_mode_p (mode))
+ {
+ start_sequence ();
+ rtx dest = gen_reg_rtx (mode);
+ emit_move_insn (dest, CONSTM1_RTX (mode));
+ rtx_insn *insn = get_last_insn ();
+ rtx src = XEXP (SET_SRC (PATTERN (insn)), 1);
+ ASSERT_TRUE (rtx_equal_p (src, CONSTM1_RTX (mode)));
+ end_sequence ();
+ }
+ }
+}
+
+static void
+run_broadcast_selftests (void)
+{
+ /* We dont't need to do the redundant tests in different march && mabi.
+ Just pick up the march && mabi which fully support all RVV modes. */
+ riscv_selftest_arch_abi_setter rv ("rv64imafdcv", ABI_LP64D);
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("riscv/empty-func.rtl"));
+ set_new_first_and_last_insn (NULL, NULL);
+
+ machine_mode mode;
+
+#define BROADCAST_TEST(MODE_CLASS) \
+ FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT) \
+ { \
+ if (riscv_v_ext_vector_mode_p (mode)) \
+ { \
+ rtx_insn *insn; \
+ rtx src; \
+ scalar_mode inner_mode = GET_MODE_INNER (mode); \
+ /* Test vlse.v with zero stride. */ \
+ start_sequence (); \
+ rtx addr = gen_reg_rtx (Pmode); \
+ rtx mem = gen_rtx_MEM (inner_mode, addr); \
+ expand_vector_broadcast (mode, mem); \
+ insn = get_last_insn (); \
+ src = XEXP (SET_SRC (PATTERN (insn)), 1); \
+ ASSERT_TRUE (MEM_P (XEXP (src, 0))); \
+ ASSERT_TRUE ( \
+ rtx_equal_p (src, gen_rtx_VEC_DUPLICATE (mode, XEXP (src, 0)))); \
+ end_sequence (); \
+ /* Test vmv.v.x or vfmv.v.f. */ \
+ start_sequence (); \
+ rtx reg = gen_reg_rtx (inner_mode); \
+ expand_vector_broadcast (mode, reg); \
+ insn = get_last_insn (); \
+ src = XEXP (SET_SRC (PATTERN (insn)), 1); \
+ ASSERT_TRUE (REG_P (XEXP (src, 0))); \
+ ASSERT_TRUE ( \
+ rtx_equal_p (src, gen_rtx_VEC_DUPLICATE (mode, XEXP (src, 0)))); \
+ end_sequence (); \
+ } \
+ }
+
+ BROADCAST_TEST (MODE_VECTOR_INT)
+ BROADCAST_TEST (MODE_VECTOR_FLOAT)
+}
+
namespace selftest {
/* Run all target-specific selftests. */
void
riscv_run_selftests (void)
{
run_poly_int_selftests ();
+ run_const_vector_selftests ();
+ run_broadcast_selftests ();
}
} // namespace selftest
#endif /* #if CHECKING_P */
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 6615a5c..4992ff2 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -40,6 +40,7 @@
#include "target.h"
#include "expr.h"
#include "optabs.h"
+#include "tm-constrs.h"
using namespace riscv_vector;
@@ -104,37 +105,81 @@ const_vec_all_same_in_range_p (rtx x, HOST_WIDE_INT minval,
&& IN_RANGE (INTVAL (elt), minval, maxval));
}
+static rtx
+emit_vlmax_vsetvl (machine_mode vmode)
+{
+ rtx vl = gen_reg_rtx (Pmode);
+ unsigned int sew = GET_MODE_CLASS (vmode) == MODE_VECTOR_BOOL
+ ? 8
+ : GET_MODE_BITSIZE (GET_MODE_INNER (vmode));
+
+ emit_insn (
+ gen_vsetvl_no_side_effects (Pmode, vl, RVV_VLMAX, gen_int_mode (sew, Pmode),
+ gen_int_mode ((unsigned int) vmode, Pmode),
+ const1_rtx, const1_rtx));
+ return vl;
+}
+
/* Emit an RVV unmask && vl mov from SRC to DEST. */
-static void
-emit_pred_move (rtx dest, rtx src, rtx vl, machine_mode mask_mode)
+void
+emit_pred_op (unsigned icode, rtx dest, rtx src, machine_mode mask_mode)
{
insn_expander<7> e;
-
machine_mode mode = GET_MODE (dest);
- if (register_operand (src, mode) && register_operand (dest, mode))
+
+ e.add_output_operand (dest, mode);
+ e.add_all_one_mask_operand (mask_mode);
+ e.add_vundef_operand (mode);
+
+ e.add_input_operand (src, GET_MODE (src));
+
+ rtx vlmax = emit_vlmax_vsetvl (mode);
+ e.add_input_operand (vlmax, Pmode);
+
+ if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
+ e.add_policy_operand (TAIL_AGNOSTIC, MASK_AGNOSTIC);
+
+ e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src));
+}
+
+static void
+expand_const_vector (rtx target, rtx src, machine_mode mask_mode)
+{
+ machine_mode mode = GET_MODE (target);
+ scalar_mode elt_mode = GET_MODE_INNER (mode);
+ if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
{
- emit_move_insn (dest, src);
+ rtx elt;
+ gcc_assert (
+ const_vec_duplicate_p (src, &elt)
+ && (rtx_equal_p (elt, const0_rtx) || rtx_equal_p (elt, const1_rtx)));
+ emit_pred_op (code_for_pred_mov (mode), target, src, mode);
return;
}
- e.add_output_operand (dest, mode);
- e.add_all_one_mask_operand (mask_mode);
- /* For load operation, we create undef operand.
- For store operation, we make it depend on the dest memory to
- avoid potential bugs. */
- if (MEM_P (src))
- e.add_vundef_operand (mode);
- else
- e.add_input_operand (dest, mode);
+ rtx elt;
+ if (const_vec_duplicate_p (src, &elt))
+ {
+ rtx tmp = register_operand (target, mode) ? target : gen_reg_rtx (mode);
+ /* Element in range -16 ~ 15 integer or 0.0 floating-point,
+ we use vmv.v.i instruction. */
+ if (satisfies_constraint_vi (src) || satisfies_constraint_Wc0 (src))
+ emit_pred_op (code_for_pred_mov (mode), tmp, src, mask_mode);
+ else
+ emit_pred_op (code_for_pred_broadcast (mode), tmp,
+ force_reg (elt_mode, elt), mask_mode);
- e.add_input_operand (src, mode);
- e.add_input_operand (vl, Pmode);
+ if (tmp != target)
+ emit_move_insn (target, tmp);
+ return;
+ }
- e.add_policy_operand (TAIL_AGNOSTIC, MASK_AGNOSTIC);
+ /* TODO: We only support const duplicate vector for now. More cases
+ will be supported when we support auto-vectorization:
- enum insn_code icode;
- icode = code_for_pred_mov (mode);
- e.expand (icode, true);
+ 1. series vector.
+ 2. multiple elts duplicate vector.
+ 3. multiple patterns with multiple elts. */
}
/* Expand a pre-RA RVV data move from SRC to DEST.
@@ -143,38 +188,72 @@ bool
legitimize_move (rtx dest, rtx src, machine_mode mask_mode)
{
machine_mode mode = GET_MODE (dest);
- /* For whole registers load/store or register-register move,
- we don't need to specially handle them, just let them go
- through "*mov<mode>" and then use the codegen directly. */
- if ((known_ge (GET_MODE_SIZE (mode), BYTES_PER_RISCV_VECTOR)
- && (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL))
- || (register_operand (src, mode) && register_operand (dest, mode)))
+ if (CONST_VECTOR_P (src))
+ {
+ expand_const_vector (dest, src, mask_mode);
+ return true;
+ }
+ if (known_ge (GET_MODE_SIZE (mode), BYTES_PER_RISCV_VECTOR)
+ && GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
{
/* Need to force register if mem <- !reg. */
if (MEM_P (dest) && !REG_P (src))
src = force_reg (mode, src);
+
return false;
}
-
- rtx vlmax = gen_reg_rtx (Pmode);
- unsigned int sew = GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL
- ? 8
- : GET_MODE_BITSIZE (GET_MODE_INNER (mode));
- emit_insn (gen_vsetvl_no_side_effects (
- Pmode, vlmax, gen_rtx_REG (Pmode, 0), gen_int_mode (sew, Pmode),
- gen_int_mode ((unsigned int) mode, Pmode), const1_rtx, const1_rtx));
-
if (!register_operand (src, mode) && !register_operand (dest, mode))
{
rtx tmp = gen_reg_rtx (mode);
if (MEM_P (src))
- emit_pred_move (tmp, src, vlmax, mask_mode);
+ emit_pred_op (code_for_pred_mov (mode), tmp, src, mask_mode);
else
emit_move_insn (tmp, src);
src = tmp;
}
- emit_pred_move (dest, src, vlmax, mask_mode);
+ emit_pred_op (code_for_pred_mov (mode), dest, src, mask_mode);
return true;
}
+/* VTYPE information for machine_mode. */
+struct mode_vtype_group
+{
+ enum vlmul_type vlmul_for_min_vlen32[NUM_MACHINE_MODES];
+ uint8_t ratio_for_min_vlen32[NUM_MACHINE_MODES];
+ enum vlmul_type vlmul_for_min_vlen64[NUM_MACHINE_MODES];
+ uint8_t ratio_for_min_vlen64[NUM_MACHINE_MODES];
+ mode_vtype_group ()
+ {
+#define ENTRY(MODE, REQUIREMENT, VLMUL_FOR_MIN_VLEN32, RATIO_FOR_MIN_VLEN32, \
+ VLMUL_FOR_MIN_VLEN64, RATIO_FOR_MIN_VLEN64) \
+ vlmul_for_min_vlen32[MODE##mode] = VLMUL_FOR_MIN_VLEN32; \
+ ratio_for_min_vlen32[MODE##mode] = RATIO_FOR_MIN_VLEN32; \
+ vlmul_for_min_vlen64[MODE##mode] = VLMUL_FOR_MIN_VLEN64; \
+ ratio_for_min_vlen64[MODE##mode] = RATIO_FOR_MIN_VLEN64;
+#include "riscv-vector-switch.def"
+ }
+};
+
+static mode_vtype_group mode_vtype_infos;
+
+/* Get vlmul field value by comparing LMUL with BYTES_PER_RISCV_VECTOR. */
+enum vlmul_type
+get_vlmul (machine_mode mode)
+{
+ if (TARGET_MIN_VLEN == 32)
+ return mode_vtype_infos.vlmul_for_min_vlen32[mode];
+ else
+ return mode_vtype_infos.vlmul_for_min_vlen64[mode];
+}
+
+/* Get ratio according to machine mode. */
+unsigned int
+get_ratio (machine_mode mode)
+{
+ if (TARGET_MIN_VLEN == 32)
+ return mode_vtype_infos.ratio_for_min_vlen32[mode];
+ else
+ return mode_vtype_infos.ratio_for_min_vlen64[mode];
+}
+
} // namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-switch.def b/gcc/config/riscv/riscv-vector-switch.def
index ee8ebd5..a51f45b 100644
--- a/gcc/config/riscv/riscv-vector-switch.def
+++ b/gcc/config/riscv/riscv-vector-switch.def
@@ -80,7 +80,8 @@ TODO: FP16 vector needs support of 'zvfh', we don't support it yet. */
/* Return 'REQUIREMENT' for machine_mode 'MODE'.
For example: 'MODE' = VNx64BImode needs TARGET_MIN_VLEN > 32. */
#ifndef ENTRY
-#define ENTRY(MODE, REQUIREMENT)
+#define ENTRY(MODE, REQUIREMENT, VLMUL_FOR_MIN_VLEN32, RATIO_FOR_MIN_VLEN32, \
+ VLMUL_FOR_MIN_VLEN64, RATIO_FOR_MIN_VLEN64)
#endif
/* Flag of FP32 vector. */
#ifndef TARGET_VECTOR_FP32
@@ -94,66 +95,68 @@ TODO: FP16 vector needs support of 'zvfh', we don't support it yet. */
#endif
/* Mask modes. Disable VNx64BImode when TARGET_MIN_VLEN == 32. */
-ENTRY (VNx64BI, TARGET_MIN_VLEN > 32)
-ENTRY (VNx32BI, true)
-ENTRY (VNx16BI, true)
-ENTRY (VNx8BI, true)
-ENTRY (VNx4BI, true)
-ENTRY (VNx2BI, true)
-ENTRY (VNx1BI, true)
+ENTRY (VNx64BI, TARGET_MIN_VLEN > 32, LMUL_F8, 64, LMUL_RESERVED, 0)
+ENTRY (VNx32BI, true, LMUL_F4, 32, LMUL_RESERVED, 0)
+ENTRY (VNx16BI, true, LMUL_F2, 16, LMUL_RESERVED, 0)
+ENTRY (VNx8BI, true, LMUL_1, 8, LMUL_RESERVED, 0)
+ENTRY (VNx4BI, true, LMUL_2, 4, LMUL_RESERVED, 0)
+ENTRY (VNx2BI, true, LMUL_4, 2, LMUL_RESERVED, 0)
+ENTRY (VNx1BI, true, LMUL_8, 1, LMUL_RESERVED, 0)
/* SEW = 8. Disable VNx64QImode when TARGET_MIN_VLEN == 32. */
-ENTRY (VNx64QI, TARGET_MIN_VLEN > 32)
-ENTRY (VNx32QI, true)
-ENTRY (VNx16QI, true)
-ENTRY (VNx8QI, true)
-ENTRY (VNx4QI, true)
-ENTRY (VNx2QI, true)
-ENTRY (VNx1QI, true)
+ENTRY (VNx64QI, TARGET_MIN_VLEN > 32, LMUL_8, 1, LMUL_RESERVED, 0)
+ENTRY (VNx32QI, true, LMUL_8, 1, LMUL_4, 2)
+ENTRY (VNx16QI, true, LMUL_4, 2, LMUL_2, 4)
+ENTRY (VNx8QI, true, LMUL_2, 4, LMUL_1, 8)
+ENTRY (VNx4QI, true, LMUL_1, 8, LMUL_F2, 16)
+ENTRY (VNx2QI, true, LMUL_F2, 16, LMUL_F4, 32)
+ENTRY (VNx1QI, true, LMUL_F4, 32, LMUL_F8, 64)
/* SEW = 16. Disable VNx32HImode when TARGET_MIN_VLEN == 32. */
-ENTRY (VNx32HI, TARGET_MIN_VLEN > 32)
-ENTRY (VNx16HI, true)
-ENTRY (VNx8HI, true)
-ENTRY (VNx4HI, true)
-ENTRY (VNx2HI, true)
-ENTRY (VNx1HI, true)
+ENTRY (VNx32HI, TARGET_MIN_VLEN > 32, LMUL_8, 2, LMUL_RESERVED, 0)
+ENTRY (VNx16HI, true, LMUL_8, 2, LMUL_4, 4)
+ENTRY (VNx8HI, true, LMUL_4, 4, LMUL_2, 8)
+ENTRY (VNx4HI, true, LMUL_2, 8, LMUL_1, 16)
+ENTRY (VNx2HI, true, LMUL_1, 16, LMUL_F2, 32)
+ENTRY (VNx1HI, true, LMUL_F2, 32, LMUL_F4, 64)
/* TODO:Disable all FP16 vector, enable them when 'zvfh' is supported. */
-ENTRY (VNx32HF, false)
-ENTRY (VNx16HF, false)
-ENTRY (VNx8HF, false)
-ENTRY (VNx4HF, false)
-ENTRY (VNx2HF, false)
-ENTRY (VNx1HF, false)
+ENTRY (VNx32HF, false, LMUL_8, 2, LMUL_RESERVED, 0)
+ENTRY (VNx16HF, false, LMUL_8, 2, LMUL_4, 4)
+ENTRY (VNx8HF, false, LMUL_4, 4, LMUL_2, 8)
+ENTRY (VNx4HF, false, LMUL_2, 8, LMUL_1, 16)
+ENTRY (VNx2HF, false, LMUL_1, 16, LMUL_F2, 32)
+ENTRY (VNx1HF, false, LMUL_F2, 32, LMUL_F4, 64)
/* SEW = 32. Disable VNx16SImode when TARGET_MIN_VLEN == 32.
For single-precision floating-point, we need TARGET_VECTOR_FP32 ==
RVV_ENABLE. */
-ENTRY (VNx16SI, TARGET_MIN_VLEN > 32)
-ENTRY (VNx8SI, true)
-ENTRY (VNx4SI, true)
-ENTRY (VNx2SI, true)
-ENTRY (VNx1SI, true)
-
-ENTRY (VNx16SF, TARGET_VECTOR_FP32 && (TARGET_MIN_VLEN > 32))
-ENTRY (VNx8SF, TARGET_VECTOR_FP32)
-ENTRY (VNx4SF, TARGET_VECTOR_FP32)
-ENTRY (VNx2SF, TARGET_VECTOR_FP32)
-ENTRY (VNx1SF, TARGET_VECTOR_FP32)
+ENTRY (VNx16SI, TARGET_MIN_VLEN > 32, LMUL_8, 4, LMUL_RESERVED, 0)
+ENTRY (VNx8SI, true, LMUL_8, 4, LMUL_4, 8)
+ENTRY (VNx4SI, true, LMUL_4, 8, LMUL_2, 4)
+ENTRY (VNx2SI, true, LMUL_2, 16, LMUL_1, 2)
+ENTRY (VNx1SI, true, LMUL_1, 32, LMUL_F2, 1)
+
+ENTRY (VNx16SF, TARGET_VECTOR_FP32 && (TARGET_MIN_VLEN > 32), LMUL_8, 4,
+ LMUL_RESERVED, 0)
+ENTRY (VNx8SF, TARGET_VECTOR_FP32, LMUL_8, 4, LMUL_4, 8)
+ENTRY (VNx4SF, TARGET_VECTOR_FP32, LMUL_4, 8, LMUL_2, 4)
+ENTRY (VNx2SF, TARGET_VECTOR_FP32, LMUL_2, 16, LMUL_1, 2)
+ENTRY (VNx1SF, TARGET_VECTOR_FP32, LMUL_1, 32, LMUL_F2, 1)
/* SEW = 64. Enable when TARGET_MIN_VLEN > 32.
For double-precision floating-point, we need TARGET_VECTOR_FP64 ==
RVV_ENABLE. */
-ENTRY (VNx8DI, TARGET_MIN_VLEN > 32)
-ENTRY (VNx4DI, TARGET_MIN_VLEN > 32)
-ENTRY (VNx2DI, TARGET_MIN_VLEN > 32)
-ENTRY (VNx1DI, TARGET_MIN_VLEN > 32)
-
-ENTRY (VNx8DF, TARGET_VECTOR_FP64 && (TARGET_MIN_VLEN > 32))
-ENTRY (VNx4DF, TARGET_VECTOR_FP64)
-ENTRY (VNx2DF, TARGET_VECTOR_FP64)
-ENTRY (VNx1DF, TARGET_VECTOR_FP64)
+ENTRY (VNx8DI, TARGET_MIN_VLEN > 32, LMUL_RESERVED, 0, LMUL_8, 8)
+ENTRY (VNx4DI, TARGET_MIN_VLEN > 32, LMUL_RESERVED, 0, LMUL_4, 16)
+ENTRY (VNx2DI, TARGET_MIN_VLEN > 32, LMUL_RESERVED, 0, LMUL_2, 32)
+ENTRY (VNx1DI, TARGET_MIN_VLEN > 32, LMUL_RESERVED, 0, LMUL_1, 64)
+
+ENTRY (VNx8DF, TARGET_VECTOR_FP64 && (TARGET_MIN_VLEN > 32), LMUL_RESERVED, 0,
+ LMUL_8, 8)
+ENTRY (VNx4DF, TARGET_VECTOR_FP64, LMUL_RESERVED, 0, LMUL_4, 16)
+ENTRY (VNx2DF, TARGET_VECTOR_FP64, LMUL_RESERVED, 0, LMUL_2, 32)
+ENTRY (VNx1DF, TARGET_VECTOR_FP64, LMUL_RESERVED, 0, LMUL_1, 64)
#undef TARGET_VECTOR_FP32
#undef TARGET_VECTOR_FP64
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 32f9ef9..1f85391 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "target.h"
+#include "backend.h"
#include "tm.h"
#include "rtl.h"
#include "regs.h"
@@ -51,6 +52,7 @@ along with GCC; see the file COPYING3. If not see
#include "optabs.h"
#include "bitmap.h"
#include "df.h"
+#include "function-abi.h"
#include "diagnostic.h"
#include "builtins.h"
#include "predict.h"
@@ -154,6 +156,11 @@ struct GTY(()) machine_function {
/* The current frame information, calculated by riscv_compute_frame_info. */
struct riscv_frame_info frame;
+
+ /* The components already handled by separate shrink-wrapping, which should
+ not be considered by the prologue and epilogue. */
+ bool reg_is_wrapped_separately[FIRST_PSEUDO_REGISTER];
+
};
/* Information about a single argument. */
@@ -618,6 +625,30 @@ riscv_build_integer (struct riscv_integer_op *codes, HOST_WIDE_INT value,
}
}
+ if (!TARGET_64BIT
+ && (value > INT32_MAX || value < INT32_MIN))
+ {
+ unsigned HOST_WIDE_INT loval = sext_hwi (value, 32);
+ unsigned HOST_WIDE_INT hival = sext_hwi ((value - loval) >> 32, 32);
+ struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS];
+ struct riscv_integer_op hicode[RISCV_MAX_INTEGER_OPS];
+ int hi_cost, lo_cost;
+
+ hi_cost = riscv_build_integer_1 (hicode, hival, mode);
+ if (hi_cost < cost)
+ {
+ lo_cost = riscv_build_integer_1 (alt_codes, loval, mode);
+ if (lo_cost + hi_cost < cost)
+ {
+ memcpy (codes, alt_codes,
+ lo_cost * sizeof (struct riscv_integer_op));
+ memcpy (codes + lo_cost, hicode,
+ hi_cost * sizeof (struct riscv_integer_op));
+ cost = lo_cost + hi_cost;
+ }
+ }
+ }
+
return cost;
}
@@ -948,7 +979,7 @@ riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type, machine_mode mode,
bool
riscv_v_ext_vector_mode_p (machine_mode mode)
{
-#define ENTRY(MODE, REQUIREMENT) \
+#define ENTRY(MODE, REQUIREMENT, ...) \
case MODE##mode: \
return REQUIREMENT;
switch (mode)
@@ -1940,6 +1971,37 @@ riscv_legitimize_poly_move (machine_mode mode, rtx dest, rtx tmp, rtx src)
}
}
+/* Adjust scalable frame of vector for prologue && epilogue. */
+
+static void
+riscv_v_adjust_scalable_frame (rtx target, poly_int64 offset, bool epilogue)
+{
+ rtx tmp = RISCV_PROLOGUE_TEMP (Pmode);
+ rtx adjust_size = RISCV_PROLOGUE_TEMP2 (Pmode);
+ rtx insn, dwarf, adjust_frame_rtx;
+
+ riscv_legitimize_poly_move (Pmode, adjust_size, tmp,
+ gen_int_mode (offset, Pmode));
+
+ if (epilogue)
+ insn = gen_add3_insn (target, target, adjust_size);
+ else
+ insn = gen_sub3_insn (target, target, adjust_size);
+
+ insn = emit_insn (insn);
+
+ RTX_FRAME_RELATED_P (insn) = 1;
+
+ adjust_frame_rtx
+ = gen_rtx_SET (target,
+ plus_constant (Pmode, target, epilogue ? offset : -offset));
+
+ dwarf = alloc_reg_note (REG_FRAME_RELATED_EXPR, copy_rtx (adjust_frame_rtx),
+ NULL_RTX);
+
+ REG_NOTES (insn) = dwarf;
+}
+
/* If (set DEST SRC) is not a valid move instruction, emit an equivalent
sequence that is valid. */
@@ -2428,6 +2490,12 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
return false;
case MINUS:
+ if (float_mode_p)
+ *total = tune_param->fp_add[mode == DFmode];
+ else
+ *total = riscv_binary_cost (x, 1, 4);
+ return false;
+
case PLUS:
/* add.uw pattern for zba. */
if (TARGET_ZBA
@@ -2451,6 +2519,19 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
*total = COSTS_N_INSNS (1);
return true;
}
+ /* Before strength-reduction, the shNadd can be expressed as the addition
+ of a multiplication with a power-of-two. If this case is not handled,
+ the strength-reduction in expmed.c will calculate an inflated cost. */
+ if (TARGET_ZBA
+ && mode == word_mode
+ && GET_CODE (XEXP (x, 0)) == MULT
+ && REG_P (XEXP (XEXP (x, 0), 0))
+ && CONST_INT_P (XEXP (XEXP (x, 0), 1))
+ && IN_RANGE (pow2p_hwi (INTVAL (XEXP (XEXP (x, 0), 1))), 1, 3))
+ {
+ *total = COSTS_N_INSNS (1);
+ return true;
+ }
/* shNadd.uw pattern for zba.
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI
@@ -2562,6 +2643,16 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
*total = riscv_extend_cost (XEXP (x, 0), GET_CODE (x) == ZERO_EXTEND);
return false;
+ case BSWAP:
+ if (TARGET_ZBB)
+ {
+ /* RISC-V only defines rev8 for XLEN, so we will need an extra
+ shift-right instruction for smaller modes. */
+ *total = COSTS_N_INSNS (mode == word_mode ? 1 : 2);
+ return true;
+ }
+ return false;
+
case FLOAT:
case UNSIGNED_FLOAT:
case FIX:
@@ -2937,9 +3028,9 @@ riscv_emit_int_order_test (enum rtx_code code, bool *invert_ptr,
}
else if (invert_ptr == 0)
{
- rtx inv_target = riscv_force_binary (GET_MODE (target),
+ rtx inv_target = riscv_force_binary (word_mode,
inv_code, cmp0, cmp1);
- riscv_emit_binary (XOR, target, inv_target, const1_rtx);
+ riscv_emit_binary (EQ, target, inv_target, const0_rtx);
}
else
{
@@ -4138,6 +4229,19 @@ riscv_print_operand (FILE *file, rtx op, int letter)
switch (letter)
{
+ case 'v': {
+ rtx elt;
+
+ if (!const_vec_duplicate_p (op, &elt))
+ output_operand_lossage ("invalid vector constant");
+ else if (satisfies_constraint_Wc0 (op))
+ asm_fprintf (file, "0");
+ else if (satisfies_constraint_vi (op))
+ asm_fprintf (file, "%wd", INTVAL (elt));
+ else
+ output_operand_lossage ("invalid vector constant");
+ break;
+ }
case 'm': {
if (riscv_v_ext_vector_mode_p (mode))
{
@@ -4746,7 +4850,7 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn,
for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
{
- bool handle_reg = TRUE;
+ bool handle_reg = !cfun->machine->reg_is_wrapped_separately[regno];
/* If this is a normal return in a function that calls the eh_return
builtin, then do not restore the eh return data registers as that
@@ -4777,9 +4881,11 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn,
for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
{
+ bool handle_reg = !cfun->machine->reg_is_wrapped_separately[regno];
machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode;
- riscv_save_restore_reg (mode, regno, offset, fn);
+ if (handle_reg)
+ riscv_save_restore_reg (mode, regno, offset, fn);
offset -= GET_MODE_SIZE (mode).to_constant ();
}
}
@@ -4822,21 +4928,29 @@ riscv_restore_reg (rtx reg, rtx mem)
static HOST_WIDE_INT
riscv_first_stack_step (struct riscv_frame_info *frame)
{
- if (SMALL_OPERAND (frame->total_size.to_constant()))
- return frame->total_size.to_constant();
+ HOST_WIDE_INT frame_total_constant_size;
+ if (!frame->total_size.is_constant ())
+ frame_total_constant_size
+ = riscv_stack_align (frame->total_size.coeffs[0])
+ - riscv_stack_align (frame->total_size.coeffs[1]);
+ else
+ frame_total_constant_size = frame->total_size.to_constant ();
+
+ if (SMALL_OPERAND (frame_total_constant_size))
+ return frame_total_constant_size;
HOST_WIDE_INT min_first_step =
- RISCV_STACK_ALIGN ((frame->total_size - frame->fp_sp_offset).to_constant());
+ RISCV_STACK_ALIGN ((frame->total_size - frame->frame_pointer_offset).to_constant());
HOST_WIDE_INT max_first_step = IMM_REACH / 2 - PREFERRED_STACK_BOUNDARY / 8;
- HOST_WIDE_INT min_second_step = frame->total_size.to_constant() - max_first_step;
+ HOST_WIDE_INT min_second_step = frame_total_constant_size - max_first_step;
gcc_assert (min_first_step <= max_first_step);
/* As an optimization, use the least-significant bits of the total frame
size, so that the second adjustment step is just LUI + ADD. */
if (!SMALL_OPERAND (min_second_step)
- && frame->total_size.to_constant() % IMM_REACH < IMM_REACH / 2
- && frame->total_size.to_constant() % IMM_REACH >= min_first_step)
- return frame->total_size.to_constant() % IMM_REACH;
+ && frame_total_constant_size % IMM_REACH < IMM_REACH / 2
+ && frame_total_constant_size % IMM_REACH >= min_first_step)
+ return frame_total_constant_size % IMM_REACH;
if (TARGET_RVC)
{
@@ -4909,12 +5023,12 @@ void
riscv_expand_prologue (void)
{
struct riscv_frame_info *frame = &cfun->machine->frame;
- HOST_WIDE_INT size = frame->total_size.to_constant ();
+ poly_int64 size = frame->total_size;
unsigned mask = frame->mask;
rtx insn;
if (flag_stack_usage_info)
- current_function_static_stack_size = size;
+ current_function_static_stack_size = constant_lower_bound (size);
if (cfun->machine->naked_p)
return;
@@ -4936,7 +5050,9 @@ riscv_expand_prologue (void)
/* Save the registers. */
if ((frame->mask | frame->fmask) != 0)
{
- HOST_WIDE_INT step1 = MIN (size, riscv_first_stack_step (frame));
+ HOST_WIDE_INT step1 = riscv_first_stack_step (frame);
+ if (size.is_constant ())
+ step1 = MIN (size.to_constant(), step1);
insn = gen_add3_insn (stack_pointer_rtx,
stack_pointer_rtx,
@@ -4959,23 +5075,40 @@ riscv_expand_prologue (void)
}
/* Allocate the rest of the frame. */
- if (size > 0)
+ if (known_gt (size, 0))
{
- if (SMALL_OPERAND (-size))
+ /* Two step adjustment:
+ 1.scalable frame. 2.constant frame. */
+ poly_int64 scalable_frame (0, 0);
+ if (!size.is_constant ())
+ {
+ /* First for scalable frame. */
+ poly_int64 scalable_frame = size;
+ scalable_frame.coeffs[0] = size.coeffs[1];
+ riscv_v_adjust_scalable_frame (stack_pointer_rtx, scalable_frame, false);
+ size -= scalable_frame;
+ }
+
+ /* Second step for constant frame. */
+ HOST_WIDE_INT constant_frame = size.to_constant ();
+ if (constant_frame == 0)
+ return;
+
+ if (SMALL_OPERAND (-constant_frame))
{
insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (-size));
+ GEN_INT (-constant_frame));
RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
}
else
{
- riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), GEN_INT (-size));
+ riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), GEN_INT (-constant_frame));
emit_insn (gen_add3_insn (stack_pointer_rtx,
stack_pointer_rtx,
RISCV_PROLOGUE_TEMP (Pmode)));
/* Describe the effect of the previous instructions. */
- insn = plus_constant (Pmode, stack_pointer_rtx, -size);
+ insn = plus_constant (Pmode, stack_pointer_rtx, -constant_frame);
insn = gen_rtx_SET (stack_pointer_rtx, insn);
riscv_set_frame_expr (insn);
}
@@ -5018,7 +5151,7 @@ riscv_expand_epilogue (int style)
Start off by assuming that no registers need to be restored. */
struct riscv_frame_info *frame = &cfun->machine->frame;
unsigned mask = frame->mask;
- HOST_WIDE_INT step1 = frame->total_size.to_constant ();
+ poly_int64 step1 = frame->total_size;
HOST_WIDE_INT step2 = 0;
bool use_restore_libcall = ((style == NORMAL_RETURN)
&& riscv_use_save_libcall (frame));
@@ -5054,11 +5187,27 @@ riscv_expand_epilogue (int style)
riscv_emit_stack_tie ();
need_barrier_p = false;
- rtx adjust = GEN_INT (-frame->hard_frame_pointer_offset.to_constant ());
- if (!SMALL_OPERAND (INTVAL (adjust)))
+ poly_int64 adjust_offset = -frame->hard_frame_pointer_offset;
+ rtx adjust = NULL_RTX;
+
+ if (!adjust_offset.is_constant ())
{
- riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), adjust);
- adjust = RISCV_PROLOGUE_TEMP (Pmode);
+ rtx tmp1 = RISCV_PROLOGUE_TEMP (Pmode);
+ rtx tmp2 = RISCV_PROLOGUE_TEMP2 (Pmode);
+ riscv_legitimize_poly_move (Pmode, tmp1, tmp2,
+ gen_int_mode (adjust_offset, Pmode));
+ adjust = tmp1;
+ }
+ else
+ {
+ if (!SMALL_OPERAND (adjust_offset.to_constant ()))
+ {
+ riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode),
+ GEN_INT (adjust_offset.to_constant ()));
+ adjust = RISCV_PROLOGUE_TEMP (Pmode);
+ }
+ else
+ adjust = GEN_INT (adjust_offset.to_constant ());
}
insn = emit_insn (
@@ -5068,7 +5217,7 @@ riscv_expand_epilogue (int style)
rtx dwarf = NULL_RTX;
rtx cfa_adjust_value = gen_rtx_PLUS (
Pmode, hard_frame_pointer_rtx,
- GEN_INT (-frame->hard_frame_pointer_offset.to_constant ()));
+ gen_int_mode (-frame->hard_frame_pointer_offset, Pmode));
rtx cfa_adjust_rtx = gen_rtx_SET (stack_pointer_rtx, cfa_adjust_value);
dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, cfa_adjust_rtx, dwarf);
RTX_FRAME_RELATED_P (insn) = 1;
@@ -5091,25 +5240,39 @@ riscv_expand_epilogue (int style)
riscv_emit_stack_tie ();
need_barrier_p = false;
- /* Get an rtx for STEP1 that we can add to BASE. */
- rtx adjust = GEN_INT (step1);
- if (!SMALL_OPERAND (step1))
+ /* Restore the scalable frame which is assigned in prologue. */
+ if (!step1.is_constant ())
{
- riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), adjust);
- adjust = RISCV_PROLOGUE_TEMP (Pmode);
+ poly_int64 scalable_frame = step1;
+ scalable_frame.coeffs[0] = step1.coeffs[1];
+ riscv_v_adjust_scalable_frame (stack_pointer_rtx, scalable_frame,
+ true);
+ step1 -= scalable_frame;
}
- insn = emit_insn (
- gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, adjust));
+ /* Get an rtx for STEP1 that we can add to BASE.
+ Skip if adjust equal to zero. */
+ if (step1.to_constant () != 0)
+ {
+ rtx adjust = GEN_INT (step1.to_constant ());
+ if (!SMALL_OPERAND (step1.to_constant ()))
+ {
+ riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), adjust);
+ adjust = RISCV_PROLOGUE_TEMP (Pmode);
+ }
- rtx dwarf = NULL_RTX;
- rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
- GEN_INT (step2));
+ insn = emit_insn (gen_add3_insn (stack_pointer_rtx,
+ stack_pointer_rtx,
+ adjust));
+ rtx dwarf = NULL_RTX;
+ rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+ GEN_INT (step2));
- dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
- RTX_FRAME_RELATED_P (insn) = 1;
+ dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
+ RTX_FRAME_RELATED_P (insn) = 1;
- REG_NOTES (insn) = dwarf;
+ REG_NOTES (insn) = dwarf;
+ }
}
else if (frame_pointer_needed)
{
@@ -5204,6 +5367,163 @@ riscv_epilogue_uses (unsigned int regno)
return false;
}
+/* Implement TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS. */
+
+static sbitmap
+riscv_get_separate_components (void)
+{
+ HOST_WIDE_INT offset;
+ sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER);
+ bitmap_clear (components);
+
+ if (riscv_use_save_libcall (&cfun->machine->frame)
+ || cfun->machine->interrupt_handler_p
+ || !cfun->machine->frame.gp_sp_offset.is_constant ())
+ return components;
+
+ offset = cfun->machine->frame.gp_sp_offset.to_constant ();
+ for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
+ if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
+ {
+ /* We can only wrap registers that have small operand offsets.
+ For large offsets a pseudo register might be needed which
+ cannot be created during the shrink wrapping pass. */
+ if (SMALL_OPERAND (offset))
+ bitmap_set_bit (components, regno);
+
+ offset -= UNITS_PER_WORD;
+ }
+
+ offset = cfun->machine->frame.fp_sp_offset.to_constant ();
+ for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
+ if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
+ {
+ machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode;
+
+ /* We can only wrap registers that have small operand offsets.
+ For large offsets a pseudo register might be needed which
+ cannot be created during the shrink wrapping pass. */
+ if (SMALL_OPERAND (offset))
+ bitmap_set_bit (components, regno);
+
+ offset -= GET_MODE_SIZE (mode).to_constant ();
+ }
+
+ /* Don't mess with the hard frame pointer. */
+ if (frame_pointer_needed)
+ bitmap_clear_bit (components, HARD_FRAME_POINTER_REGNUM);
+
+ bitmap_clear_bit (components, RETURN_ADDR_REGNUM);
+
+ return components;
+}
+
+/* Implement TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB. */
+
+static sbitmap
+riscv_components_for_bb (basic_block bb)
+{
+ bitmap in = DF_LIVE_IN (bb);
+ bitmap gen = &DF_LIVE_BB_INFO (bb)->gen;
+ bitmap kill = &DF_LIVE_BB_INFO (bb)->kill;
+
+ sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER);
+ bitmap_clear (components);
+
+ function_abi_aggregator callee_abis;
+ rtx_insn *insn;
+ FOR_BB_INSNS (bb, insn)
+ if (CALL_P (insn))
+ callee_abis.note_callee_abi (insn_callee_abi (insn));
+ HARD_REG_SET extra_caller_saves = callee_abis.caller_save_regs (*crtl->abi);
+
+ /* GPRs are used in a bb if they are in the IN, GEN, or KILL sets. */
+ for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
+ if (!fixed_regs[regno]
+ && !crtl->abi->clobbers_full_reg_p (regno)
+ && (TEST_HARD_REG_BIT (extra_caller_saves, regno)
+ || bitmap_bit_p (in, regno)
+ || bitmap_bit_p (gen, regno)
+ || bitmap_bit_p (kill, regno)))
+ bitmap_set_bit (components, regno);
+
+ for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
+ if (!fixed_regs[regno]
+ && !crtl->abi->clobbers_full_reg_p (regno)
+ && (TEST_HARD_REG_BIT (extra_caller_saves, regno)
+ || bitmap_bit_p (in, regno)
+ || bitmap_bit_p (gen, regno)
+ || bitmap_bit_p (kill, regno)))
+ bitmap_set_bit (components, regno);
+
+ return components;
+}
+
+/* Implement TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS. */
+
+static void
+riscv_disqualify_components (sbitmap, edge, sbitmap, bool)
+{
+ /* Nothing to do for riscv. */
+}
+
+static void
+riscv_process_components (sbitmap components, bool prologue_p)
+{
+ HOST_WIDE_INT offset;
+ riscv_save_restore_fn fn = prologue_p? riscv_save_reg : riscv_restore_reg;
+
+ offset = cfun->machine->frame.gp_sp_offset.to_constant ();
+ for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
+ if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
+ {
+ if (bitmap_bit_p (components, regno))
+ riscv_save_restore_reg (word_mode, regno, offset, fn);
+
+ offset -= UNITS_PER_WORD;
+ }
+
+ offset = cfun->machine->frame.fp_sp_offset.to_constant ();
+ for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
+ if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
+ {
+ machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode;
+
+ if (bitmap_bit_p (components, regno))
+ riscv_save_restore_reg (mode, regno, offset, fn);
+
+ offset -= GET_MODE_SIZE (mode).to_constant ();
+ }
+}
+
+/* Implement TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS. */
+
+static void
+riscv_emit_prologue_components (sbitmap components)
+{
+ riscv_process_components (components, true);
+}
+
+/* Implement TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS. */
+
+static void
+riscv_emit_epilogue_components (sbitmap components)
+{
+ riscv_process_components (components, false);
+}
+
+static void
+riscv_set_handled_components (sbitmap components)
+{
+ for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
+ if (bitmap_bit_p (components, regno))
+ cfun->machine->reg_is_wrapped_separately[regno] = true;
+
+ for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
+ if (bitmap_bit_p (components, regno))
+ cfun->machine->reg_is_wrapped_separately[regno] = true;
+}
+
/* Return nonzero if this function is known to have a null epilogue.
This allows the optimizer to omit jumps to jumps if no stack
was created. */
@@ -6474,6 +6794,31 @@ riscv_regmode_natural_size (machine_mode mode)
return UNITS_PER_WORD;
}
+/* Implement the TARGET_DWARF_POLY_INDETERMINATE_VALUE hook. */
+
+static unsigned int
+riscv_dwarf_poly_indeterminate_value (unsigned int i, unsigned int *factor,
+ int *offset)
+{
+ /* Polynomial invariant 1 == (VLENB / riscv_bytes_per_vector_chunk) - 1.
+ 1. TARGET_MIN_VLEN == 32, olynomial invariant 1 == (VLENB / 4) - 1.
+ 2. TARGET_MIN_VLEN > 32, olynomial invariant 1 == (VLENB / 8) - 1.
+ */
+ gcc_assert (i == 1);
+ *factor = riscv_bytes_per_vector_chunk;
+ *offset = 1;
+ return RISCV_DWARF_VLENB;
+}
+
+/* Return true if a shift-amount matches the trailing cleared bits on
+ a bitmask. */
+
+bool
+riscv_shamt_matches_mask_p (int shamt, HOST_WIDE_INT mask)
+{
+ return shamt == ctz_hwi (mask);
+}
+
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
@@ -6551,6 +6896,30 @@ riscv_regmode_natural_size (machine_mode mode)
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY riscv_function_arg_boundary
+#undef TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS
+#define TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS \
+ riscv_get_separate_components
+
+#undef TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB
+#define TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB \
+ riscv_components_for_bb
+
+#undef TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS
+#define TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS \
+ riscv_disqualify_components
+
+#undef TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS
+#define TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS \
+ riscv_emit_prologue_components
+
+#undef TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS
+#define TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS \
+ riscv_emit_epilogue_components
+
+#undef TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS
+#define TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS \
+ riscv_set_handled_components
+
/* The generic ELF target does not always have TLS support. */
#ifdef HAVE_AS_TLS
#undef TARGET_HAVE_TLS
@@ -6695,6 +7064,9 @@ riscv_regmode_natural_size (machine_mode mode)
#undef TARGET_VECTOR_ALIGNMENT
#define TARGET_VECTOR_ALIGNMENT riscv_vector_alignment
+#undef TARGET_DWARF_POLY_INDETERMINATE_VALUE
+#define TARGET_DWARF_POLY_INDETERMINATE_VALUE riscv_dwarf_poly_indeterminate_value
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-riscv.h"
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 1385f0a..defb475 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -392,6 +392,7 @@ ASM_MISA_SPEC
/* Define Dwarf for RVV. */
#define RISCV_DWARF_VL (4096 + 0xc20)
#define RISCV_DWARF_VTYPE (4096 + 0xc21)
+#define RISCV_DWARF_VLENB (4096 + 0xc22)
/* Register in which static-chain is passed to a function. */
#define STATIC_CHAIN_REGNUM (GP_TEMP_FIRST + 2)
@@ -405,6 +406,8 @@ ASM_MISA_SPEC
#define RISCV_PROLOGUE_TEMP_REGNUM (GP_TEMP_FIRST)
#define RISCV_PROLOGUE_TEMP(MODE) gen_rtx_REG (MODE, RISCV_PROLOGUE_TEMP_REGNUM)
+#define RISCV_PROLOGUE_TEMP2_REGNUM (GP_TEMP_FIRST + 1)
+#define RISCV_PROLOGUE_TEMP2(MODE) gen_rtx_REG (MODE, RISCV_PROLOGUE_TEMP2_REGNUM)
#define RISCV_CALL_ADDRESS_TEMP_REGNUM (GP_TEMP_FIRST + 1)
#define RISCV_CALL_ADDRESS_TEMP(MODE) \
@@ -590,6 +593,14 @@ enum reg_class
? (VALUE) \
: ((VALUE) & ((HOST_WIDE_INT_1U << 32)-1))))
+/* True if VALUE can be represented as an immediate with 1 extra bit
+ set: we check that it is not a SMALL_OPERAND (as this would be true
+ for all small operands) unmodified and turns into a small operand
+ once we clear the top bit. */
+#define UIMM_EXTRA_BIT_OPERAND(VALUE) \
+ (!SMALL_OPERAND (VALUE) \
+ && SMALL_OPERAND (VALUE & ~(HOST_WIDE_INT_1U << floor_log2 (VALUE))))
+
/* Stack layout; function entry, exit and calling. */
#define STACK_GROWS_DOWNWARD 1
@@ -640,6 +651,9 @@ enum reg_class
#define FP_ARG_FIRST (FP_REG_FIRST + 10)
#define FP_ARG_LAST (FP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1)
+/* Helper macro for RVV vsetvl instruction generation. */
+#define X0_REGNUM GP_REG_FIRST
+
#define CALLEE_SAVED_REG_NUMBER(REGNO) \
((REGNO) >= 8 && (REGNO) <= 9 ? (REGNO) - 8 : \
(REGNO) >= 18 && (REGNO) <= 27 ? (REGNO) - 16 : -1)
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 798f737..df57e2b 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -62,6 +62,9 @@
;; Stack tie
UNSPEC_TIE
+
+ ;; OR-COMBINE
+ UNSPEC_ORC_B
])
(define_c_enum "unspecv" [
@@ -94,6 +97,9 @@
UNSPECV_INVAL
UNSPECV_ZERO
UNSPECV_PREI
+
+ ;; Zihintpause unspec
+ UNSPECV_PAUSE
])
(define_constants
@@ -1910,6 +1916,11 @@
"TARGET_ZIFENCEI"
"fence.i")
+(define_insn "riscv_pause"
+ [(unspec_volatile [(const_int 0)] UNSPECV_PAUSE)]
+ ""
+ "pause")
+
;;
;; ....................
;;
@@ -2205,6 +2216,57 @@
;; Conditional branches
+(define_insn_and_split "*branch<ANYI:mode>_shiftedarith_equals_zero"
+ [(set (pc)
+ (if_then_else (match_operator 1 "equality_operator"
+ [(and:ANYI (match_operand:ANYI 2 "register_operand" "r")
+ (match_operand 3 "shifted_const_arith_operand" "i"))
+ (const_int 0)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))
+ (clobber (match_scratch:X 4 "=&r"))]
+ "!SMALL_OPERAND (INTVAL (operands[3]))"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4) (lshiftrt:X (subreg:X (match_dup 2) 0) (match_dup 6)))
+ (set (match_dup 4) (and:X (match_dup 4) (match_dup 7)))
+ (set (pc) (if_then_else (match_op_dup 1 [(match_dup 4) (const_int 0)])
+ (label_ref (match_dup 0)) (pc)))]
+{
+ HOST_WIDE_INT mask = INTVAL (operands[3]);
+ int trailing = ctz_hwi (mask);
+
+ operands[6] = GEN_INT (trailing);
+ operands[7] = GEN_INT (mask >> trailing);
+})
+
+(define_insn_and_split "*branch<ANYI:mode>_shiftedmask_equals_zero"
+ [(set (pc)
+ (if_then_else (match_operator 1 "equality_operator"
+ [(and:ANYI (match_operand:ANYI 2 "register_operand" "r")
+ (match_operand 3 "consecutive_bits_operand" "i"))
+ (const_int 0)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))
+ (clobber (match_scratch:X 4 "=&r"))]
+ "(INTVAL (operands[3]) >= 0 || !partial_subreg_p (operands[2]))
+ && popcount_hwi (INTVAL (operands[3])) > 1
+ && !SMALL_OPERAND (INTVAL (operands[3]))"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4) (ashift:X (subreg:X (match_dup 2) 0) (match_dup 6)))
+ (set (match_dup 4) (lshiftrt:X (match_dup 4) (match_dup 7)))
+ (set (pc) (if_then_else (match_op_dup 1 [(match_dup 4) (const_int 0)])
+ (label_ref (match_dup 0)) (pc)))]
+{
+ unsigned HOST_WIDE_INT mask = INTVAL (operands[3]);
+ int leading = clz_hwi (mask);
+ int trailing = ctz_hwi (mask);
+
+ operands[6] = GEN_INT (leading);
+ operands[7] = GEN_INT (leading + trailing);
+})
+
(define_insn "*branch<mode>"
[(set (pc)
(if_then_else
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 426ea95..7c3ca48 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -204,6 +204,9 @@ TargetVariable
int riscv_zi_subext
TargetVariable
+int riscv_za_subext
+
+TargetVariable
int riscv_zb_subext
TargetVariable
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 627e2f7..92c4bd0 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -34,6 +34,29 @@
(VNx8DF "TARGET_VECTOR_ELEN_FP_64")
])
+(define_mode_iterator V_WHOLE [
+ (VNx4QI "TARGET_MIN_VLEN == 32") VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN > 32")
+ (VNx2HI "TARGET_MIN_VLEN == 32") VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32")
+ (VNx1SI "TARGET_MIN_VLEN == 32") VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32")
+ VNx1DI VNx2DI VNx4DI (VNx8DI "TARGET_MIN_VLEN > 32")
+ (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN == 32")
+ (VNx2SF "TARGET_VECTOR_ELEN_FP_32")
+ (VNx4SF "TARGET_VECTOR_ELEN_FP_32")
+ (VNx8SF "TARGET_VECTOR_ELEN_FP_32")
+ (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32")
+ (VNx1DF "TARGET_VECTOR_ELEN_FP_64")
+ (VNx2DF "TARGET_VECTOR_ELEN_FP_64")
+ (VNx4DF "TARGET_VECTOR_ELEN_FP_64")
+ (VNx8DF "TARGET_VECTOR_ELEN_FP_64")
+])
+
+(define_mode_iterator V_FRACT [
+ VNx1QI VNx2QI (VNx4QI "TARGET_MIN_VLEN > 32")
+ VNx1HI (VNx2HI "TARGET_MIN_VLEN > 32")
+ (VNx1SI "TARGET_MIN_VLEN > 32")
+ (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32")
+])
+
(define_mode_iterator VB [
VNx1BI VNx2BI VNx4BI VNx8BI VNx16BI VNx32BI
(VNx64BI "TARGET_MIN_VLEN > 32")
@@ -48,6 +71,15 @@
(VNx1DF "VNx1BI") (VNx2DF "VNx2BI") (VNx4DF "VNx4BI") (VNx8DF "VNx8BI")
])
+(define_mode_attr VEL [
+ (VNx1QI "QI") (VNx2QI "QI") (VNx4QI "QI") (VNx8QI "QI") (VNx16QI "QI") (VNx32QI "QI") (VNx64QI "QI")
+ (VNx1HI "HI") (VNx2HI "HI") (VNx4HI "HI") (VNx8HI "HI") (VNx16HI "HI") (VNx32HI "HI")
+ (VNx1SI "SI") (VNx2SI "SI") (VNx4SI "SI") (VNx8SI "SI") (VNx16SI "SI")
+ (VNx1DI "DI") (VNx2DI "DI") (VNx4DI "DI") (VNx8DI "DI")
+ (VNx1SF "SF") (VNx2SF "SF") (VNx4SF "SF") (VNx8SF "SF") (VNx16SF "SF")
+ (VNx1DF "DF") (VNx2DF "DF") (VNx4DF "DF") (VNx8DF "DF")
+])
+
(define_mode_attr sew [
(VNx1QI "8") (VNx2QI "8") (VNx4QI "8") (VNx8QI "8") (VNx16QI "8") (VNx32QI "8") (VNx64QI "8")
(VNx1HI "16") (VNx2HI "16") (VNx4HI "16") (VNx8HI "16") (VNx16HI "16") (VNx32HI "16")
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 451ed23..1b82218 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -34,6 +34,191 @@
UNSPEC_VPREDICATE
])
+(define_constants [
+ (INVALID_ATTRIBUTE 255)
+])
+
+;; True if the type is RVV instructions that include VTYPE
+;; global status register in the use op list.
+;; We known VTYPE has 4 fields: SEW, LMUL, TA, MA.
+;; The instruction need any of VTYPE field is set as true
+;; in this attribute.
+(define_attr "has_vtype_op" "false,true"
+ (cond [(eq_attr "type" "vlde,vste,vldm,vstm,vlds,vsts,\
+ vldux,vldox,vstux,vstox,vldff,\
+ vialu,viwalu,vext,vicalu,vshift,vnshift,vicmp,\
+ vimul,vidiv,viwmul,vimuladd,viwmuladd,vimerge,vimov,\
+ vsalu,vaalu,vsmul,vsshift,vnclip,\
+ vfalu,vfwalu,vfmul,vfdiv,vfwmul,vfmuladd,vfwmuladd,vfsqrt,vfrecp,\
+ vfcmp,vfsgnj,vfclass,vfmerge,vfmov,\
+ vfcvtitof,vfcvtftoi,vfwcvtitof,vfwcvtftoi,\
+ vfwcvtftof,vfncvtitof,vfncvtftoi,vfncvtftof,\
+ vired,viwred,vfred,vfredo,vfwred,vfwredo,\
+ vmalu,vmpop,vmffs,vmsfs,vmiota,vmidx,vimovvx,vimovxv,vfmovvf,vfmovfv,\
+ vislide,vislide1,vfslide1,vgather,vcompress")
+ (const_string "true")]
+ (const_string "false")))
+
+;; True if the type is RVV instructions that include VL
+;; global status register in the use op list.
+;; The instruction need vector length to be specified is set
+;; in this attribute.
+(define_attr "has_vl_op" "false,true"
+ (cond [(eq_attr "type" "vlde,vste,vldm,vstm,vlds,vsts,\
+ vldux,vldox,vstux,vstox,vldff,\
+ vialu,viwalu,vext,vicalu,vshift,vnshift,vicmp,\
+ vimul,vidiv,viwmul,vimuladd,viwmuladd,vimerge,vimov,\
+ vsalu,vaalu,vsmul,vsshift,vnclip,\
+ vfalu,vfwalu,vfmul,vfdiv,vfwmul,vfmuladd,vfwmuladd,vfsqrt,vfrecp,\
+ vfcmp,vfsgnj,vfclass,vfmerge,vfmov,\
+ vfcvtitof,vfcvtftoi,vfwcvtitof,vfwcvtftoi,\
+ vfwcvtftof,vfncvtitof,vfncvtftoi,vfncvtftof,\
+ vired,viwred,vfred,vfredo,vfwred,vfwredo,\
+ vmalu,vmpop,vmffs,vmsfs,vmiota,vmidx,vimovxv,vfmovfv,\
+ vislide,vislide1,vfslide1,vgather,vcompress")
+ (const_string "true")]
+ (const_string "false")))
+
+;; The default SEW of RVV instruction. This attribute doesn't mean the instruction
+;; is necessary to require SEW check for example vlm.v which require ratio to
+;; check. However, we need default value of SEW for vsetvl instruction since there
+;; is no field for ratio in the vsetvl instruction encoding.
+(define_attr "sew" ""
+ (cond [(eq_attr "mode" "VNx1QI,VNx2QI,VNx4QI,VNx8QI,VNx16QI,VNx32QI,VNx64QI,\
+ VNx1BI,VNx2BI,VNx4BI,VNx8BI,VNx16BI,VNx32BI,VNx64BI")
+ (const_int 8)
+ (eq_attr "mode" "VNx1HI,VNx2HI,VNx4HI,VNx8HI,VNx16HI,VNx32HI")
+ (const_int 16)
+ (eq_attr "mode" "VNx1SI,VNx2SI,VNx4SI,VNx8SI,VNx16SI,\
+ VNx1SF,VNx2SF,VNx4SF,VNx8SF,VNx16SF")
+ (const_int 32)
+ (eq_attr "mode" "VNx1DI,VNx2DI,VNx4DI,VNx8DI,\
+ VNx1DF,VNx2DF,VNx4DF,VNx8DF")
+ (const_int 64)]
+ (const_int INVALID_ATTRIBUTE)))
+
+;; Ditto to LMUL.
+(define_attr "vlmul" ""
+ (cond [(eq_attr "mode" "VNx1QI,VNx1BI")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx1QImode)")
+ (eq_attr "mode" "VNx2QI,VNx2BI")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx2QImode)")
+ (eq_attr "mode" "VNx4QI,VNx4BI")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx4QImode)")
+ (eq_attr "mode" "VNx8QI,VNx8BI")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx8QImode)")
+ (eq_attr "mode" "VNx16QI,VNx16BI")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx16QImode)")
+ (eq_attr "mode" "VNx32QI,VNx32BI")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx32QImode)")
+ (eq_attr "mode" "VNx64QI,VNx64BI")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx64QImode)")
+ (eq_attr "mode" "VNx1HI")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx1HImode)")
+ (eq_attr "mode" "VNx2HI")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx2HImode)")
+ (eq_attr "mode" "VNx4HI")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx4HImode)")
+ (eq_attr "mode" "VNx8HI")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx8HImode)")
+ (eq_attr "mode" "VNx16HI")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx16HImode)")
+ (eq_attr "mode" "VNx32HI")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx32HImode)")
+ (eq_attr "mode" "VNx1SI,VNx1SF")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx1SImode)")
+ (eq_attr "mode" "VNx2SI,VNx2SF")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx2SImode)")
+ (eq_attr "mode" "VNx4SI,VNx4SF")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx4SImode)")
+ (eq_attr "mode" "VNx8SI,VNx8SF")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx8SImode)")
+ (eq_attr "mode" "VNx16SI,VNx16SF")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx16SImode)")
+ (eq_attr "mode" "VNx1DI,VNx1DF")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx1DImode)")
+ (eq_attr "mode" "VNx2DI,VNx2DF")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx2DImode)")
+ (eq_attr "mode" "VNx4DI,VNx4DF")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx4DImode)")
+ (eq_attr "mode" "VNx8DI,VNx8DF")
+ (symbol_ref "riscv_vector::get_vlmul(E_VNx8DImode)")]
+ (const_int INVALID_ATTRIBUTE)))
+
+;; It is valid for instruction that require sew/lmul ratio.
+(define_attr "ratio" ""
+ (cond [(eq_attr "type" "vimov,vfmov")
+ (const_int INVALID_ATTRIBUTE)
+ (eq_attr "mode" "VNx1QI,VNx1BI")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)")
+ (eq_attr "mode" "VNx2QI,VNx2BI")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx2QImode)")
+ (eq_attr "mode" "VNx4QI,VNx4BI")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx4QImode)")
+ (eq_attr "mode" "VNx8QI,VNx8BI")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx8QImode)")
+ (eq_attr "mode" "VNx16QI,VNx16BI")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx16QImode)")
+ (eq_attr "mode" "VNx32QI,VNx32BI")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx32QImode)")
+ (eq_attr "mode" "VNx64QI,VNx64BI")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx64QImode)")
+ (eq_attr "mode" "VNx1HI")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx1HImode)")
+ (eq_attr "mode" "VNx2HI")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx2HImode)")
+ (eq_attr "mode" "VNx4HI")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx4HImode)")
+ (eq_attr "mode" "VNx8HI")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx8HImode)")
+ (eq_attr "mode" "VNx16HI")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx16HImode)")
+ (eq_attr "mode" "VNx32HI")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx32HImode)")
+ (eq_attr "mode" "VNx1SI,VNx1SF")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx1SImode)")
+ (eq_attr "mode" "VNx2SI,VNx2SF")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx2SImode)")
+ (eq_attr "mode" "VNx4SI,VNx4SF")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx4SImode)")
+ (eq_attr "mode" "VNx8SI,VNx8SF")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx8SImode)")
+ (eq_attr "mode" "VNx16SI,VNx16SF")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx16SImode)")
+ (eq_attr "mode" "VNx1DI,VNx1DF")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx1DImode)")
+ (eq_attr "mode" "VNx2DI,VNx2DF")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx2DImode)")
+ (eq_attr "mode" "VNx4DI,VNx4DF")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx4DImode)")
+ (eq_attr "mode" "VNx8DI,VNx8DF")
+ (symbol_ref "riscv_vector::get_ratio(E_VNx8DImode)")]
+ (const_int INVALID_ATTRIBUTE)))
+
+;; The index of operand[] to get the merge op.
+(define_attr "merge_op_idx" ""
+ (cond [(eq_attr "type" "vlde,vste,vimov,vfmov,vldm,vstm,vlds,vmalu")
+ (const_int 2)]
+ (const_int INVALID_ATTRIBUTE)))
+
+;; The index of operand[] to get the avl op.
+(define_attr "vl_op_idx" ""
+ (cond [(eq_attr "type" "vlde,vste,vimov,vfmov,vldm,vstm,vlds,vmalu")
+ (const_int 4)]
+ (const_int INVALID_ATTRIBUTE)))
+
+;; The index of operand[] to get the tail policy op.
+(define_attr "tail_policy_op_idx" ""
+ (cond [(eq_attr "type" "vlde,vste,vimov,vfmov,vlds")
+ (const_int 5)]
+ (const_int INVALID_ATTRIBUTE)))
+
+;; The index of operand[] to get the mask policy op.
+(define_attr "mask_policy_op_idx" ""
+ (cond [(eq_attr "type" "vlde,vste,vlds")
+ (const_int 6)]
+ (const_int INVALID_ATTRIBUTE)))
+
;; -----------------------------------------------------------------
;; ---- Miscellaneous Operations
;; -----------------------------------------------------------------
@@ -53,6 +238,36 @@
(match_operand:V 1 "vector_move_operand"))]
"TARGET_VECTOR"
{
+ /* For whole register move, we transform the pattern into the format
+ that excludes the clobber of scratch register.
+
+ We include clobber of a scalar scratch register which is going to be
+ used for emit of vsetvl instruction after reload_completed since we
+ need vsetvl instruction to set VL/VTYPE global status for fractional
+ vector load/store.
+
+ For example:
+ [(set (match_operand:VNx1QI v24)
+ (match_operand:VNx1QI (mem: a4)))
+ (clobber (scratch:SI a5))]
+ ====>> vsetvl a5,zero,e8,mf8
+ ====>> vle8.v v24,(a4)
+
+ Philosophy:
+
+ - Clobber a scalar scratch register for each mov<mode>.
+
+ - Classify the machine_mode mode = <MODE>mode into 2 class:
+ Whole register move and fractional register move.
+
+ - Transform and remove scratch clobber register for whole
+ register move so that we can avoid occupying the scalar
+ registers.
+
+ - We can not leave it to TARGET_SECONDARY_RELOAD since it happens
+ before spilling. The clobber scratch is used by spilling fractional
+ registers in IRA/LRA so it's too early. */
+
if (riscv_vector::legitimize_move (operands[0], operands[1], <VM>mode))
DONE;
})
@@ -61,12 +276,34 @@
;; Also applicable for all register moves.
;; Fractional vector modes load/store are not allowed to match this pattern.
;; Mask modes load/store are not allowed to match this pattern.
-(define_insn "*mov<mode>"
- [(set (match_operand:V 0 "reg_or_mem_operand" "=vr,m,vr")
- (match_operand:V 1 "reg_or_mem_operand" "m,vr,vr"))]
- "TARGET_VECTOR && ((register_operand (operands[0], <MODE>mode)
- && register_operand (operands[1], <MODE>mode))
- || known_ge (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR))"
+;; We seperate "*mov<mode>" into "*mov<mode>_whole" and "*mov<mode>_fract" because
+;; we don't want to include fractional load/store in "*mov<mode>" which will
+;; create unexpected patterns in LRA.
+;; For example:
+;; ira rtl:
+;; (insn 20 19 9 2 (set (reg/v:VNx2QI 97 v1 [ v1 ])
+;; (reg:VNx2QI 134 [ _1 ])) "rvv.c":9:22 571 {*movvnx2qi_fract}
+;; (nil))
+;; When the value of pseudo register 134 of the insn above is discovered already
+;; spilled in the memory during LRA.
+;; LRA will reload this pattern into a memory load instruction pattern.
+;; Because VNx2QI is a fractional vector, we want LRA reload this pattern into
+;; (insn 20 19 9 2 (parallel [
+;; (set (reg:VNx2QI 98 v2 [orig:134 _1 ] [134])
+;; (mem/c:VNx2QI (reg:SI 13 a3 [155]) [1 %sfp+[-2, -2] S[2, 2] A8]))
+;; (clobber (reg:SI 14 a4 [149]))])
+;; So that we could be able to emit vsetvl instruction using clobber sratch a4.
+;; To let LRA generate the expected pattern, we should exclude fractional vector
+;; load/store in "*mov<mode>_whole". Otherwise, it will reload this pattern into:
+;; (insn 20 19 9 2 (set (reg:VNx2QI 98 v2 [orig:134 _1 ] [134])
+;; (mem/c:VNx2QI (reg:SI 13 a3 [155]) [1 %sfp+[-2, -2] S[2, 2] A8])))
+;; which is not the pattern we want.
+;; According the facts above, we make "*mov<mode>_whole" includes load/store/move for whole
+;; vector modes according to '-march' and "*mov<mode>_fract" only include fractional vector modes.
+(define_insn "*mov<mode>_whole"
+ [(set (match_operand:V_WHOLE 0 "reg_or_mem_operand" "=vr, m,vr")
+ (match_operand:V_WHOLE 1 "reg_or_mem_operand" " m,vr,vr"))]
+ "TARGET_VECTOR"
"@
vl%m1re<sew>.v\t%0,%1
vs%m1r.v\t%1,%0
@@ -74,24 +311,52 @@
[(set_attr "type" "vldr,vstr,vmov")
(set_attr "mode" "<MODE>")])
+(define_insn "*mov<mode>_fract"
+ [(set (match_operand:V_FRACT 0 "register_operand" "=vr")
+ (match_operand:V_FRACT 1 "register_operand" " vr"))]
+ "TARGET_VECTOR"
+ "vmv1r.v\t%0,%1"
+ [(set_attr "type" "vmov")
+ (set_attr "mode" "<MODE>")])
+
(define_expand "mov<mode>"
[(set (match_operand:VB 0 "reg_or_mem_operand")
(match_operand:VB 1 "vector_move_operand"))]
"TARGET_VECTOR"
{
if (riscv_vector::legitimize_move (operands[0], operands[1], <MODE>mode))
- DONE;
+ DONE;
})
(define_insn "*mov<mode>"
[(set (match_operand:VB 0 "register_operand" "=vr")
- (match_operand:VB 1 "register_operand" "vr"))]
+ (match_operand:VB 1 "register_operand" " vr"))]
"TARGET_VECTOR"
"vmv1r.v\t%0,%1"
[(set_attr "type" "vmov")
(set_attr "mode" "<MODE>")])
;; -----------------------------------------------------------------
+;; ---- Duplicate Operations
+;; -----------------------------------------------------------------
+
+;; According to GCC internal:
+;; This pattern only handles duplicates of non-constant inputs.
+;; Constant vectors go through the movm pattern instead.
+;; So "direct_broadcast_operand" can only be mem or reg, no CONSTANT.
+(define_expand "vec_duplicate<mode>"
+ [(set (match_operand:V 0 "register_operand")
+ (vec_duplicate:V
+ (match_operand:<VEL> 1 "direct_broadcast_operand")))]
+ "TARGET_VECTOR"
+ {
+ riscv_vector::emit_pred_op (
+ code_for_pred_broadcast (<MODE>mode), operands[0], operands[1], <VM>mode);
+ DONE;
+ }
+)
+
+;; -----------------------------------------------------------------
;; ---- 6. Configuration-Setting Instructions
;; -----------------------------------------------------------------
;; Includes:
@@ -290,50 +555,89 @@
;; (const_int:QI N)]), -15 <= N < 16.
;; 2. (const_vector:VNx1SF repeat [
;; (const_double:SF 0.0 [0x0.0p+0])]).
-(define_insn "@pred_mov<mode>"
+(define_insn_and_split "@pred_mov<mode>"
[(set (match_operand:V 0 "nonimmediate_operand" "=vd, vr, m, vr, vr")
- (if_then_else:V
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" " vm, Wc1, vmWc1, vmWc1, Wc1")
- (match_operand 4 "vector_length_operand" " rK, rK, rK, rK, rK")
- (match_operand 5 "const_int_operand" " i, i, i, i, i")
- (match_operand 6 "const_int_operand" " i, i, i, i, i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (match_operand:V 3 "vector_move_operand" " m, m, vr, vr, viWc0")
- (match_operand:V 2 "vector_merge_operand" " 0, vu, 0, vu0, vu0")))]
+ (if_then_else:V
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, Wc1, vmWc1, Wc1, Wc1")
+ (match_operand 4 "vector_length_operand" " rK, rK, rK, rK, rK")
+ (match_operand 5 "const_int_operand" " i, i, i, i, i")
+ (match_operand 6 "const_int_operand" " i, i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (match_operand:V 3 "vector_move_operand" " m, m, vr, vr, viWc0")
+ (match_operand:V 2 "vector_merge_operand" " 0, vu, vu0, vu0, vu0")))]
"TARGET_VECTOR"
"@
vle<sew>.v\t%0,%3%p1
vle<sew>.v\t%0,%3%p1
vse<sew>.v\t%3,%0%p1
vmv.v.v\t%0,%3
- vmv.v.i\t%0,v%3"
+ vmv.v.i\t%0,%v3"
+ "&& register_operand (operands[0], <MODE>mode)
+ && register_operand (operands[3], <MODE>mode)
+ && satisfies_constraint_vu (operands[2])"
+ [(set (match_dup 0) (match_dup 3))]
+ ""
[(set_attr "type" "vlde,vlde,vste,vimov,vimov")
(set_attr "mode" "<MODE>")])
;; vlm.v/vsm.v/vmclr.m/vmset.m.
;; constraint alternative 0 match vlm.v.
-;; constraint alternative 2 match vsm.v.
+;; constraint alternative 1 match vsm.v.
;; constraint alternative 3 match vmclr.m.
;; constraint alternative 4 match vmset.m.
-(define_insn "@pred_mov<mode>"
- [(set (match_operand:VB 0 "nonimmediate_operand" "=vr, m, vr, vr")
- (if_then_else:VB
- (unspec:VB
- [(match_operand:VB 1 "vector_mask_operand" "Wc1, Wc1, Wc1, Wc1")
- (match_operand 4 "vector_length_operand" " rK, rK, rK, rK")
- (match_operand 5 "const_int_operand" " i, i, i, i")
- (match_operand 6 "const_int_operand" " i, i, i, i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (match_operand:VB 3 "vector_move_operand" " m, vr, Wc0, Wc1")
- (match_operand:VB 2 "vector_merge_operand" " vu, 0, vu, vu")))]
+(define_insn_and_split "@pred_mov<mode>"
+ [(set (match_operand:VB 0 "nonimmediate_operand" "=vr, m, vr, vr, vr")
+ (if_then_else:VB
+ (unspec:VB
+ [(match_operand:VB 1 "vector_mask_operand" "Wc1, Wc1, Wc1, Wc1, Wc1")
+ (match_operand 4 "vector_length_operand" " rK, rK, rK, rK, rK")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (match_operand:VB 3 "vector_move_operand" " m, vr, vr, Wc0, Wc1")
+ (match_operand:VB 2 "vector_merge_operand" " vu, vu0, vu, vu, vu")))]
"TARGET_VECTOR"
"@
vlm.v\t%0,%3
vsm.v\t%3,%0
+ #
vmclr.m\t%0
vmset.m\t%0"
- [(set_attr "type" "vldm,vstm,vmalu,vmalu")
+ "&& register_operand (operands[0], <MODE>mode)
+ && register_operand (operands[3], <MODE>mode)"
+ [(set (match_dup 0) (match_dup 3))]
+ ""
+ [(set_attr "type" "vldm,vstm,vimov,vmalu,vmalu")
+ (set_attr "mode" "<MODE>")])
+
+;; -------------------------------------------------------------------------------
+;; ---- Predicated Broadcast
+;; -------------------------------------------------------------------------------
+;; Includes:
+;; - 7.5. Vector Strided Instructions (zero stride)
+;; - 11.16 Vector Integer Move Instructions (vmv.v.x)
+;; - 13.16 Vector Floating-Point Move Instruction (vfmv.v.f)
+;; -------------------------------------------------------------------------------
+
+(define_insn "@pred_broadcast<mode>"
+ [(set (match_operand:V 0 "register_operand" "=vr, vr, vr, vr")
+ (if_then_else:V
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " Wc1, Wc1, vm, Wc1")
+ (match_operand 4 "vector_length_operand" " rK, rK, rK, rK")
+ (match_operand 5 "const_int_operand" " i, i, i, i")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (vec_duplicate:V
+ (match_operand:<VEL> 3 "direct_broadcast_operand" " r, f, Wdm, Wdm"))
+ (match_operand:V 2 "vector_merge_operand" "vu0, vu0, vu0, vu0")))]
+ "TARGET_VECTOR"
+ "@
+ vmv.v.x\t%0,%3
+ vfmv.v.f\t%0,%3
+ vlse<sew>.v\t%0,%3,zero,%1.t
+ vlse<sew>.v\t%0,%3,zero"
+ [(set_attr "type" "vimov,vfmov,vlds,vlds")
(set_attr "mode" "<MODE>")])
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 2c4940f..8466007 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -1875,7 +1875,7 @@
}
[(set_attr "type" "vecperm")])
-(define_insn "*altivec_vrl<VI_char>"
+(define_insn "altivec_vrl<VI_char>"
[(set (match_operand:VI2 0 "register_operand" "=v")
(rotate:VI2 (match_operand:VI2 1 "register_operand" "v")
(match_operand:VI2 2 "register_operand" "v")))]
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index b1fcc69..a176401 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -760,7 +760,7 @@
return 0;
elt = BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 : 0;
val = const_vector_elt_as_int (op, elt);
- val = ((val & 0xff) ^ 0x80) - 0x80;
+ val = sext_hwi (val, 8);
return EASY_VECTOR_15_ADD_SELF (val);
})
diff --git a/gcc/config/rs6000/rs6000-call.cc b/gcc/config/rs6000/rs6000-call.cc
index 6da4de6..59c51fa 100644
--- a/gcc/config/rs6000/rs6000-call.cc
+++ b/gcc/config/rs6000/rs6000-call.cc
@@ -2802,6 +2802,10 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
return build_va_arg_indirect_ref (addr);
}
+/* Return the permutation index for the swapping on the given vector mode.
+ Note that the permutation index is correspondingly generated by endianness,
+ it should be used by direct vector permutation. */
+
rtx
swap_endian_selector_for_mode (machine_mode mode)
{
@@ -2834,7 +2838,11 @@ swap_endian_selector_for_mode (machine_mode mode)
}
for (i = 0; i < 16; ++i)
- perm[i] = GEN_INT (swaparray[i]);
+ if (BYTES_BIG_ENDIAN)
+ perm[i] = GEN_INT (swaparray[i]);
+ else
+ /* Generates the reversed perm for little endian. */
+ perm[i] = GEN_INT (~swaparray[i] & 0x0000001f);
return force_reg (V16QImode, gen_rtx_CONST_VECTOR (V16QImode,
gen_rtvec_v (16, perm)));
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index a85d7630..b3a609f 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -6021,7 +6021,7 @@ num_insns_constant_gpr (HOST_WIDE_INT value)
else if (TARGET_POWERPC64)
{
- HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
+ HOST_WIDE_INT low = sext_hwi (value, 32);
HOST_WIDE_INT high = value >> 31;
if (high == 0 || high == -1)
@@ -8456,7 +8456,7 @@ darwin_rs6000_legitimate_lo_sum_const_p (rtx x, machine_mode mode)
}
/* We only care if the access(es) would cause a change to the high part. */
- offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
+ offset = sext_hwi (offset, 16);
return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
}
@@ -8522,7 +8522,7 @@ mem_operand_gpr (rtx op, machine_mode mode)
if (GET_CODE (addr) == LO_SUM)
/* For lo_sum addresses, we must allow any offset except one that
causes a wrap, so test only the low 16 bits. */
- offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
+ offset = sext_hwi (offset, 16);
return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
}
@@ -8562,7 +8562,7 @@ mem_operand_ds_form (rtx op, machine_mode mode)
if (GET_CODE (addr) == LO_SUM)
/* For lo_sum addresses, we must allow any offset except one that
causes a wrap, so test only the low 16 bits. */
- offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
+ offset = sext_hwi (offset, 16);
return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
}
@@ -9136,7 +9136,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
{
HOST_WIDE_INT high_int, low_int;
rtx sum;
- low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
+ low_int = sext_hwi (INTVAL (XEXP (x, 1)), 16);
if (low_int >= 0x8000 - extra)
low_int = 0;
high_int = INTVAL (XEXP (x, 1)) - low_int;
@@ -10186,10 +10186,9 @@ rs6000_emit_set_const (rtx dest, rtx source)
case E_SImode:
temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
- emit_insn (gen_rtx_SET (copy_rtx (temp),
- GEN_INT (c & ~(HOST_WIDE_INT) 0xffff)));
+ emit_insn (gen_rtx_SET (temp, GEN_INT (c & ~(HOST_WIDE_INT) 0xffff)));
emit_insn (gen_rtx_SET (dest,
- gen_rtx_IOR (SImode, copy_rtx (temp),
+ gen_rtx_IOR (SImode, temp,
GEN_INT (c & 0xffff))));
break;
@@ -10198,12 +10197,10 @@ rs6000_emit_set_const (rtx dest, rtx source)
{
rtx hi, lo;
- hi = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN == 0,
- DImode);
- lo = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
- DImode);
+ hi = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0, DImode);
+ lo = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0, DImode);
emit_move_insn (hi, GEN_INT (c >> 32));
- c = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
+ c = sext_hwi (c, 32);
emit_move_insn (lo, GEN_INT (c));
}
else
@@ -10242,41 +10239,35 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
|| (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
- emit_move_insn (dest, GEN_INT ((ud1 ^ 0x8000) - 0x8000));
+ emit_move_insn (dest, GEN_INT (sext_hwi (ud1, 16)));
else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
|| (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
{
temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
- emit_move_insn (ud1 != 0 ? copy_rtx (temp) : dest,
- GEN_INT (((ud2 << 16) ^ 0x80000000) - 0x80000000));
+ emit_move_insn (ud1 != 0 ? temp : dest,
+ GEN_INT (sext_hwi (ud2 << 16, 32)));
if (ud1 != 0)
- emit_move_insn (dest,
- gen_rtx_IOR (DImode, copy_rtx (temp),
- GEN_INT (ud1)));
+ emit_move_insn (dest, gen_rtx_IOR (DImode, temp, GEN_INT (ud1)));
}
else if (ud3 == 0 && ud4 == 0)
{
temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
gcc_assert (ud2 & 0x8000);
- emit_move_insn (copy_rtx (temp),
- GEN_INT (((ud2 << 16) ^ 0x80000000) - 0x80000000));
+ emit_move_insn (temp, GEN_INT (sext_hwi (ud2 << 16, 32)));
if (ud1 != 0)
- emit_move_insn (copy_rtx (temp),
- gen_rtx_IOR (DImode, copy_rtx (temp),
- GEN_INT (ud1)));
+ emit_move_insn (temp, gen_rtx_IOR (DImode, temp, GEN_INT (ud1)));
emit_move_insn (dest,
gen_rtx_ZERO_EXTEND (DImode,
- gen_lowpart (SImode,
- copy_rtx (temp))));
+ gen_lowpart (SImode,temp)));
}
else if (ud1 == ud3 && ud2 == ud4)
{
temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
HOST_WIDE_INT num = (ud2 << 16) | ud1;
- rs6000_emit_set_long_const (temp, (num ^ 0x80000000) - 0x80000000);
+ rs6000_emit_set_long_const (temp, sext_hwi (num, 32));
rtx one = gen_rtx_AND (DImode, temp, GEN_INT (0xffffffff));
rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32));
emit_move_insn (dest, gen_rtx_IOR (DImode, one, two));
@@ -10286,19 +10277,13 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
{
temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
- emit_move_insn (copy_rtx (temp),
- GEN_INT (((ud3 << 16) ^ 0x80000000) - 0x80000000));
+ emit_move_insn (temp, GEN_INT (sext_hwi (ud3 << 16, 32)));
if (ud2 != 0)
- emit_move_insn (copy_rtx (temp),
- gen_rtx_IOR (DImode, copy_rtx (temp),
- GEN_INT (ud2)));
- emit_move_insn (ud1 != 0 ? copy_rtx (temp) : dest,
- gen_rtx_ASHIFT (DImode, copy_rtx (temp),
- GEN_INT (16)));
+ emit_move_insn (temp, gen_rtx_IOR (DImode, temp, GEN_INT (ud2)));
+ emit_move_insn (ud1 != 0 ? temp : dest,
+ gen_rtx_ASHIFT (DImode, temp, GEN_INT (16)));
if (ud1 != 0)
- emit_move_insn (dest,
- gen_rtx_IOR (DImode, copy_rtx (temp),
- GEN_INT (ud1)));
+ emit_move_insn (dest, gen_rtx_IOR (DImode, temp, GEN_INT (ud1)));
}
else if (TARGET_PREFIXED)
{
@@ -10339,24 +10324,17 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
{
temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
- emit_move_insn (copy_rtx (temp),
- GEN_INT (((ud4 << 16) ^ 0x80000000) - 0x80000000));
+ emit_move_insn (temp, GEN_INT (sext_hwi (ud4 << 16, 32)));
if (ud3 != 0)
- emit_move_insn (copy_rtx (temp),
- gen_rtx_IOR (DImode, copy_rtx (temp),
- GEN_INT (ud3)));
+ emit_move_insn (temp, gen_rtx_IOR (DImode, temp, GEN_INT (ud3)));
- emit_move_insn (ud2 != 0 || ud1 != 0 ? copy_rtx (temp) : dest,
- gen_rtx_ASHIFT (DImode, copy_rtx (temp),
- GEN_INT (32)));
+ emit_move_insn (ud2 != 0 || ud1 != 0 ? temp : dest,
+ gen_rtx_ASHIFT (DImode, temp, GEN_INT (32)));
if (ud2 != 0)
- emit_move_insn (ud1 != 0 ? copy_rtx (temp) : dest,
- gen_rtx_IOR (DImode, copy_rtx (temp),
- GEN_INT (ud2 << 16)));
+ emit_move_insn (ud1 != 0 ? temp : dest,
+ gen_rtx_IOR (DImode, temp, GEN_INT (ud2 << 16)));
if (ud1 != 0)
- emit_move_insn (dest,
- gen_rtx_IOR (DImode, copy_rtx (temp),
- GEN_INT (ud1)));
+ emit_move_insn (dest, gen_rtx_IOR (DImode, temp, GEN_INT (ud1)));
}
}
@@ -14170,8 +14148,7 @@ print_operand (FILE *file, rtx x, int code)
/* If constant, low-order 16 bits of constant, signed. Otherwise, write
normally. */
if (INT_P (x))
- fprintf (file, HOST_WIDE_INT_PRINT_DEC,
- ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, sext_hwi (INTVAL (x), 16));
else
print_operand (file, x, 0);
return;
@@ -14925,22 +14902,13 @@ rs6000_print_patchable_function_entry (FILE *file,
unsigned HOST_WIDE_INT patch_area_size,
bool record_p)
{
- unsigned int flags = SECTION_WRITE | SECTION_RELRO;
- /* When .opd section is emitted, the function symbol
- default_print_patchable_function_entry_1 is emitted into the .opd section
- while the patchable area is emitted into the function section.
- Don't use SECTION_LINK_ORDER in that case. */
- if (!(TARGET_64BIT && DEFAULT_ABI != ABI_ELFv2)
- && HAVE_GAS_SECTION_LINK_ORDER)
- flags |= SECTION_LINK_ORDER;
bool global_entry_needed_p = rs6000_global_entry_point_prologue_needed_p ();
/* For a function which needs global entry point, we will emit the
patchable area before and after local entry point under the control of
cfun->machine->global_entry_emitted, see the handling in function
rs6000_output_function_prologue. */
if (!global_entry_needed_p || cfun->machine->global_entry_emitted)
- default_print_patchable_function_entry_1 (file, patch_area_size, record_p,
- flags);
+ default_print_patchable_function_entry (file, patch_area_size, record_p);
}
enum rtx_code
@@ -28731,14 +28699,12 @@ constant_generates_xxspltiw (vec_const_128bit_type *vsx_const)
/* See if we can use VSPLTISH or VSPLTISW. */
if (vsx_const->all_half_words_same)
{
- unsigned short h_word = vsx_const->half_words[0];
- short sign_h_word = ((h_word & 0xffff) ^ 0x8000) - 0x8000;
+ short sign_h_word = vsx_const->half_words[0];
if (EASY_VECTOR_15 (sign_h_word))
return 0;
}
- unsigned int word = vsx_const->words[0];
- int sign_word = ((word & 0xffffffff) ^ 0x80000000) - 0x80000000;
+ int sign_word = vsx_const->words[0];
if (EASY_VECTOR_15 (sign_word))
return 0;
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 3bae303..6011f5b 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -1787,7 +1787,7 @@
}
HOST_WIDE_INT val = INTVAL (operands[2]);
- HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
+ HOST_WIDE_INT low = sext_hwi (val, 16);
HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
@@ -1930,7 +1930,7 @@
(set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
{
HOST_WIDE_INT val = INTVAL (operands[2]);
- HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
+ HOST_WIDE_INT low = sext_hwi (val, 16);
HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
operands[4] = GEN_INT (low);
@@ -8213,7 +8213,7 @@
operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
operands[4] = GEN_INT (value >> 32);
- operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
+ operands[1] = GEN_INT (sext_hwi (value, 32));
})
(define_split
@@ -9577,7 +9577,7 @@
operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
DImode);
operands[4] = GEN_INT (value >> 32);
- operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
+ operands[1] = GEN_INT (sext_hwi (value, 32));
})
(define_split
@@ -11913,6 +11913,16 @@
DONE;
})
+(define_expand "cbranchcc4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "branch_comparison_operator"
+ [(match_operand 1 "cc_reg_operand")
+ (match_operand 2 "zero_constant")])
+ (label_ref (match_operand 3))
+ (pc)))]
+ ""
+ "")
+
(define_expand "cstore<mode>4_signed"
[(use (match_operator 1 "signed_comparison_operator"
[(match_operand:P 2 "gpc_reg_operand")
@@ -12425,7 +12435,7 @@
SImode,
operands[1], operands[2]);
HOST_WIDE_INT c = INTVAL (cnst);
- HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
+ HOST_WIDE_INT sextc = sext_hwi (c, 16);
HOST_WIDE_INT xorv = c ^ sextc;
operands[9] = GEN_INT (xorv);
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index e0e34a7..992fbc9 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -6087,12 +6087,21 @@
emit_insn (gen_p9_xxbr<VSX_XXBR>_<mode> (operands[0], operands[1]));
else
{
- /* Want to have the elements in reverse order relative
- to the endian mode in use, i.e. in LE mode, put elements
- in BE order. */
- rtx sel = swap_endian_selector_for_mode(<MODE>mode);
- emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1],
- operands[1], sel));
+ if (<MODE>mode == V8HImode)
+ {
+ rtx splt = gen_reg_rtx (V8HImode);
+ emit_insn (gen_altivec_vspltish (splt, GEN_INT (8)));
+ emit_insn (gen_altivec_vrlh (operands[0], operands[1], splt));
+ }
+ else
+ {
+ /* Want to have the elements in reverse order relative
+ to the endian mode in use, i.e. in LE mode, put elements
+ in BE order. */
+ rtx sel = swap_endian_selector_for_mode (<MODE>mode);
+ emit_insn (gen_altivec_vperm_<mode>_direct (operands[0], operands[1],
+ operands[1], sel));
+ }
}
DONE;
diff --git a/gcc/config/rtems.h b/gcc/config/rtems.h
index 95bcdc4..7ee68af 100644
--- a/gcc/config/rtems.h
+++ b/gcc/config/rtems.h
@@ -56,3 +56,7 @@
/* Prefer int for int32_t (see stdint-newlib.h). */
#undef STDINT_LONG32
#define STDINT_LONG32 (INT_TYPE_SIZE != 32 && LONG_TYPE_SIZE == 32)
+
+/* Default to local-exec TLS model. */
+#undef OS_CC1_SPEC
+#define OS_CC1_SPEC " %{!ftls-model=*:-ftls-model=local-exec}"
diff --git a/gcc/config/sh/sh_treg_combine.cc b/gcc/config/sh/sh_treg_combine.cc
index f6553c0..ab7dc5d 100644
--- a/gcc/config/sh/sh_treg_combine.cc
+++ b/gcc/config/sh/sh_treg_combine.cc
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfgrtl.h"
#include "tree-pass.h"
#include "expr.h"
+#include "tm-preds.h"
/*
This pass tries to optimize for example this:
@@ -426,10 +427,6 @@ is_conditional_insn (rtx_insn* i)
return GET_CODE (p) == SET && GET_CODE (XEXP (p, 1)) == IF_THEN_ELSE;
}
-// FIXME: Remove dependency on SH predicate function somehow.
-extern int t_reg_operand (rtx, machine_mode);
-extern int negt_reg_operand (rtx, machine_mode);
-
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// RTL pass class
diff --git a/gcc/config/xtensa/t-xtensa b/gcc/config/xtensa/t-xtensa
index 6d43b37..4e5b7de 100644
--- a/gcc/config/xtensa/t-xtensa
+++ b/gcc/config/xtensa/t-xtensa
@@ -16,5 +16,11 @@
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
-TM_H += $(srcdir)/../include/xtensa-config.h
+TM_H += $(srcdir)/../include/xtensa-config.h \
+ $(srcdir)/../include/xtensa-dynconfig.h
$(out_object_file): gt-xtensa.h
+
+xtensa-dynconfig.o: $(srcdir)/config/xtensa/xtensa-dynconfig.c \
+ $(CONFIG_H) $(SYSTEM_H) $(srcdir)/../include/xtensa-dynconfig.h \
+ $(srcdir)/../include/xtensa-config.h
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $<
diff --git a/gcc/config/xtensa/xtensa-dynconfig.c b/gcc/config/xtensa/xtensa-dynconfig.c
new file mode 100644
index 0000000..056204a
--- /dev/null
+++ b/gcc/config/xtensa/xtensa-dynconfig.c
@@ -0,0 +1,170 @@
+/* Xtensa configuration settings loader.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 3, or (at your option) any later
+ version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <system.h>
+#include <coretypes.h>
+#include <diagnostic.h>
+#include <intl.h>
+#define XTENSA_CONFIG_DEFINITION
+#include "xtensa-config.h"
+#include "xtensa-dynconfig.h"
+
+#if defined (HAVE_DLFCN_H)
+#include <dlfcn.h>
+#elif defined (_WIN32)
+#include <windows.h>
+#define ENABLE_PLUGIN
+#endif
+
+#if !defined (HAVE_DLFCN_H) && defined (_WIN32)
+
+#define RTLD_LAZY 0 /* Dummy value. */
+
+static void *
+dlopen (const char *file, int mode ATTRIBUTE_UNUSED)
+{
+ return LoadLibrary (file);
+}
+
+static void *
+dlsym (void *handle, const char *name)
+{
+ return (void *) GetProcAddress ((HMODULE) handle, name);
+}
+
+static int ATTRIBUTE_UNUSED
+dlclose (void *handle)
+{
+ FreeLibrary ((HMODULE) handle);
+ return 0;
+}
+
+static const char *
+dlerror (void)
+{
+ return _("Unable to load DLL.");
+}
+
+#endif /* !defined (HAVE_DLFCN_H) && defined (_WIN32) */
+
+#define CONFIG_ENV_NAME "XTENSA_GNU_CONFIG"
+
+const void *xtensa_load_config (const char *name ATTRIBUTE_UNUSED,
+ const void *no_plugin_def,
+ const void *no_name_def ATTRIBUTE_UNUSED)
+{
+ static int init;
+#ifdef ENABLE_PLUGIN
+ static void *handle;
+ void *p;
+
+ if (!init)
+ {
+ const char *path = getenv (CONFIG_ENV_NAME);
+
+ init = 1;
+ if (!path)
+ return no_plugin_def;
+ handle = dlopen (path, RTLD_LAZY);
+ if (!handle)
+ {
+ fatal_error (input_location,
+ _("%qs is defined but could not be loaded: %s"),
+ CONFIG_ENV_NAME, dlerror ());
+ exit (FATAL_EXIT_CODE);
+ }
+ if (dlsym (handle, "plugin_is_GPL_compatible") == NULL)
+ {
+ fatal_error (input_location,
+ _("%qs plugin is not licensed under a GPL-compatible license"),
+ CONFIG_ENV_NAME);
+ exit (FATAL_EXIT_CODE);
+ }
+ }
+ else if (!handle)
+ {
+ return no_plugin_def;
+ }
+
+ p = dlsym (handle, name);
+ if (!p)
+ {
+ if (no_name_def)
+ return no_name_def;
+
+ fatal_error (input_location,
+ _("%qs is loaded but symbol %qs is not found: %s"),
+ CONFIG_ENV_NAME, name, dlerror ());
+ exit (FATAL_EXIT_CODE);
+ }
+ return p;
+#else
+ if (!init)
+ {
+ const char *path = getenv (CONFIG_ENV_NAME);
+
+ init = 1;
+ if (path)
+ {
+ fatal_error (input_location,
+ _("%qs is defined but plugin support is disabled"),
+ CONFIG_ENV_NAME);
+ exit (FATAL_EXIT_CODE);
+ }
+ }
+ return no_plugin_def;
+#endif
+}
+
+XTENSA_CONFIG_INSTANCE_LIST;
+
+#define _STRINGIFY(a) #a
+#define STRINGIFY(a) _STRINGIFY(a)
+
+#undef XTENSA_CONFIG_ENTRY
+#define XTENSA_CONFIG_ENTRY(a) "__" #a "=" STRINGIFY(a)
+
+static const char * const xtensa_config_strings[] = {
+ XTENSA_CONFIG_ENTRY_LIST,
+ NULL,
+};
+
+const struct xtensa_config_v1 *xtensa_get_config_v1 (void)
+{
+ static const struct xtensa_config_v1 *config;
+
+ if (!config)
+ config = (const struct xtensa_config_v1 *) xtensa_load_config ("xtensa_config_v1",
+ &xtensa_config_v1,
+ NULL);
+ return config;
+}
+
+const char * const *xtensa_get_config_strings (void)
+{
+ static const char * const *config_strings;
+
+ if (!config_strings)
+ config_strings = (const char * const *) xtensa_load_config ("xtensa_config_strings",
+ &xtensa_config_strings,
+ NULL);
+
+ return config_strings;
+}
diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h
index bc75ad9..91a215e 100644
--- a/gcc/config/xtensa/xtensa-protos.h
+++ b/gcc/config/xtensa/xtensa-protos.h
@@ -81,5 +81,6 @@ extern void xtensa_expand_epilogue (bool);
extern void order_regs_for_local_alloc (void);
extern enum reg_class xtensa_regno_to_class (int regno);
extern HOST_WIDE_INT xtensa_initial_elimination_offset (int from, int to);
+extern const char **xtensa_get_config_strings (void);
#endif /* !__XTENSA_PROTOS_H__ */
diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
index 2275fe6..7e19306 100644
--- a/gcc/config/xtensa/xtensa.h
+++ b/gcc/config/xtensa/xtensa.h
@@ -19,27 +19,12 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* Get Xtensa configuration settings */
-#include "xtensa-config.h"
+#include "xtensa-dynconfig.h"
/* External variables defined in xtensa.cc. */
/* Macros used in the machine description to select various Xtensa
configuration options. */
-#ifndef XCHAL_HAVE_MUL32_HIGH
-#define XCHAL_HAVE_MUL32_HIGH 0
-#endif
-#ifndef XCHAL_HAVE_RELEASE_SYNC
-#define XCHAL_HAVE_RELEASE_SYNC 0
-#endif
-#ifndef XCHAL_HAVE_S32C1I
-#define XCHAL_HAVE_S32C1I 0
-#endif
-#ifndef XCHAL_HAVE_THREADPTR
-#define XCHAL_HAVE_THREADPTR 0
-#endif
-#ifndef XCHAL_HAVE_FP_POSTINC
-#define XCHAL_HAVE_FP_POSTINC 0
-#endif
#define TARGET_BIG_ENDIAN XCHAL_HAVE_BE
#define TARGET_DENSITY XCHAL_HAVE_DENSITY
#define TARGET_MAC16 XCHAL_HAVE_MAC16
@@ -76,7 +61,7 @@ along with GCC; see the file COPYING3. If not see
#endif
/* Define this if the target has no hardware divide instructions. */
-#if !TARGET_DIV32
+#if !__XCHAL_HAVE_DIV32
#define TARGET_HAS_NO_HW_DIVIDE
#endif
@@ -84,6 +69,7 @@ along with GCC; see the file COPYING3. If not see
/* Target CPU builtins. */
#define TARGET_CPU_CPP_BUILTINS() \
do { \
+ const char **builtin; \
builtin_assert ("cpu=xtensa"); \
builtin_assert ("machine=xtensa"); \
builtin_define ("__xtensa__"); \
@@ -93,6 +79,8 @@ along with GCC; see the file COPYING3. If not see
builtin_define (TARGET_BIG_ENDIAN ? "__XTENSA_EB__" : "__XTENSA_EL__"); \
if (!TARGET_HARD_FLOAT) \
builtin_define ("__XTENSA_SOFT_FLOAT__"); \
+ for (builtin = xtensa_get_config_strings (); *builtin; ++builtin) \
+ builtin_define (*builtin); \
} while (0)
#define CPP_SPEC " %(subtarget_cpp_spec) "
diff --git a/gcc/configure b/gcc/configure
index 85181bc..5e10b50 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -1826,7 +1826,8 @@ Optional Packages:
--with-stack-clash-protection-guard-size=size
Set the default stack clash protection guard size
for specific targets as a power of two in bytes.
- --with-dwarf2 force the default debug format to be DWARF 2
+ --with-dwarf2 force the default debug format to be DWARF 2 (or
+ later)
--with-specs=SPECS add SPECS to driver command-line processing
--with-pkgversion=PKG Use PKG in the version string in place of "GCC"
--with-bugurl=URL Direct users to URL to report a bug
@@ -7846,7 +7847,8 @@ if test x${enable_multiarch} = xauto; then
fi
fi
if test x${enable_multiarch} = xyes; then
- $as_echo "#define ENABLE_MULTIARCH 1" >>confdefs.h
+
+$as_echo "#define ENABLE_MULTIARCH 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for multiarch configuration" >&5
@@ -8256,12 +8258,6 @@ if test x"$enable_as_accelerator_for" != x; then
$as_echo "#define ACCEL_COMPILER 1" >>confdefs.h
enable_as_accelerator=yes
- case "${target}" in
- *-intelmicemul-*)
- # In this case we expect offload compiler to be built as native, so we
- # need to rename the driver to avoid clashes with host's drivers.
- program_transform_name="s&^&${target}-&" ;;
- esac
sedscript="s#${target_noncanonical}#${enable_as_accelerator_for}-accel-${target_noncanonical}#"
program_transform_name=`echo $program_transform_name | sed $sedscript`
accel_dir_suffix=/accel/${target_noncanonical}
@@ -8276,10 +8272,6 @@ for tgt in `echo $enable_offload_targets | sed 's/,/ /g'`; do
enable_offloading=1
case "$tgt" in
- *-intelmic-* | *-intelmicemul-*)
- omp_device_property=omp-device-properties-i386
- omp_device_property_tmake_file="${omp_device_property_tmake_file} \$(srcdir)/config/i386/t-omp-device"
- ;;
amdgcn*)
omp_device_property=omp-device-properties-gcn
omp_device_property_tmake_file="${omp_device_property_tmake_file} \$(srcdir)/config/gcn/t-omp-device"
@@ -19734,7 +19726,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 19737 "configure"
+#line 19729 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -19840,7 +19832,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 19843 "configure"
+#line 19835 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -31117,15 +31109,25 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking sys/sdt.h in the target C library" >&5
$as_echo_n "checking sys/sdt.h in the target C library... " >&6; }
-have_sys_sdt_h=no
-if test -f $target_header_dir/sys/sdt.h; then
- have_sys_sdt_h=yes
+if ${gcc_cv_sys_sdt_h+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gcc_cv_sys_sdt_h=no
+ if test -f $target_header_dir/sys/sdt.h; then
+ gcc_cv_sys_sdt_h=yes
+ fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_sys_sdt_h" >&5
+$as_echo "$gcc_cv_sys_sdt_h" >&6; }
+if test x$gcc_cv_sys_sdt_h = xyes; then :
+
$as_echo "#define HAVE_SYS_SDT_H 1" >>confdefs.h
+
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_sys_sdt_h" >&5
-$as_echo "$have_sys_sdt_h" >&6; }
# Check if TFmode long double should be used by default or not.
# Some glibc targets used DFmode long double, but with glibc 2.4
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 53b1a27..42fc379 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -888,7 +888,7 @@ if test x${enable_multiarch} = xauto; then
fi
fi
if test x${enable_multiarch} = xyes; then
- AC_DEFINE(ENABLE_MULTIARCH, 1)
+ AC_DEFINE(ENABLE_MULTIARCH, 1, [If --with-multiarch option is used])
fi
AC_MSG_CHECKING(for multiarch configuration)
AC_SUBST(enable_multiarch)
@@ -1023,7 +1023,7 @@ fi,
objc_boehm_gc='')
AC_ARG_WITH(dwarf2,
-[AS_HELP_STRING([--with-dwarf2], [force the default debug format to be DWARF 2])],
+[AS_HELP_STRING([--with-dwarf2], [force the default debug format to be DWARF 2 (or later)])],
dwarf2="$with_dwarf2",
dwarf2=no)
@@ -1136,12 +1136,6 @@ if test x"$enable_as_accelerator_for" != x; then
AC_DEFINE(ACCEL_COMPILER, 1,
[Define if this compiler should be built as the offload target compiler.])
enable_as_accelerator=yes
- case "${target}" in
- *-intelmicemul-*)
- # In this case we expect offload compiler to be built as native, so we
- # need to rename the driver to avoid clashes with host's drivers.
- program_transform_name="s&^&${target}-&" ;;
- esac
sedscript="s#${target_noncanonical}#${enable_as_accelerator_for}-accel-${target_noncanonical}#"
program_transform_name=`echo $program_transform_name | sed $sedscript`
accel_dir_suffix=/accel/${target_noncanonical}
@@ -1156,10 +1150,6 @@ for tgt in `echo $enable_offload_targets | sed 's/,/ /g'`; do
enable_offloading=1
case "$tgt" in
- *-intelmic-* | *-intelmicemul-*)
- omp_device_property=omp-device-properties-i386
- omp_device_property_tmake_file="${omp_device_property_tmake_file} \$(srcdir)/config/i386/t-omp-device"
- ;;
amdgcn*)
omp_device_property=omp-device-properties-gcn
omp_device_property_tmake_file="${omp_device_property_tmake_file} \$(srcdir)/config/gcn/t-omp-device"
@@ -6789,14 +6779,16 @@ AC_SUBST([enable_default_ssp])
# Test for <sys/sdt.h> on the target.
GCC_TARGET_TEMPLATE([HAVE_SYS_SDT_H])
-AC_MSG_CHECKING(sys/sdt.h in the target C library)
-have_sys_sdt_h=no
-if test -f $target_header_dir/sys/sdt.h; then
- have_sys_sdt_h=yes
- AC_DEFINE(HAVE_SYS_SDT_H, 1,
+AC_CACHE_CHECK([sys/sdt.h in the target C library], [gcc_cv_sys_sdt_h], [
+ gcc_cv_sys_sdt_h=no
+ if test -f $target_header_dir/sys/sdt.h; then
+ gcc_cv_sys_sdt_h=yes
+ fi
+])
+AS_IF([test x$gcc_cv_sys_sdt_h = xyes], [
+ AC_DEFINE([HAVE_SYS_SDT_H], [1],
[Define if your target C library provides sys/sdt.h])
-fi
-AC_MSG_RESULT($have_sys_sdt_h)
+])
# Check if TFmode long double should be used by default or not.
# Some glibc targets used DFmode long double, but with glibc 2.4
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 82629ef..a4733be 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,650 @@
+2022-12-12 Jason Merrill <jason@redhat.com>
+
+ Revert:
+ 2022-12-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/105838
+ * call.cc (convert_like_internal) [ck_list]: Use
+ maybe_init_list_as_array.
+ * constexpr.cc (cxx_eval_vec_init_1): Init might have
+ a different type.
+ * tree.cc (build_vec_init_elt): Likewise.
+ * init.cc (build_vec_init): Handle from_array from a
+ TARGET_EXPR. Retain TARGET_EXPR of a different type.
+
+2022-12-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/105838
+ * call.cc (convert_like_internal) [ck_list]: Use
+ maybe_init_list_as_array.
+ * constexpr.cc (cxx_eval_vec_init_1): Init might have
+ a different type.
+ * tree.cc (build_vec_init_elt): Likewise.
+ * init.cc (build_vec_init): Handle from_array from a
+ TARGET_EXPR. Retain TARGET_EXPR of a different type.
+
+2022-12-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/105838
+ * call.cc (list_ctor_element_type): New.
+ (braced_init_element_type): New.
+ (has_non_trivial_temporaries): New.
+ (maybe_init_list_as_array): New.
+ (maybe_init_list_as_range): New.
+ (build_user_type_conversion_1): Use maybe_init_list_as_range.
+ * parser.cc (cp_parser_braced_list): Call
+ recompute_constructor_flags.
+ * cp-tree.h (find_temps_r): Declare.
+
+2022-12-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/105838
+ * cp-tree.h (is_std_allocator): Declare.
+ * constexpr.cc (is_std_allocator): Split out from...
+ (is_std_allocator_allocate): ...here.
+ * init.cc (find_temps_r): New.
+ (find_allocator_temp): New.
+ (build_vec_init): Use it.
+
+2022-12-08 Jason Merrill <jason@redhat.com>
+
+ * constexpr.cc (maybe_constant_value): Add default arg comments.
+
+2022-12-05 Scott Snyder <sss@li-snyder.org>
+
+ PR plugins/107964
+ * Make-lang.in (CP_PLUGIN_HEADERS): Install contracts.h
+
+2022-12-04 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/107417
+ * pt.cc (for_each_template_parm_r) <case REQUIRES_EXPR>: Move
+ walking of the TREE_TYPE of each parameter to ...
+ * tree.cc (cp_walk_subtrees) <case REQUIRES_EXPR>: ... here.
+
+2022-12-04 Iain Sandoe <iain@sandoe.co.uk>
+ Adrian Perl <adrian.perl@web.de>
+
+ PR c++/100611
+ PR c++/101367
+ PR c++/101976
+ PR c++/99576
+ * coroutines.cc (find_interesting_subtree): Do not promote temporaries
+ that are only used as direct initializers for some other object.
+
+2022-12-03 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/103081
+ * pt.cc (tsubst_copy) <case CONST_DECL>: Generalize
+ early exit test for namespace-scope decls to check dependence of
+ the enclosing scope instead. Remove dead early exit test.
+
+2022-12-02 Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
+ Jason Merrill <jason@redhat.com>
+
+ * decl.cc (grokdeclarator): Build RESULT_DECL.
+ (start_preparsed_function): Copy location from template.
+ * semantics.cc (apply_deduced_return_type): Handle
+ arg != current_function_decl.
+ * method.cc (implicitly_declare_fn): Use it.
+
+2022-12-02 Jason Merrill <jason@redhat.com>
+
+ * g++spec.cc (lang_specific_driver): Set SKIPOPT for nostdlib++.
+
+2022-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/84469
+ * parser.cc (cp_convert_omp_range_for): After do_auto_deduction if
+ !processing_template_decl call cp_finish_decomp with
+ processing_template_decl temporarily incremented.
+
+2022-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/84469
+ * parser.cc (do_range_for_auto_deduction): Add DECOMP_FIRST_NAME
+ and DECOMP_CNT arguments. Call cp_finish_decomp if DECL
+ is a structured binding.
+ (cp_parser_range_for): Adjust do_range_for_auto_deduction caller.
+ (cp_convert_omp_range_for): Likewise.
+
+2022-12-02 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/107539
+ * constraint.cc (norm_hasher::hash, norm_hasher::equal): Set
+ comparing_specializations.
+ (sat_hasher::hash, sat_hasher::equal): Likewise.
+ * cp-tree.h (atom_hasher::hash, atom_hasher::equal): Likewise.
+ * pt.cc (ctp_hasher::hash, ctp_hasher::equal): Likewise.
+
+2022-12-01 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Remove extra object dependency.
+
+2022-12-01 Jason Merrill <jason@redhat.com>
+
+ * contracts.cc (remove_contract_attributes): Actually prepend
+ to the list.
+ * pt.cc (tsubst_contract): Only look for a postcondition if type is
+ nonnull.
+
+2022-11-30 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/107542
+ * typeck.cc (cp_build_binary_op): In the SPACESHIP_EXPR case,
+ handle an error_mark_node result type.
+
+2022-11-29 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/107864
+ * decl.cc (function_requirements_equivalent_p): Don't check
+ DECL_TEMPLATE_SPECIALIZATION.
+ * pt.cc (determine_specialization): Propagate constraints when
+ specializing a function template too. Simplify by using
+ add_outermost_template_args.
+
+2022-11-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/101733
+ * parser.cc (cp_parser_requirement): Parse tentatively for the
+ 'typename' case.
+
+2022-11-28 Jason Merrill <jason@redhat.com>
+
+ * parser.cc (cp_parser_decl_specifier_seq): Change 'concept bool'
+ diagnostic from pedwarn to permerror.
+
+2022-11-28 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
+ Yvan ROUX <yvan.roux@foss.st.com>
+
+ * module.cc: On Windows, 'A:Foo' is supposed to be a module
+ and not a path.
+
+2022-11-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/107781
+ * contracts.cc (role_name_equal): Use strcspn instead
+ of strchrnul.
+
+2022-11-22 Jason Merrill <jason@redhat.com>
+
+ * contracts.cc (build_contract_condition_function):
+ Set DECL_ARTIFICIAL on return value parm.
+ * g++spec.cc (lang_specific_driver): Add -lstdc++exp
+ just before -lstdc++.
+
+2022-11-20 Patrick Palka <ppalka@redhat.com>
+
+ * constraint.cc (struct norm_entry): Define.
+ (struct norm_hasher): Define.
+ (norm_cache): Define.
+ (normalize_concept_check): Add function comment. Cache the
+ the normal form of the substituted concept-id. Canonicalize
+ generic arguments as NULL_TREE. Don't coerce arguments unless
+ they were substituted.
+ (normalize_concept_definition): Simplify. Use norm_cache
+ instead of normalized_map.
+
+2022-11-20 Patrick Palka <ppalka@redhat.com>
+
+ * pt.cc (coerce_template_parms): Salvage part of the function
+ comment from c_innermost_t_p. Handle parms being a full
+ template parameter list.
+ (coerce_innermost_template_parms): Remove.
+ (lookup_template_class): Use c_t_p instead of c_innermost_t_p.
+ (finish_template_variable): Likewise.
+ (tsubst_decl): Likewise.
+ (instantiate_alias_template): Likewise.
+
+2022-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ * constexpr.cc (cxx_eval_constant_expression): Implement C++23
+ P2647R1 - Permitting static constexpr variables in constexpr functions.
+ Allow DECL_EXPRs of decl_constant_var_p static or thread_local vars.
+ (potential_constant_expression_1): Similarly, except use
+ decl_maybe_constant_var_p instead of decl_constant_var_p if
+ processing_template_decl.
+
+2022-11-19 Jeff Chapman II <jchapman@lock3software.com>
+ Andrew Sutton <asutton@lock3software.com>
+ Andrew Marmaduke <amarmaduke@lock3software.com>
+ Michael Lopez <mlopez@lock3software.com>
+ Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (enum cp_tree_index): Add
+ CPTI_PSEUDO_CONTRACT_VIOLATION.
+ (pseudo_contract_violation_type): New macro.
+ (struct saved_scope): Add x_processing_contract_condition.
+ (processing_contract_condition): New macro.
+ (comparing_override_contracts): New variable decl.
+ (find_contract): New inline.
+ (set_decl_contracts): New inline.
+ (get_contract_semantic): New inline.
+ (set_contract_semantic): New inline.
+ * constexpr.cc (cxx_eval_assert): Split out from...
+ (cxx_eval_internal_function): ...here.
+ (cxx_eval_constant_expression): Use it for contracts.
+ (potential_constant_expression_1): Handle contracts.
+ * cp-gimplify.cc (cp_genericize_r): Handle contracts.
+ * cp-objcp-common.cc (cp_tree_size): Handle contracts.
+ (cp_common_init_ts): Handle contracts.
+ (cp_handle_option): Handle contracts.
+ * decl.cc (duplicate_decls): Handle contracts.
+ (check_tag_decl): Check for bogus contracts.
+ (start_decl): Check flag_contracts.
+ (grokfndecl): Call rebuild_postconditions.
+ (grokdeclarator): Handle contract attributes.
+ (start_preparsed_function): Call start_function_contracts.
+ (finish_function): Call finish_function_contracts.
+ * decl2.cc (cp_check_const_attributes): Skip contracts.
+ (comdat_linkage): Handle outlined contracts.
+ * error.cc (dump_type): Handle null TYPE_IDENTIFIER.
+ * g++spec.cc (EXPERIMENTAL): New macro.
+ (lang_specific_driver): Add -lstdc++exp if -fcontracts.
+ * mangle.cc (write_encoding): Handle outlined contracts.
+ * module.cc (trees_out::fn_parms_init): Handle outlined contracts.
+ (trees_in::fn_parms_init): Likewise.
+ (check_mergeable_decl): Likewise.
+ (module_state_config::get_dialect): Record -fcontracts.
+ * parser.h (struct cp_unparsed_functions_entry): Add contracts.
+ * parser.cc (unparsed_contracts): New macro.
+ (push_unparsed_function_queues): Adjust.
+ (contract_attribute_p): New.
+ (cp_parser_statement): Check contracts.
+ (cp_parser_decl_specifier_seq): Handle contracts.
+ (cp_parser_skip_to_closing_square_bracket): Split out...
+ (cp_parser_skip_up_to_closing_square_bracket): ...this fn.
+ (cp_parser_class_specifier): Do contract late parsing.
+ (cp_parser_class_head): Check contracts.
+ (cp_parser_contract_role): New.
+ (cp_parser_contract_mode_opt): New.
+ (find_error, contains_error_p): New.
+ (cp_parser_contract_attribute_spec): New.
+ (cp_parser_late_contract_condition): New.
+ (cp_parser_std_attribute_spec): Handle contracts.
+ (cp_parser_save_default_args): Also save contracts.
+ * pt.cc (register_parameter_specializations): No longer static.
+ (register_local_identity): New.
+ (check_explicit_specialization): Call remove_contract_attributes.
+ (tsubst_contract, tsubst_contract_attribute): New.
+ (tsubst_contract_attributes): New.
+ (tsubst_attribute): Add comment.
+ (tsubst_copy): Also allow parm when processing_contract_condition.
+ (tsubst_expr): Handle contracts.
+ (regenerate_decl_from_template): Handle contracts.
+ * search.cc (check_final_overrider): Compare contracts.
+ * semantics.cc (set_cleanup_locs): Skip POSTCONDITION_STMT.
+ (finish_non_static_data_member): Check contracts.
+ (finish_this_expr): Check contracts.
+ (process_outer_var_ref): Handle contracts.
+ (finish_id_expression_1): Handle contracts.
+ (apply_deduced_return_type): Adjust contracts.
+ * tree.cc (handle_contract_attribute): New.
+ (get_innermost_component, is_this_expression): New.
+ (comparing_this_references): New.
+ (equivalent_member_references): New.
+ (cp_tree_equal): Check it.
+ * typeck.cc (check_return_expr): Apply contracts.
+ * Make-lang.in: Add contracts.o.
+ * config-lang.in: Add contracts.cc.
+ * cp-tree.def (ASSERTION_STMT, PRECONDITION_STMT)
+ (POSTCONDITION_STMT): New.
+ * contracts.h: New file.
+ * contracts.cc: New file.
+
+2022-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.cc (grokdeclarator): Implement
+ CWG2635 - Constrained structured bindings. Emit a pedwarn on
+ constrained auto type. Add auto_diagnostic_group for error_at
+ and inform for non-auto type on structured bindings declaration.
+
+2022-11-18 Marek Polacek <polacek@redhat.com>
+
+ PR c++/104066
+ * decl.cc (grokdeclarator): Check funcdecl_p before complaining
+ about constinit.
+
+2022-11-16 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106649
+ * constexpr.cc (constexpr_error): New function.
+ (is_valid_constexpr_fn): Use constexpr_error.
+ (maybe_save_constexpr_fundef): Call
+ require_potential_rvalue_constant_expression_fncheck rather than
+ require_potential_rvalue_constant_expression. Register the
+ function if -Wno-invalid-constexpr was specified.
+ (explain_invalid_constexpr_fn): Don't return early if a function marked
+ 'constexpr' that isn't actually a constant expression was called.
+ (non_const_var_error): Add a bool parameter. Use constexpr_error.
+ (inline_asm_in_constexpr_error): Likewise.
+ (cxx_eval_constant_expression): Adjust calls to non_const_var_error
+ and inline_asm_in_constexpr_error.
+ (potential_constant_expression_1): Add a bool parameter. Use
+ constexpr_error.
+ (require_potential_rvalue_constant_expression_fncheck): New function.
+ * cp-tree.h (require_potential_rvalue_constant_expression_fncheck):
+ Declare.
+ * method.cc (struct comp_info): Call
+ require_potential_rvalue_constant_expression_fncheck rather than
+ require_potential_rvalue_constant_expression.
+
+2022-11-16 Jakub Jelinek <jakub@redhat.com>
+
+ * typeck.cc (next_common_initial_sequence): Return false members have
+ different DECL_ALIGN.
+ (layout_compatible_type_p): Don't test TYPE_ALIGN of ENUMERAL_TYPE
+ or CLASS_TYPE_P.
+
+2022-11-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/107624
+ * call.cc (keep_unused_object_arg): New function.
+ (build_op_call): Use it.
+ (build_op_subscript): Likewise.
+ (build_new_op): Similarly for ARRAY_REF.
+ (build_new_method_call): Use it.
+ * decl.cc (grok_op_properties): For C++20 and earlier, if operator[]
+ is static member function, require exactly one parameter rather than
+ exactly two parameters.
+
+2022-11-16 Jakub Jelinek <jakub@redhat.com>
+
+ * typeck.cc (cp_build_modify_expr): Implement CWG 2654
+ - Un-deprecation of compound volatile assignments. Remove
+ -Wvolatile warning about compound volatile assignments.
+
+2022-11-16 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.def (CONCEPT_DECL): Move to c-common.def.
+ * cp-objcp-common.cc (cp_common_init_ts): Don't handle CONCEPT_DECL
+ here.
+ * cp-tree.h (finish_concept_definition): Add ATTRS parameter.
+ * parser.cc (cp_parser_concept_definition): Parse attributes in
+ between identifier and =. Adjust finish_concept_definition
+ caller.
+ * pt.cc (finish_concept_definition): Add ATTRS parameter. Call
+ cplus_decl_attributes.
+ * constraint.cc (build_standard_check): If CONCEPT_DECL is
+ TREE_DEPRECATED, emit -Wdeprecated-declaration warnings.
+
+2022-11-15 Marek Polacek <polacek@redhat.com>
+
+ PR c++/107492
+ * decl.cc (grokdeclarator): Only emit a -Wignored-qualifiers warning
+ when funcdecl_p.
+
+2022-11-15 Patrick Palka <ppalka@redhat.com>
+
+ * constexpr.cc (potential_constant_expression_1)
+ <case *_CAST_EXPR>: Use
+ cast_valid_in_integral_constant_expression_p instead of
+ open coding it.
+ * constraint.cc (tsubst_valid_expression_requirement): Adjust
+ calls to tsubst_copy_and_build and tsubst_expr.
+ (tsubst_constraint): Likewise.
+ (satisfy_atom): Likewise.
+ (diagnose_trait_expr): Likewise.
+ * cp-tree.h (tsubst_copy_and_build): Remove i_c_e_p parameter.
+ (tsubst_expr): Likewise.
+ * init.cc (get_nsdmi): Adjust calls to tsubst_copy_and_build
+ and tsubst_expr.
+ * pt.cc (expand_integer_pack): Likewise.
+ (instantiate_non_dependent_expr_internal): Likewise.
+ (tsubst_friend_function): Likewise.
+ (tsubst_attribute): Likewise.
+ (instantiate_class_template): Likewise.
+ (tsubst_template_arg): Likewise.
+ (gen_elem_of_pack_expansion_instantiation): Likewise.
+ (tsubst_fold_expr_init): Likewise.
+ (tsubst_pack_expansion): Likewise.
+ (tsubst_default_argument): Likewise.
+ (tsubst_function_decl): Likewise.
+ (tsubst_decl): Likewise.
+ (tsubst_arg_types): Likewise.
+ (tsubst_exception_specification): Likewise.
+ (tsubst): Likewise.
+ (tsubst_init): Likewise.
+ (tsubst_copy): Likewise.
+ (tsubst_omp_clause_decl): Likewise.
+ (tsubst_omp_clauses): Likewise.
+ (tsubst_copy_asm_operands): Likewise.
+ (tsubst_omp_for_iterator): Likewise.
+ (tsubst_expr): Likewise. Remove i_c_e_p parameter.
+ (tsubst_omp_udr): Likewise.
+ (tsubst_non_call_postfix_expression): Likewise. Remove i_c_e_p parameter.
+ (tsubst_lambda_expr): Likewise.
+ (tsubst_copy_and_build_call_args): Likewise.
+ (tsubst_copy_and_build): Likewise. Remove i_c_e_p parameter.
+ <case IDENTIFIER_NODE>: Adjust call to finish_id_expression
+ following removal of i_c_e_p.
+ <case *_CAST_EXPR>: Remove C++98-specific cast validity check
+ guarded by i_c_e_p.
+ (maybe_instantiate_noexcept): Adjust calls to
+ tsubst_copy_and_build and tsubst_expr.
+ (instantiate_body): Likewise.
+ (instantiate_decl): Likewise.
+ (tsubst_initializer_list): Likewise.
+ (tsubst_enum): Likewise.
+
+2022-11-15 Patrick Palka <ppalka@redhat.com>
+
+ * cp-lang.cc (objcp_tsubst_copy_and_build): Remove
+ function_p parameter.
+ * cp-objcp-common.h (objcp_tsubst_copy_and_build):
+ Likewise.
+ * cp-tree.h (tsubst_copy_and_build): Likewise.
+ * init.cc (get_nsdmi): Adjust calls to tsubst_copy_and_build.
+ * pt.cc (expand_integer_pack): Likewise.
+ (instantiate_non_dependent_expr_internal): Likewise.
+ (tsubst_function_decl): Likewise.
+ (tsubst_arg_types): Likewise.
+ (tsubst_exception_specification): Likewise.
+ (tsubst): Likewise.
+ (tsubst_copy_asm_operands): Likewise.
+ (tsubst_expr): Likewise.
+ (tsubst_non_call_postfix_expression): Likewise.
+ (tsubst_lambda_expr): Likewise.
+ (tsubst_copy_and_build_call_args): Likewise.
+ (tsubst_copy_and_build): Remove function_p parameter
+ and adjust function comment. Adjust recursive calls.
+ <case CALL_EXPR>: Update outdated comment about when
+ we can see an IDENTIFIER_NODE callee with koenig_p=false.
+ (maybe_instantiate_noexcept): Adjust calls to
+ tsubst_copy_and_build.
+
+2022-11-15 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (next_common_initial_seqence): Rename to ...
+ (next_common_initial_sequence): ... this.
+ * typeck.cc (next_common_initial_seqence): Rename to ...
+ (next_common_initial_sequence): ... this.
+ (layout_compatible_type_p): Call next_common_initial_sequence
+ rather than next_common_initial_seqence.
+ * semantics.cc (is_corresponding_member_aggr): Likewise.
+
+2022-11-15 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.cc (grok_op_properties): Implement C++23 P2589R1
+ - static operator[]. Handle operator[] similarly to operator()
+ - allow static member functions, but pedwarn on it for C++20 and
+ older. Unlike operator(), perform rest of checks on it though for
+ C++20.
+ * call.cc (add_operator_candidates): For operator[] with class
+ typed first parameter, pass that parameter as first_arg and
+ an adjusted arglist without that parameter.
+
+2022-11-15 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/107638
+ * tree.cc (cxx_attribute_table): Don't conditionally exclude
+ the init_priority entry.
+ (handle_init_priority_attribute): Remove ATTRIBUTE_UNUSED.
+ Return error_mark_node if !SUPPORTS_INIT_PRIORITY.
+
+2022-11-15 Marek Polacek <polacek@redhat.com>
+
+ * call.cc (maybe_warn_dangling_reference): Don't warn when initializing
+ a non-const lvalue reference.
+
+2022-11-14 Jason Merrill <jason@redhat.com>
+
+ * pt.cc (tsubst_friend_function): Check satisfaction.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support Sphinx based documentation.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in:
+ Support installation if sphinx-build is missing.
+
+2022-11-10 Marek Polacek <polacek@redhat.com>
+
+ * call.cc (std_pair_ref_ref_p): New.
+ (do_warn_dangling_reference): Also warn when the function returns
+ std::pair<const T&, const T&>. Recurse into TARGET_EXPR_INITIAL.
+ (maybe_warn_dangling_reference): Don't return early if we're
+ initializing a std_pair_ref_ref_p.
+
+2022-11-09 Jakub Jelinek <jakub@redhat.com>
+
+ * tree.cc (handle_carries_dependency_attribute): New function.
+ (std_attribute_table): Add carries_dependency attribute.
+ * parser.cc (cp_parser_check_std_attribute): Add carries_dependency
+ attribute.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in:
+ Support installation if sphinx-build is missing.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support Sphinx based documentation.
+
+2022-11-09 Marek Polacek <polacek@redhat.com>
+
+ PR c++/107363
+ * semantics.cc (finish_call_expr): Suppress OPT_Wpessimizing_move.
+ * typeck.cc (maybe_warn_pessimizing_move): Check warn_redundant_move
+ and warning_suppressed_p. Adjust a message depending on return_p.
+ (check_return_expr): Don't suppress OPT_Wpessimizing_move here.
+
+2022-11-08 Jason Merrill <jason@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (fns_correspond): Declare.
+ * decl.cc (fns_correspond): New.
+ * call.cc (add_candidates): Look for op!= matching op==.
+ (joust): Complain about non-standard reversed tiebreaker.
+ (tourney): Fix champ_compared_to_predecessor logic.
+ (build_new_op): Don't complain about error_mark_node not having
+ 'bool' type.
+ * pt.cc (tsubst_copy_and_build): Don't try to be permissive
+ when seen_error().
+
+2022-11-06 Patrick Palka <ppalka@redhat.com>
+
+ * tree.cc (cxx_attribute_table): Include init_priority entry
+ only if SUPPORTS_INIT_PRIORITY.
+ (handle_init_priority_attribute): Add ATTRIBUTE_UNUSED. Assert
+ SUPPORTS_INIT_PRIORITY is true.
+
+2022-11-04 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
+ Yvan ROUX <yvan.roux@foss.st.com>
+
+ * mapper-client.cc: Use in-process client when networking is
+ disabled.
+
+2022-11-03 Marek Polacek <polacek@redhat.com>
+
+ PR c++/107488
+ * call.cc (do_warn_dangling_reference): Quash -Wdangling-reference
+ for member operator*.
+
+2022-11-03 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/107179
+ * constraint.cc (tsubst_requires_expr): Make sure we're not
+ deferring access checks.
+
+2022-11-03 Jason Merrill <jason@redhat.com>
+
+ * parser.cc (cp_parser_template_declaration_after_parameters): Fix
+ concept parsing below C++20.
+
+2022-11-03 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/93413
+ * decl2.cc (mark_used): Don't defer synthesis of virtual
+ functions.
+
+2022-11-01 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR): New.
+ (struct tree_lambda_expr): Add discriminator_sig bitfield.
+ (recrd_lambda_scope_sig_discriminator): Declare.
+ * lambda.cc (struct lambda_sig_count): New.
+ (lambda_discriminator): Add signature vector.
+ (start_lambda_scope): Adjust.
+ (compare_lambda_template_head, compare_lambda_sig): New.
+ (record_lambda_scope_sig_discriminator): New.
+ * mangle.cc (write_closure_type): Use the scope-sig discriminator for
+ ABI >= 18. Emit abi mangling warning if needed.
+ * module.cc (trees_out::core_vals): Stream the new discriminator.
+ (trees_in::core_vals): Likewise.
+ * parser.cc (cp_parser_lambda_declarator_opt): Call
+ record_lambda_scope_sig_discriminator.
+ * pt.cc (tsubst_lambda_expr): Likewise.
+
+2022-11-01 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (LAMBDA_EXPR_DISCRIMINATOR): Rename to ...
+ (LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR): ... here.
+ (struct tree_lambda_expr): Make default_capture_mode &
+ discriminator_scope bitfields.
+ (record_null_lambda_scope) Delete.
+ (record_lambda_scope_discriminator): Declare.
+ * lambda.cc (struct lambda_discriminator): New struct.
+ (lambda_scope, lambda_scope_stack): Adjust types.
+ (lambda_count): Delete.
+ (struct tree_int): Delete.
+ (start_lambda_scope, finish_lambda_scope): Adjust.
+ (record_lambda_scope): Only record the scope.
+ (record_lambda_scope_discriminator): New.
+ * mangle.cc (write_closure_type_name): Adjust.
+ * module.cc (trees_out::core_vals): Likewise,
+ (trees_in::core_vals): Likewise.
+ * parser.cc (cp_parser_lambda_expression): Call
+ record_lambda_scope_discriminator.
+ * pt.cc (tsubst_lambda_expr): Adjust record_lambda_scope caling. Call
+ record_lambda_scope_discriminator. Commonize control flow on tsubsting
+ the operator function.
+
+2022-11-01 Jason Merrill <jason@redhat.com>
+
+ * parser.cc (make_call_declarator): Add std_attrs parm.
+ (cp_parser_lambda_declarator_opt): Pass it.
+ (cp_parser_direct_declarator): Pass it.
+
+2022-11-01 Jason Merrill <jason@redhat.com>
+
+ * decl.cc (finish_function): Set TREE_NOTHROW later in the function.
+
+2022-11-01 Jason Merrill <jason@redhat.com>
+
+ * decl.cc (duplicate_decls): Reformat loop.
+ * parser.cc (cp_parser_member_declaration): Add newline.
+ * semantics.cc: Remove newline.
+
2022-10-28 Marek Polacek <polacek@redhat.com>
* call.cc (maybe_warn_dangling_reference): Enable the warning in
@@ -1807,7 +2454,7 @@
initializer calling function and add it to the list. Shrink
the c-lang region.
* module.cc (num_init_calls_needed): Delete.
- (module_has_import_init): Rename to ...
+ (module_has_import_init): Rename to ...
(module_determined_import_inits): ... here. Do the
calculation here ...
(finish_module_processing): ... rather than here.
@@ -2560,7 +3207,7 @@
2022-05-04 Jason Merrill <jason@redhat.com>
* decl.cc (reshape_init): Shortcut already-reshaped init.
- (reshape_init_class): Assert not getting one here.
+ (reshape_init_class): Assert not getting one here.
2022-05-04 Jason Merrill <jason@redhat.com>
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 291835d..b313196 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -39,7 +39,7 @@ CXX_INSTALL_NAME := $(shell echo c++|sed '$(program_transform_name)')
GXX_INSTALL_NAME := $(shell echo g++|sed '$(program_transform_name)')
CXX_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo c++|sed '$(program_transform_name)')
GXX_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo g++|sed '$(program_transform_name)')
-CP_PLUGIN_HEADERS := cp-tree.h cxx-pretty-print.h name-lookup.h type-utils.h operators.def cp-trait.def
+CP_PLUGIN_HEADERS := cp-tree.h cxx-pretty-print.h name-lookup.h type-utils.h operators.def cp-trait.def contracts.h
#
# Define the names for selecting c++ in LANGUAGES.
@@ -81,7 +81,7 @@ g++-cross$(exeext): xg++$(exeext)
# The compiler itself.
# Shared with C front end:
-CXX_C_OBJS = attribs.o incpath.o \
+CXX_C_OBJS = attribs.o \
$(C_COMMON_OBJS) $(CXX_TARGET_OBJS)
# Language-specific object files for C++ and Objective C++.
@@ -89,7 +89,7 @@ CXX_AND_OBJCXX_OBJS = \
cp/call.o cp/class.o cp/constexpr.o cp/constraint.o \
cp/coroutines.o cp/cp-gimplify.o \
cp/cp-objcp-common.o cp/cp-ubsan.o \
- cp/cvt.o cp/cxx-pretty-print.o \
+ cp/cvt.o cp/contracts.o cp/cxx-pretty-print.o \
cp/decl.o cp/decl2.o cp/dump.o \
cp/error.o cp/except.o cp/expr.o \
cp/friend.o cp/init.o \
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 2c0fa37..33b5e7f8 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -4154,6 +4154,134 @@ add_list_candidates (tree fns, tree first_arg,
access_path, flags, candidates, complain);
}
+/* Given C(std::initializer_list<A>), return A. */
+
+static tree
+list_ctor_element_type (tree fn)
+{
+ gcc_checking_assert (is_list_ctor (fn));
+
+ tree parm = FUNCTION_FIRST_USER_PARMTYPE (fn);
+ parm = non_reference (TREE_VALUE (parm));
+ return TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0);
+}
+
+/* If EXPR is a braced-init-list where the elements all decay to the same type,
+ return that type. */
+
+static tree
+braced_init_element_type (tree expr)
+{
+ if (TREE_CODE (expr) == CONSTRUCTOR
+ && TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE)
+ return TREE_TYPE (TREE_TYPE (expr));
+ if (!BRACE_ENCLOSED_INITIALIZER_P (expr))
+ return NULL_TREE;
+
+ tree elttype = NULL_TREE;
+ for (constructor_elt &e: CONSTRUCTOR_ELTS (expr))
+ {
+ tree type = TREE_TYPE (e.value);
+ type = type_decays_to (type);
+ if (!elttype)
+ elttype = type;
+ else if (!same_type_p (type, elttype))
+ return NULL_TREE;
+ }
+ return elttype;
+}
+
+/* True iff EXPR contains any temporaries with non-trivial destruction.
+
+ ??? Also ignore classes with non-trivial but no-op destruction other than
+ std::allocator? */
+
+static bool
+has_non_trivial_temporaries (tree expr)
+{
+ auto_vec<tree*> temps;
+ cp_walk_tree_without_duplicates (&expr, find_temps_r, &temps);
+ for (tree *p : temps)
+ {
+ tree t = TREE_TYPE (*p);
+ if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (t)
+ && !is_std_allocator (t))
+ return true;
+ }
+ return false;
+}
+
+/* We're initializing an array of ELTTYPE from INIT. If it seems useful,
+ return INIT as an array (of its own type) so the caller can initialize the
+ target array in a loop. */
+
+static tree
+maybe_init_list_as_array (tree elttype, tree init)
+{
+ /* Only do this if the array can go in rodata but not once converted. */
+ if (!CLASS_TYPE_P (elttype))
+ return NULL_TREE;
+ tree init_elttype = braced_init_element_type (init);
+ if (!init_elttype || !SCALAR_TYPE_P (init_elttype) || !TREE_CONSTANT (init))
+ return NULL_TREE;
+
+ tree first = CONSTRUCTOR_ELT (init, 0)->value;
+ if (TREE_CODE (init_elttype) == INTEGER_TYPE && null_ptr_cst_p (first))
+ /* Avoid confusion from treating 0 as a null pointer constant. */
+ first = build1 (UNARY_PLUS_EXPR, init_elttype, first);
+ first = (perform_implicit_conversion_flags
+ (elttype, first, tf_none, LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING));
+ if (first == error_mark_node)
+ /* Let the normal code give the error. */
+ return NULL_TREE;
+
+ /* Don't do this if the conversion would be constant. */
+ first = maybe_constant_init (first);
+ if (TREE_CONSTANT (first))
+ return NULL_TREE;
+
+ /* We can't do this if the conversion creates temporaries that need
+ to live until the whole array is initialized. */
+ if (has_non_trivial_temporaries (first))
+ return NULL_TREE;
+
+ init_elttype = cp_build_qualified_type (init_elttype, TYPE_QUAL_CONST);
+ tree arr = build_array_of_n_type (init_elttype, CONSTRUCTOR_NELTS (init));
+ return finish_compound_literal (arr, init, tf_none);
+}
+
+/* If we were going to call e.g. vector(initializer_list<string>) starting
+ with a list of string-literals (which is inefficient, see PR105838),
+ instead build an array of const char* and pass it to the range constructor.
+ But only do this for standard library types, where we can assume the
+ transformation makes sense.
+
+ Really the container classes should have initializer_list<U> constructors to
+ get the same effect more simply; this is working around that lack. */
+
+static tree
+maybe_init_list_as_range (tree fn, tree expr)
+{
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && is_list_ctor (fn)
+ && decl_in_std_namespace_p (fn))
+ {
+ tree to = list_ctor_element_type (fn);
+ if (tree init = maybe_init_list_as_array (to, expr))
+ {
+ tree begin = decay_conversion (TARGET_EXPR_SLOT (init), tf_none);
+ tree nelts = array_type_nelts_top (TREE_TYPE (init));
+ tree end = cp_build_binary_op (input_location, PLUS_EXPR, begin,
+ nelts, tf_none);
+ begin = cp_build_compound_expr (init, begin, tf_none);
+ return build_constructor_va (init_list_type_node, 2,
+ NULL_TREE, begin, NULL_TREE, end);
+ }
+ }
+
+ return NULL_TREE;
+}
+
/* Returns the best overload candidate to perform the requested
conversion. This function is used for three the overloading situations
described in [over.match.copy], [over.match.conv], and [over.match.ref].
@@ -4425,6 +4553,16 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
return cand;
}
+ /* Maybe pass { } as iterators instead of an initializer_list. */
+ if (tree iters = maybe_init_list_as_range (cand->fn, expr))
+ if (z_candidate *cand2
+ = build_user_type_conversion_1 (totype, iters, flags, tf_none))
+ if (cand2->viable == 1)
+ {
+ cand = cand2;
+ expr = iters;
+ }
+
tree convtype;
if (!DECL_CONSTRUCTOR_P (cand->fn))
convtype = non_reference (TREE_TYPE (TREE_TYPE (cand->fn)));
@@ -5017,6 +5155,33 @@ build_operator_new_call (tree fnname, vec<tree, va_gc> **args,
return ret;
}
+/* Evaluate side-effects from OBJ before evaluating call
+ to FN in RESULT expression.
+ This is for expressions of the form `obj->fn(...)'
+ where `fn' turns out to be a static member function and
+ `obj' needs to be evaluated. `fn' could be also static operator[]
+ or static operator(), in which cases the source expression
+ would be `obj[...]' or `obj(...)'. */
+
+static tree
+keep_unused_object_arg (tree result, tree obj, tree fn)
+{
+ if (result == NULL_TREE
+ || result == error_mark_node
+ || TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
+ || !TREE_SIDE_EFFECTS (obj))
+ return result;
+
+ /* But avoid the implicit lvalue-rvalue conversion when `obj' is
+ volatile. */
+ tree a = obj;
+ if (TREE_THIS_VOLATILE (a))
+ a = build_this (a);
+ if (TREE_SIDE_EFFECTS (a))
+ return build2 (COMPOUND_EXPR, TREE_TYPE (result), a, result);
+ return result;
+}
+
/* Build a new call to operator(). This may change ARGS. */
tree
@@ -5137,7 +5302,13 @@ build_op_call (tree obj, vec<tree, va_gc> **args, tsubst_flags_t complain)
else if (TREE_CODE (cand->fn) == FUNCTION_DECL
&& DECL_OVERLOADED_OPERATOR_P (cand->fn)
&& DECL_OVERLOADED_OPERATOR_IS (cand->fn, CALL_EXPR))
- result = build_over_call (cand, LOOKUP_NORMAL, complain);
+ {
+ result = build_over_call (cand, LOOKUP_NORMAL, complain);
+ /* In an expression of the form `a()' where cand->fn
+ which is operator() turns out to be a static member function,
+ `a' is none-the-less evaluated. */
+ result = keep_unused_object_arg (result, obj, cand->fn);
+ }
else
{
if (TREE_CODE (cand->fn) == FUNCTION_DECL)
@@ -6232,6 +6403,7 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
bool check_list_ctor = false;
bool check_converting = false;
unification_kind_t strict;
+ tree ne_fns = NULL_TREE;
if (!fns)
return;
@@ -6269,6 +6441,32 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE;
}
+ /* P2468: Check if operator== is a rewrite target with first operand
+ (*args)[0]; for now just do the lookups. */
+ if ((flags & (LOOKUP_REWRITTEN | LOOKUP_REVERSED))
+ && DECL_OVERLOADED_OPERATOR_IS (fn, EQ_EXPR))
+ {
+ tree ne_name = ovl_op_identifier (false, NE_EXPR);
+ if (DECL_CLASS_SCOPE_P (fn))
+ {
+ ne_fns = lookup_fnfields (TREE_TYPE ((*args)[0]), ne_name,
+ 1, tf_none);
+ if (ne_fns == error_mark_node || ne_fns == NULL_TREE)
+ ne_fns = NULL_TREE;
+ else
+ ne_fns = BASELINK_FUNCTIONS (ne_fns);
+ }
+ else
+ {
+ tree context = decl_namespace_context (fn);
+ ne_fns = lookup_qualified_name (context, ne_name, LOOK_want::NORMAL,
+ /*complain*/false);
+ if (ne_fns == error_mark_node
+ || !is_overloaded_fn (ne_fns))
+ ne_fns = NULL_TREE;
+ }
+ }
+
if (first_arg)
non_static_args = args;
else
@@ -6345,6 +6543,27 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
continue;
}
+ /* When considering reversed operator==, if there's a corresponding
+ operator!= in the same scope, it's not a rewrite target. */
+ if (ne_fns)
+ {
+ bool found = false;
+ for (lkp_iterator ne (ne_fns); !found && ne; ++ne)
+ if (0 && !ne.using_p ()
+ && DECL_NAMESPACE_SCOPE_P (fn)
+ && DECL_CONTEXT (*ne) != DECL_CONTEXT (fn))
+ /* ??? This kludge excludes inline namespace members for the H
+ test in spaceship-eq15.C, but I don't see why we would want
+ that behavior. Asked Core 2022-11-04. Disabling for now. */;
+ else if (fns_correspond (fn, *ne))
+ {
+ found = true;
+ break;
+ }
+ if (found)
+ continue;
+ }
+
if (TREE_CODE (fn) == TEMPLATE_DECL)
{
if (!add_template_candidate (candidates,
@@ -6541,12 +6760,36 @@ add_operator_candidates (z_candidate **candidates,
if (fns == error_mark_node)
return error_mark_node;
if (fns)
- add_candidates (BASELINK_FUNCTIONS (fns),
- NULL_TREE, arglist, NULL_TREE,
- NULL_TREE, false,
- BASELINK_BINFO (fns),
- BASELINK_ACCESS_BINFO (fns),
- flags, candidates, complain);
+ {
+ if (code == ARRAY_REF)
+ {
+ vec<tree,va_gc> *restlist = make_tree_vector ();
+ for (unsigned i = 1; i < nargs; ++i)
+ vec_safe_push (restlist, (*arglist)[i]);
+ z_candidate *save_cand = *candidates;
+ add_candidates (BASELINK_FUNCTIONS (fns),
+ (*arglist)[0], restlist, NULL_TREE,
+ NULL_TREE, false,
+ BASELINK_BINFO (fns),
+ BASELINK_ACCESS_BINFO (fns),
+ flags, candidates, complain);
+ /* Release the vec if we didn't add a candidate that uses it. */
+ for (z_candidate *c = *candidates; c != save_cand; c = c->next)
+ if (c->args == restlist)
+ {
+ restlist = NULL;
+ break;
+ }
+ release_tree_vector (restlist);
+ }
+ else
+ add_candidates (BASELINK_FUNCTIONS (fns),
+ NULL_TREE, arglist, NULL_TREE,
+ NULL_TREE, false,
+ BASELINK_BINFO (fns),
+ BASELINK_ACCESS_BINFO (fns),
+ flags, candidates, complain);
+ }
}
/* Per [over.match.oper]3.2, if no operand has a class type, then
only non-member functions that have type T1 or reference to
@@ -6917,10 +7160,12 @@ build_new_op (const op_location_t &loc, enum tree_code code, int flags,
gcc_checking_assert (cand->reversed ());
gcc_fallthrough ();
case NE_EXPR:
+ if (result == error_mark_node)
+ ;
/* If a rewritten operator== candidate is selected by
overload resolution for an operator @, its return type
shall be cv bool.... */
- if (TREE_CODE (TREE_TYPE (result)) != BOOLEAN_TYPE)
+ else if (TREE_CODE (TREE_TYPE (result)) != BOOLEAN_TYPE)
{
if (complain & tf_error)
{
@@ -6972,6 +7217,12 @@ build_new_op (const op_location_t &loc, enum tree_code code, int flags,
gcc_unreachable ();
}
}
+
+ /* In an expression of the form `a[]' where cand->fn
+ which is operator[] turns out to be a static member function,
+ `a' is none-the-less evaluated. */
+ if (code == ARRAY_REF)
+ result = keep_unused_object_arg (result, arg1, cand->fn);
}
else
{
@@ -7228,6 +7479,11 @@ build_op_subscript (const op_location_t &loc, tree obj,
/* Specify evaluation order as per P0145R2. */
CALL_EXPR_ORDERED_ARGS (call) = op_is_ordered (ARRAY_REF) == 1;
}
+
+ /* In an expression of the form `a[]' where cand->fn
+ which is operator[] turns out to be a static member function,
+ `a' is none-the-less evaluated. */
+ result = keep_unused_object_arg (result, obj, cand->fn);
}
else
gcc_unreachable ();
@@ -11420,21 +11676,11 @@ build_new_method_call (tree instance, tree fns, vec<tree, va_gc> **args,
/* In an expression of the form `a->f()' where `f' turns
out to be a static member function, `a' is
none-the-less evaluated. */
- if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
- && !is_dummy_object (instance)
- && TREE_SIDE_EFFECTS (instance))
- {
- /* But avoid the implicit lvalue-rvalue conversion when 'a'
- is volatile. */
- tree a = instance;
- if (TREE_THIS_VOLATILE (a))
- a = build_this (a);
- if (TREE_SIDE_EFFECTS (a))
- call = build2 (COMPOUND_EXPR, TREE_TYPE (call), a, call);
- }
- else if (call != error_mark_node
- && DECL_DESTRUCTOR_P (cand->fn)
- && !VOID_TYPE_P (TREE_TYPE (call)))
+ if (!is_dummy_object (instance))
+ call = keep_unused_object_arg (call, instance, fn);
+ if (call != error_mark_node
+ && DECL_DESTRUCTOR_P (cand->fn)
+ && !VOID_TYPE_P (TREE_TYPE (call)))
/* An explicit call of the form "x->~X()" has type
"void". However, on platforms where destructors
return "this" (i.e., those where
@@ -12488,10 +12734,53 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
if (winner && comp != winner)
{
/* Ambiguity between normal and reversed comparison operators
- with the same parameter types; prefer the normal one. */
- if ((cand1->reversed () != cand2->reversed ())
+ with the same parameter types. P2468 decided not to go with
+ this approach to resolving the ambiguity, so pedwarn. */
+ if ((complain & tf_warning_or_error)
+ && (cand1->reversed () != cand2->reversed ())
&& cand_parms_match (cand1, cand2))
- return cand1->reversed () ? -1 : 1;
+ {
+ struct z_candidate *w, *l;
+ if (cand2->reversed ())
+ winner = 1, w = cand1, l = cand2;
+ else
+ winner = -1, w = cand2, l = cand1;
+ if (warn)
+ {
+ auto_diagnostic_group d;
+ if (pedwarn (input_location, 0,
+ "C++20 says that these are ambiguous, "
+ "even though the second is reversed:"))
+ {
+ print_z_candidate (input_location,
+ N_("candidate 1:"), w);
+ print_z_candidate (input_location,
+ N_("candidate 2:"), l);
+ if (w->fn == l->fn
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (w->fn)
+ && (type_memfn_quals (TREE_TYPE (w->fn))
+ & TYPE_QUAL_CONST) == 0)
+ {
+ /* Suggest adding const to
+ struct A { bool operator==(const A&); }; */
+ tree parmtype
+ = FUNCTION_FIRST_USER_PARMTYPE (w->fn);
+ parmtype = TREE_VALUE (parmtype);
+ if (TYPE_REF_P (parmtype)
+ && TYPE_READONLY (TREE_TYPE (parmtype))
+ && (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (parmtype),
+ DECL_CONTEXT (w->fn))))
+ inform (DECL_SOURCE_LOCATION (w->fn),
+ "try making the operator a %<const%> "
+ "member function");
+ }
+ }
+ }
+ else
+ add_warning (w, l);
+ return winner;
+ }
winner = 0;
goto tweak;
@@ -12880,7 +13169,7 @@ tourney (struct z_candidate *candidates, tsubst_flags_t complain)
{
struct z_candidate *champ = candidates, *challenger;
int fate;
- int champ_compared_to_predecessor = 0;
+ struct z_candidate *champ_compared_to_predecessor = nullptr;
/* Walk through the list once, comparing each current champ to the next
candidate, knocking out a candidate or two with each comparison. */
@@ -12897,12 +13186,12 @@ tourney (struct z_candidate *candidates, tsubst_flags_t complain)
champ = challenger->next;
if (champ == 0)
return NULL;
- champ_compared_to_predecessor = 0;
+ champ_compared_to_predecessor = nullptr;
}
else
{
+ champ_compared_to_predecessor = champ;
champ = challenger;
- champ_compared_to_predecessor = 1;
}
challenger = champ->next;
@@ -12914,7 +13203,7 @@ tourney (struct z_candidate *candidates, tsubst_flags_t complain)
for (challenger = candidates;
challenger != champ
- && !(champ_compared_to_predecessor && challenger->next == champ);
+ && challenger != champ_compared_to_predecessor;
challenger = challenger->next)
{
fate = joust (champ, challenger, 0, complain);
@@ -13434,6 +13723,34 @@ initialize_reference (tree type, tree expr,
return expr;
}
+/* Return true if T is std::pair<const T&, const T&>. */
+
+static bool
+std_pair_ref_ref_p (tree t)
+{
+ /* First, check if we have std::pair. */
+ if (!NON_UNION_CLASS_TYPE_P (t)
+ || !CLASSTYPE_TEMPLATE_INSTANTIATION (t))
+ return false;
+ tree tdecl = TYPE_NAME (TYPE_MAIN_VARIANT (t));
+ if (!decl_in_std_namespace_p (tdecl))
+ return false;
+ tree name = DECL_NAME (tdecl);
+ if (!name || !id_equal (name, "pair"))
+ return false;
+
+ /* Now see if the template arguments are both const T&. */
+ tree args = CLASSTYPE_TI_ARGS (t);
+ if (TREE_VEC_LENGTH (args) != 2)
+ return false;
+ for (int i = 0; i < 2; i++)
+ if (!TYPE_REF_OBJ_P (TREE_VEC_ELT (args, i))
+ || !CP_TYPE_CONST_P (TREE_TYPE (TREE_VEC_ELT (args, i))))
+ return false;
+
+ return true;
+}
+
/* Helper for maybe_warn_dangling_reference to find a problematic CALL_EXPR
that initializes the LHS (and at least one of its arguments represents
a temporary, as outlined in maybe_warn_dangling_reference), or NULL_TREE
@@ -13463,11 +13780,6 @@ do_warn_dangling_reference (tree expr)
|| warning_suppressed_p (fndecl, OPT_Wdangling_reference)
|| !warning_enabled_at (DECL_SOURCE_LOCATION (fndecl),
OPT_Wdangling_reference)
- /* If the function doesn't return a reference, don't warn. This
- can be e.g.
- const int& z = std::min({1, 2, 3, 4, 5, 6, 7});
- which doesn't dangle: std::min here returns an int. */
- || !TYPE_REF_OBJ_P (TREE_TYPE (TREE_TYPE (fndecl)))
/* Don't emit a false positive for:
std::vector<int> v = ...;
std::vector<int>::const_iterator it = v.begin();
@@ -13480,6 +13792,20 @@ do_warn_dangling_reference (tree expr)
&& DECL_OVERLOADED_OPERATOR_IS (fndecl, INDIRECT_REF)))
return NULL_TREE;
+ tree rettype = TREE_TYPE (TREE_TYPE (fndecl));
+ /* If the function doesn't return a reference, don't warn. This
+ can be e.g.
+ const int& z = std::min({1, 2, 3, 4, 5, 6, 7});
+ which doesn't dangle: std::min here returns an int.
+
+ If the function returns a std::pair<const T&, const T&>, we
+ warn, to detect e.g.
+ std::pair<const int&, const int&> v = std::minmax(1, 2);
+ which also creates a dangling reference, because std::minmax
+ returns std::pair<const T&, const T&>(b, a). */
+ if (!(TYPE_REF_OBJ_P (rettype) || std_pair_ref_ref_p (rettype)))
+ return NULL_TREE;
+
/* Here we're looking to see if any of the arguments is a temporary
initializing a reference parameter. */
for (int i = 0; i < call_expr_nargs (expr); ++i)
@@ -13521,6 +13847,8 @@ do_warn_dangling_reference (tree expr)
return do_warn_dangling_reference (TREE_OPERAND (expr, 2));
case PAREN_EXPR:
return do_warn_dangling_reference (TREE_OPERAND (expr, 0));
+ case TARGET_EXPR:
+ return do_warn_dangling_reference (TARGET_EXPR_INITIAL (expr));
default:
return NULL_TREE;
}
@@ -13547,7 +13875,14 @@ maybe_warn_dangling_reference (const_tree decl, tree init)
{
if (!warn_dangling_reference)
return;
- if (!TYPE_REF_P (TREE_TYPE (decl)))
+ tree type = TREE_TYPE (decl);
+ /* Only warn if what we're initializing has type T&& or const T&, or
+ std::pair<const T&, const T&>. (A non-const lvalue reference can't
+ bind to a temporary.) */
+ if (!((TYPE_REF_OBJ_P (type)
+ && (TYPE_REF_IS_RVALUE (type)
+ || CP_TYPE_CONST_P (TREE_TYPE (type))))
+ || std_pair_ref_ref_p (type)))
return;
/* Don't suppress the diagnostic just because the call comes from
a system header. If the DECL is not in a system header, or if
diff --git a/gcc/cp/config-lang.in b/gcc/cp/config-lang.in
index 9ac3dee..f9e5f32 100644
--- a/gcc/cp/config-lang.in
+++ b/gcc/cp/config-lang.in
@@ -39,6 +39,7 @@ gtfiles="\
\$(srcdir)/c-family/c-common.cc \$(srcdir)/c-family/c-format.cc \
\$(srcdir)/c-family/c-cppbuiltin.cc \$(srcdir)/c-family/c-pragma.cc \
\$(srcdir)/cp/call.cc \$(srcdir)/cp/class.cc \$(srcdir)/cp/constexpr.cc \
+\$(srcdir)/cp/contracts.cc \
\$(srcdir)/cp/constraint.cc \$(srcdir)/cp/coroutines.cc \
\$(srcdir)/cp/cp-gimplify.cc \
\$(srcdir)/cp/cp-lang.cc \$(srcdir)/cp/cp-objcp-common.cc \
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 15b4f2c..e43d928 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h"
#include "attribs.h"
#include "fold-const.h"
+#include "intl.h"
static bool verify_constant (tree, bool, bool *, bool *);
#define VERIFY_CONSTANT(X) \
@@ -139,6 +140,42 @@ ensure_literal_type_for_constexpr_object (tree decl)
return decl;
}
+/* Issue a diagnostic with text GMSGID for constructs that are invalid in
+ constexpr functions. CONSTEXPR_FUNDEF_P is true if we're checking
+ a constexpr function body; if so, don't report hard errors and issue
+ a pedwarn pre-C++23, or a warning in C++23, if requested by
+ -Winvalid-constexpr. Otherwise, we're not in the context where we are
+ checking if a function can be marked 'constexpr', so give a hard error. */
+
+ATTRIBUTE_GCC_DIAG(3,4)
+static bool
+constexpr_error (location_t location, bool constexpr_fundef_p,
+ const char *gmsgid, ...)
+{
+ diagnostic_info diagnostic;
+ va_list ap;
+ rich_location richloc (line_table, location);
+ va_start (ap, gmsgid);
+ bool ret;
+ if (!constexpr_fundef_p)
+ {
+ /* Report an error that cannot be suppressed. */
+ diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ERROR);
+ ret = diagnostic_report_diagnostic (global_dc, &diagnostic);
+ }
+ else if (warn_invalid_constexpr)
+ {
+ diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
+ cxx_dialect < cxx23 ? DK_PEDWARN : DK_WARNING);
+ diagnostic.option_index = OPT_Winvalid_constexpr;
+ ret = diagnostic_report_diagnostic (global_dc, &diagnostic);
+ }
+ else
+ ret = false;
+ va_end (ap);
+ return ret;
+}
+
struct constexpr_fundef_hasher : ggc_ptr_hash<constexpr_fundef>
{
static hashval_t hash (const constexpr_fundef *);
@@ -208,9 +245,11 @@ is_valid_constexpr_fn (tree fun, bool complain)
if (complain)
{
auto_diagnostic_group d;
- error ("invalid type for parameter %d of %<constexpr%> "
- "function %q+#D", DECL_PARM_INDEX (parm), fun);
- explain_non_literal_class (TREE_TYPE (parm));
+ if (constexpr_error (input_location, /*constexpr_fundef_p*/true,
+ "invalid type for parameter %d of "
+ "%<constexpr%> function %q+#D",
+ DECL_PARM_INDEX (parm), fun))
+ explain_non_literal_class (TREE_TYPE (parm));
}
}
}
@@ -242,9 +281,10 @@ is_valid_constexpr_fn (tree fun, bool complain)
if (complain)
{
auto_diagnostic_group d;
- error ("invalid return type %qT of %<constexpr%> function %q+D",
- rettype, fun);
- explain_non_literal_class (rettype);
+ if (constexpr_error (input_location, /*constexpr_fundef_p*/true,
+ "invalid return type %qT of %<constexpr%> "
+ "function %q+D", rettype, fun))
+ explain_non_literal_class (rettype);
}
}
@@ -918,7 +958,7 @@ maybe_save_constexpr_fundef (tree fun)
bool potential = potential_rvalue_constant_expression (massaged);
if (!potential && complain)
- require_potential_rvalue_constant_expression (massaged);
+ require_potential_rvalue_constant_expression_fncheck (massaged);
if (DECL_CONSTRUCTOR_P (fun) && potential
&& !DECL_DEFAULTED_FN (fun))
@@ -933,11 +973,16 @@ maybe_save_constexpr_fundef (tree fun)
massaged = DECL_SAVED_TREE (fun);
potential = potential_rvalue_constant_expression (massaged);
if (!potential && complain)
- require_potential_rvalue_constant_expression (massaged);
+ require_potential_rvalue_constant_expression_fncheck (massaged);
}
}
- if (!potential && complain)
+ if (!potential && complain
+ /* If -Wno-invalid-constexpr was specified, we haven't complained
+ about non-constant expressions yet. Register the function and
+ complain in explain_invalid_constexpr_fn if the function is
+ called. */
+ && warn_invalid_constexpr != 0)
return;
if (implicit)
@@ -996,19 +1041,27 @@ register_constexpr_fundef (const constexpr_fundef &value)
**slot = value;
}
-/* FUN is a non-constexpr function called in a context that requires a
- constant expression. If it comes from a constexpr template, explain why
- the instantiation isn't constexpr. */
+/* FUN is a non-constexpr (or, with -Wno-invalid-constexpr, a constexpr
+ function called in a context that requires a constant expression).
+ If it comes from a constexpr template, explain why the instantiation
+ isn't constexpr. Otherwise, explain why the function cannot be used
+ in a constexpr context. */
void
explain_invalid_constexpr_fn (tree fun)
{
static hash_set<tree> *diagnosed;
tree body;
+ /* In C++23, a function marked 'constexpr' may not actually be a constant
+ expression. We haven't diagnosed the problem yet: -Winvalid-constexpr
+ wasn't enabled. The function was called, so diagnose why it cannot be
+ used in a constant expression. */
+ if (warn_invalid_constexpr == 0 && DECL_DECLARED_CONSTEXPR_P (fun))
+ /* Go on. */;
/* Only diagnose defaulted functions, lambdas, or instantiations. */
- if (!DECL_DEFAULTED_FN (fun)
- && !LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun))
- && !is_instantiation_of_constexpr (fun))
+ else if (!DECL_DEFAULTED_FN (fun)
+ && !LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun))
+ && !is_instantiation_of_constexpr (fun))
{
inform (DECL_SOURCE_LOCATION (fun), "%qD declared here", fun);
return;
@@ -1936,6 +1989,61 @@ diagnose_failing_condition (tree bad, location_t cloc, bool show_expr_p,
inform (cloc, "%qE evaluates to false", bad);
}
+/* Process an assert/assume of ORIG_ARG. If it's not supposed to be evaluated,
+ do it without changing the current evaluation state. If it evaluates to
+ false, complain and return false; otherwise, return true. */
+
+static bool
+cxx_eval_assert (const constexpr_ctx *ctx, tree arg, const char *msg,
+ location_t loc, bool evaluated,
+ bool *non_constant_p, bool *overflow_p)
+{
+ if (*non_constant_p)
+ return true;
+
+ tree eval;
+ if (!evaluated)
+ {
+ if (!potential_rvalue_constant_expression (arg))
+ return true;
+
+ constexpr_ctx new_ctx = *ctx;
+ new_ctx.quiet = true;
+ bool new_non_constant_p = false, new_overflow_p = false;
+ /* Avoid modification of existing values. */
+ modifiable_tracker ms (new_ctx.global);
+ eval = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue,
+ &new_non_constant_p,
+ &new_overflow_p);
+ }
+ else
+ eval = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
+ non_constant_p,
+ overflow_p);
+ if (!*non_constant_p && integer_zerop (eval))
+ {
+ if (!ctx->quiet)
+ {
+ /* See if we can find which clause was failing
+ (for logical AND). */
+ tree bad = find_failing_clause (ctx, arg);
+ /* If not, or its location is unusable, fall back to the
+ previous location. */
+ location_t cloc = cp_expr_loc_or_loc (bad, loc);
+
+ /* Report the error. */
+ auto_diagnostic_group d;
+ error_at (cloc, msg);
+ diagnose_failing_condition (bad, cloc, true, ctx);
+ return bad;
+ }
+ *non_constant_p = true;
+ return false;
+ }
+
+ return true;
+}
+
/* Evaluate a call T to a GCC internal function when possible and return
the evaluated result or, under the control of CTX, give an error, set
NON_CONSTANT_P, and return the unevaluated call T otherwise. */
@@ -1956,41 +2064,11 @@ cxx_eval_internal_function (const constexpr_ctx *ctx, tree t,
return void_node;
case IFN_ASSUME:
- if (potential_rvalue_constant_expression (CALL_EXPR_ARG (t, 0)))
- {
- constexpr_ctx new_ctx = *ctx;
- new_ctx.quiet = true;
- tree arg = CALL_EXPR_ARG (t, 0);
- bool new_non_constant_p = false, new_overflow_p = false;
- /* Avoid modification of existing values. */
- modifiable_tracker ms (new_ctx.global);
- arg = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue,
- &new_non_constant_p,
- &new_overflow_p);
- if (!new_non_constant_p && !new_overflow_p && integer_zerop (arg))
- {
- if (!*non_constant_p && !ctx->quiet)
- {
- /* See if we can find which clause was failing
- (for logical AND). */
- tree bad = find_failing_clause (&new_ctx,
- CALL_EXPR_ARG (t, 0));
- /* If not, or its location is unusable, fall back to the
- previous location. */
- location_t cloc = cp_expr_loc_or_loc (bad, EXPR_LOCATION (t));
-
- auto_diagnostic_group d;
-
- /* Report the error. */
- error_at (cloc,
- "failed %<assume%> attribute assumption");
- diagnose_failing_condition (bad, cloc, false, &new_ctx);
- }
-
- *non_constant_p = true;
- return t;
- }
- }
+ if (!cxx_eval_assert (ctx, CALL_EXPR_ARG (t, 0),
+ G_("failed %<assume%> attribute assumption"),
+ EXPR_LOCATION (t), /*eval*/false,
+ non_constant_p, overflow_p))
+ return t;
return void_node;
case IFN_ADD_OVERFLOW:
@@ -2136,28 +2214,35 @@ is_std_construct_at (const constexpr_call *call)
&& is_std_construct_at (call->fundef->decl));
}
-/* Return true if FNDECL is std::allocator<T>::{,de}allocate. */
+/* True if CTX is an instance of std::allocator. */
-static inline bool
-is_std_allocator_allocate (tree fndecl)
+bool
+is_std_allocator (tree ctx)
{
- tree name = DECL_NAME (fndecl);
- if (name == NULL_TREE
- || !(id_equal (name, "allocate") || id_equal (name, "deallocate")))
- return false;
-
- tree ctx = DECL_CONTEXT (fndecl);
if (ctx == NULL_TREE || !CLASS_TYPE_P (ctx) || !TYPE_MAIN_DECL (ctx))
return false;
tree decl = TYPE_MAIN_DECL (ctx);
- name = DECL_NAME (decl);
+ tree name = DECL_NAME (decl);
if (name == NULL_TREE || !id_equal (name, "allocator"))
return false;
return decl_in_std_namespace_p (decl);
}
+/* Return true if FNDECL is std::allocator<T>::{,de}allocate. */
+
+static inline bool
+is_std_allocator_allocate (tree fndecl)
+{
+ tree name = DECL_NAME (fndecl);
+ if (name == NULL_TREE
+ || !(id_equal (name, "allocate") || id_equal (name, "deallocate")))
+ return false;
+
+ return is_std_allocator (DECL_CONTEXT (fndecl));
+}
+
/* Overload for the above taking constexpr_call*. */
static inline bool
@@ -5612,11 +5697,12 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
}
/* Complain about R, a VAR_DECL, not being usable in a constant expression.
+ FUNDEF_P is true if we're checking a constexpr function body.
Shared between potential_constant_expression and
cxx_eval_constant_expression. */
static void
-non_const_var_error (location_t loc, tree r)
+non_const_var_error (location_t loc, tree r, bool fundef_p)
{
auto_diagnostic_group d;
tree type = TREE_TYPE (r);
@@ -5625,20 +5711,21 @@ non_const_var_error (location_t loc, tree r)
|| DECL_NAME (r) == heap_vec_uninit_identifier
|| DECL_NAME (r) == heap_vec_identifier)
{
- error_at (loc, "the content of uninitialized storage is not usable "
- "in a constant expression");
- inform (DECL_SOURCE_LOCATION (r), "allocated here");
+ if (constexpr_error (loc, fundef_p, "the content of uninitialized "
+ "storage is not usable in a constant expression"))
+ inform (DECL_SOURCE_LOCATION (r), "allocated here");
return;
}
if (DECL_NAME (r) == heap_deleted_identifier)
{
- error_at (loc, "use of allocated storage after deallocation in a "
- "constant expression");
- inform (DECL_SOURCE_LOCATION (r), "allocated here");
+ if (constexpr_error (loc, fundef_p, "use of allocated storage after "
+ "deallocation in a constant expression"))
+ inform (DECL_SOURCE_LOCATION (r), "allocated here");
return;
}
- error_at (loc, "the value of %qD is not usable in a constant "
- "expression", r);
+ if (!constexpr_error (loc, fundef_p, "the value of %qD is not usable in "
+ "a constant expression", r))
+ return;
/* Avoid error cascade. */
if (DECL_INITIAL (r) == error_mark_node)
return;
@@ -6697,15 +6784,17 @@ lookup_placeholder (const constexpr_ctx *ctx, value_cat lval, tree type)
return ob;
}
-/* Complain about an attempt to evaluate inline assembly. */
+/* Complain about an attempt to evaluate inline assembly. If FUNDEF_P is
+ true, we're checking a constexpr function body. */
static void
-inline_asm_in_constexpr_error (location_t loc)
+inline_asm_in_constexpr_error (location_t loc, bool fundef_p)
{
auto_diagnostic_group d;
- error_at (loc, "inline assembly is not a constant expression");
- inform (loc, "only unevaluated inline assembly is allowed in a "
- "%<constexpr%> function in C++20");
+ if (constexpr_error (loc, fundef_p, "inline assembly is not a "
+ "constant expression"))
+ inform (loc, "only unevaluated inline assembly is allowed in a "
+ "%<constexpr%> function in C++20");
}
/* We're getting the constant value of DECL in a manifestly constant-evaluated
@@ -6983,7 +7072,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
if (DECL_P (r))
{
if (!ctx->quiet)
- non_const_var_error (loc, r);
+ non_const_var_error (loc, r, /*fundef_p*/false);
*non_constant_p = true;
}
break;
@@ -7042,7 +7131,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
&& (TREE_STATIC (r)
|| (CP_DECL_THREAD_LOCAL_P (r) && !DECL_REALLY_EXTERN (r)))
/* Allow __FUNCTION__ etc. */
- && !DECL_ARTIFICIAL (r))
+ && !DECL_ARTIFICIAL (r)
+ && !decl_constant_var_p (r))
{
if (!ctx->quiet)
{
@@ -7845,6 +7935,24 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
r = void_node;
break;
+ case ASSERTION_STMT:
+ case PRECONDITION_STMT:
+ case POSTCONDITION_STMT:
+ {
+ contract_semantic semantic = get_contract_semantic (t);
+ if (semantic == CCS_IGNORE)
+ break;
+
+ if (!cxx_eval_assert (ctx, CONTRACT_CONDITION (t),
+ G_("contract predicate is false in "
+ "constant expression"),
+ EXPR_LOCATION (t), checked_contract_p (semantic),
+ non_constant_p, overflow_p))
+ *non_constant_p = true;
+ r = void_node;
+ }
+ break;
+
case TEMPLATE_ID_EXPR:
{
/* We can evaluate template-id that refers to a concept only if
@@ -7874,7 +7982,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case ASM_EXPR:
if (!ctx->quiet)
- inline_asm_in_constexpr_error (loc);
+ inline_asm_in_constexpr_error (loc, /*constexpr_fundef_p*/false);
*non_constant_p = true;
return t;
@@ -8373,7 +8481,8 @@ fold_simple (tree t)
static GTY((deletable)) hash_map<tree, tree> *cv_cache;
tree
-maybe_constant_value (tree t, tree decl, bool manifestly_const_eval)
+maybe_constant_value (tree t, tree decl /* = NULL_TREE */,
+ bool manifestly_const_eval /* = false */)
{
tree r;
@@ -8759,7 +8868,8 @@ check_for_return_continue (tree *tp, int *walk_subtrees, void *data)
diagnostic as appropriate under control of FLAGS. If WANT_RVAL is true,
an lvalue-rvalue conversion is implied. If NOW is true, we want to
consider the expression in the current context, independent of constexpr
- substitution.
+ substitution. If FUNDEF_P is true, we're checking a constexpr function body
+ and hard errors should not be reported by constexpr_error.
C++0x [expr.const] used to say
@@ -8776,10 +8886,12 @@ check_for_return_continue (tree *tp, int *walk_subtrees, void *data)
static bool
potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
- tsubst_flags_t flags, tree *jump_target)
+ bool fundef_p, tsubst_flags_t flags,
+ tree *jump_target)
{
#define RECUR(T,RV) \
- potential_constant_expression_1 ((T), (RV), strict, now, flags, jump_target)
+ potential_constant_expression_1 ((T), (RV), strict, now, fundef_p, flags, \
+ jump_target)
enum { any = false, rval = true };
int i;
@@ -8801,8 +8913,9 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
if (TREE_THIS_VOLATILE (t) && want_rval)
{
if (flags & tf_error)
- error_at (loc, "lvalue-to-rvalue conversion of a volatile lvalue "
- "%qE with type %qT", t, TREE_TYPE (t));
+ constexpr_error (loc, fundef_p, "lvalue-to-rvalue conversion of "
+ "a volatile lvalue %qE with type %qT", t,
+ TREE_TYPE (t));
return false;
}
if (CONSTANT_CLASS_P (t))
@@ -8861,7 +8974,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
/* An empty class has no data to read. */
return true;
if (flags & tf_error)
- error ("%qE is not a constant expression", t);
+ constexpr_error (input_location, fundef_p,
+ "%qE is not a constant expression", t);
return false;
}
return true;
@@ -8910,7 +9024,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
{
/* fold_call_expr can't do anything with IFN calls. */
if (flags & tf_error)
- error_at (loc, "call to internal function %qE", t);
+ constexpr_error (loc, fundef_p,
+ "call to internal function %qE", t);
return false;
}
}
@@ -8940,12 +9055,11 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
|| !is_std_construct_at (current_function_decl))
&& !cxx_dynamic_cast_fn_p (fun))
{
- if (flags & tf_error)
- {
- error_at (loc, "call to non-%<constexpr%> function %qD",
- fun);
- explain_invalid_constexpr_fn (fun);
- }
+ if ((flags & tf_error)
+ && constexpr_error (loc, fundef_p,
+ "call to non-%<constexpr%> "
+ "function %qD", fun))
+ explain_invalid_constexpr_fn (fun);
return false;
}
/* A call to a non-static member function takes the address
@@ -8962,8 +9076,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
constexpr substitution might not use the value. */
bool sub_now = false;
if (!potential_constant_expression_1 (x, rval, strict,
- sub_now, flags,
- jump_target))
+ sub_now, fundef_p,
+ flags, jump_target))
return false;
i = 1;
}
@@ -8997,7 +9111,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
substitution might not use the value of the argument. */
bool sub_now = false;
if (!potential_constant_expression_1 (x, rv, strict,
- sub_now, flags, jump_target))
+ sub_now, fundef_p, flags,
+ jump_target))
return false;
}
return true;
@@ -9035,9 +9150,10 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
if (flags & tf_error)
{
tree cap = DECL_CAPTURED_VARIABLE (t);
- error ("lambda capture of %qE is not a constant expression",
- cap);
- if (decl_constant_var_p (cap))
+ if (constexpr_error (input_location, fundef_p,
+ "lambda capture of %qE is not a "
+ "constant expression", cap)
+ && decl_constant_var_p (cap))
inform (input_location, "because it is used as a glvalue");
}
return false;
@@ -9060,8 +9176,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
&& COMPLETE_TYPE_P (TREE_TYPE (t))
&& !is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
{
- if (flags & tf_error)
- non_const_var_error (loc, t);
+ if (flags & tf_error)
+ non_const_var_error (loc, t, fundef_p);
return false;
}
return true;
@@ -9070,7 +9186,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
if (REINTERPRET_CAST_P (t))
{
if (flags & tf_error)
- error_at (loc, "%<reinterpret_cast%> is not a constant expression");
+ constexpr_error (loc, fundef_p, "%<reinterpret_cast%> is not a "
+ "constant expression");
return false;
}
/* FALLTHRU */
@@ -9092,8 +9209,9 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
&& !integer_zerop (from))
{
if (flags & tf_error)
- error_at (loc,
- "%<reinterpret_cast%> from integer to pointer");
+ constexpr_error (loc, fundef_p,
+ "%<reinterpret_cast%> from integer to "
+ "pointer");
return false;
}
}
@@ -9165,7 +9283,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
if (!var_in_maybe_constexpr_fn (x))
{
if (flags & tf_error)
- error_at (loc, "use of %<this%> in a constant expression");
+ constexpr_error (loc, fundef_p, "use of %<this%> in a "
+ "constant expression");
return false;
}
return true;
@@ -9313,8 +9432,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
/* In C++17 lambdas can be constexpr, don't give up yet. */
return true;
else if (flags & tf_error)
- error_at (loc, "lambda-expression is not a constant expression "
- "before C++17");
+ constexpr_error (loc, fundef_p, "lambda-expression is not a "
+ "constant expression before C++17");
return false;
case NEW_EXPR:
@@ -9325,8 +9444,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
/* In C++20, new-expressions are potentially constant. */
return true;
else if (flags & tf_error)
- error_at (loc, "new-expression is not a constant expression "
- "before C++20");
+ constexpr_error (loc, fundef_p, "new-expression is not a "
+ "constant expression before C++20");
return false;
case DYNAMIC_CAST_EXPR:
@@ -9375,12 +9494,13 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case AT_ENCODE_EXPR:
fail:
if (flags & tf_error)
- error_at (loc, "expression %qE is not a constant expression", t);
+ constexpr_error (loc, fundef_p, "expression %qE is not a constant "
+ "expression", t);
return false;
case ASM_EXPR:
if (flags & tf_error)
- inline_asm_in_constexpr_error (loc);
+ inline_asm_in_constexpr_error (loc, fundef_p);
return false;
case OBJ_TYPE_REF:
@@ -9388,8 +9508,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
/* In C++20 virtual calls can be constexpr, don't give up yet. */
return true;
else if (flags & tf_error)
- error_at (loc,
- "virtual functions cannot be %<constexpr%> before C++20");
+ constexpr_error (loc, fundef_p, "virtual functions cannot be "
+ "%<constexpr%> before C++20");
return false;
case TYPEID_EXPR:
@@ -9404,8 +9524,9 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
&& TYPE_POLYMORPHIC_P (TREE_TYPE (e)))
{
if (flags & tf_error)
- error_at (loc, "%<typeid%> is not a constant expression "
- "because %qE is of polymorphic type", e);
+ constexpr_error (loc, fundef_p, "%<typeid%> is not a "
+ "constant expression because %qE is "
+ "of polymorphic type", e);
return false;
}
return true;
@@ -9460,16 +9581,14 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case STATIC_CAST_EXPR:
case REINTERPRET_CAST_EXPR:
case IMPLICIT_CONV_EXPR:
- if (cxx_dialect < cxx11
- && !dependent_type_p (TREE_TYPE (t))
- && !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t)))
+ if (!cast_valid_in_integral_constant_expression_p (TREE_TYPE (t)))
/* In C++98, a conversion to non-integral type can't be part of a
constant expression. */
{
if (flags & tf_error)
- error_at (loc,
- "cast to non-integral type %qT in a constant expression",
- TREE_TYPE (t));
+ constexpr_error (loc, fundef_p,
+ "cast to non-integral type %qT in a constant "
+ "expression", TREE_TYPE (t));
return false;
}
/* This might be a conversion from a class to a (potentially) literal
@@ -9520,20 +9639,25 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case DECL_EXPR:
tmp = DECL_EXPR_DECL (t);
- if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp))
+ if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp)
+ && (processing_template_decl
+ ? !decl_maybe_constant_var_p (tmp)
+ : !decl_constant_var_p (tmp)))
{
if (CP_DECL_THREAD_LOCAL_P (tmp) && !DECL_REALLY_EXTERN (tmp))
{
if (flags & tf_error)
- error_at (DECL_SOURCE_LOCATION (tmp), "%qD defined "
- "%<thread_local%> in %<constexpr%> context", tmp);
+ constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p,
+ "%qD defined %<thread_local%> in "
+ "%<constexpr%> context", tmp);
return false;
}
else if (TREE_STATIC (tmp))
{
if (flags & tf_error)
- error_at (DECL_SOURCE_LOCATION (tmp), "%qD defined "
- "%<static%> in %<constexpr%> context", tmp);
+ constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p,
+ "%qD defined %<static%> in %<constexpr%> "
+ "context", tmp);
return false;
}
else if (!check_for_uninitialized_const_var
@@ -9556,9 +9680,10 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
if (flags & tf_error)
{
auto_diagnostic_group d;
- error_at (loc, "temporary of non-literal type %qT in a "
- "constant expression", TREE_TYPE (t));
- explain_non_literal_class (TREE_TYPE (t));
+ if (constexpr_error (loc, fundef_p,
+ "temporary of non-literal type %qT in a "
+ "constant expression", TREE_TYPE (t)))
+ explain_non_literal_class (TREE_TYPE (t));
}
return false;
}
@@ -9605,7 +9730,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
if (integer_zerop (denom))
{
if (flags & tf_error)
- error ("division by zero is not a constant expression");
+ constexpr_error (input_location, fundef_p,
+ "division by zero is not a constant expression");
return false;
}
else
@@ -9706,7 +9832,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
if (COND_EXPR_IS_VEC_DELETE (t) && cxx_dialect < cxx20)
{
if (flags & tf_error)
- error_at (loc, "%<delete[]%> is not a constant expression");
+ constexpr_error (loc, fundef_p, "%<delete[]%> is not a "
+ "constant expression");
return false;
}
/* Fall through. */
@@ -9736,7 +9863,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
{
tree this_jump_target = tmp;
if (potential_constant_expression_1 (TREE_OPERAND (t, i),
- want_rval, strict, now,
+ want_rval, strict, now, fundef_p,
tf_none, &this_jump_target))
{
if (returns (&this_jump_target))
@@ -9774,9 +9901,11 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
if (flags & tf_error)
{
if (TREE_CODE (t) == IF_STMT)
- error_at (loc, "neither branch of %<if%> is a constant expression");
+ constexpr_error (loc, fundef_p, "neither branch of %<if%> is a "
+ "constant expression");
else
- error_at (loc, "expression %qE is not a constant expression", t);
+ constexpr_error (loc, fundef_p, "expression %qE is not a "
+ "constant expression", t);
}
return false;
@@ -9785,8 +9914,9 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
return true;
if (flags & tf_error)
{
- error_at (loc, "non-constant array initialization");
- diagnose_non_constexpr_vec_init (t);
+ if (constexpr_error (loc, fundef_p, "non-constant array "
+ "initialization"))
+ diagnose_non_constexpr_vec_init (t);
}
return false;
@@ -9815,17 +9945,26 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
return true;
}
if (flags & tf_error)
- error_at (loc, "%<goto%> is not a constant expression");
+ constexpr_error (loc, fundef_p, "%<goto%> is not a constant "
+ "expression");
return false;
}
+ case ASSERTION_STMT:
+ case PRECONDITION_STMT:
+ case POSTCONDITION_STMT:
+ if (!checked_contract_p (get_contract_semantic (t)))
+ return true;
+ return RECUR (CONTRACT_CONDITION (t), rval);
+
case LABEL_EXPR:
t = LABEL_EXPR_LABEL (t);
if (DECL_ARTIFICIAL (t) || cxx_dialect >= cxx23)
return true;
else if (flags & tf_error)
- error_at (loc, "label definition in %<constexpr%> function only "
- "available with %<-std=c++2b%> or %<-std=gnu++2b%>");
+ constexpr_error (loc, fundef_p, "label definition in %<constexpr%> "
+ "function only available with %<-std=c++2b%> or "
+ "%<-std=gnu++2b%>");
return false;
case ANNOTATE_EXPR:
@@ -9863,7 +10002,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
bool
potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
- tsubst_flags_t flags)
+ bool fundef_p, tsubst_flags_t flags)
{
if (flags & tf_error)
{
@@ -9871,13 +10010,14 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
efficiently in some cases (currently only for TRUTH_*_EXPR). If
that fails, replay the check noisily to give errors. */
flags &= ~tf_error;
- if (potential_constant_expression_1 (t, want_rval, strict, now, flags))
+ if (potential_constant_expression_1 (t, want_rval, strict, now, fundef_p,
+ flags))
return true;
flags |= tf_error;
}
tree target = NULL_TREE;
- return potential_constant_expression_1 (t, want_rval, strict, now,
+ return potential_constant_expression_1 (t, want_rval, strict, now, fundef_p,
flags, &target);
}
@@ -9886,7 +10026,9 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
bool
potential_constant_expression (tree t)
{
- return potential_constant_expression_1 (t, false, true, false, tf_none);
+ return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
+ /*now*/false, /*fundef_p*/false,
+ tf_none);
}
/* As above, but require a constant rvalue. */
@@ -9894,7 +10036,9 @@ potential_constant_expression (tree t)
bool
potential_rvalue_constant_expression (tree t)
{
- return potential_constant_expression_1 (t, true, true, false, tf_none);
+ return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
+ /*now*/false, /*fundef_p*/false,
+ tf_none);
}
/* Like above, but complain about non-constant expressions. */
@@ -9902,7 +10046,8 @@ potential_rvalue_constant_expression (tree t)
bool
require_potential_constant_expression (tree t)
{
- return potential_constant_expression_1 (t, false, true, false,
+ return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
+ /*now*/false, /*fundef_p*/false,
tf_warning_or_error);
}
@@ -9911,7 +10056,18 @@ require_potential_constant_expression (tree t)
bool
require_potential_rvalue_constant_expression (tree t)
{
- return potential_constant_expression_1 (t, true, true, false,
+ return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
+ /*now*/false, /*fundef_p*/false,
+ tf_warning_or_error);
+}
+
+/* Like require_potential_rvalue_constant_expression, but fundef_p is true. */
+
+bool
+require_potential_rvalue_constant_expression_fncheck (tree t)
+{
+ return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
+ /*now*/false, /*fundef_p*/true,
tf_warning_or_error);
}
@@ -9920,7 +10076,8 @@ require_potential_rvalue_constant_expression (tree t)
bool
require_rvalue_constant_expression (tree t)
{
- return potential_constant_expression_1 (t, true, true, true,
+ return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
+ /*now*/true, /*fundef_p*/false,
tf_warning_or_error);
}
@@ -9934,7 +10091,9 @@ require_rvalue_constant_expression (tree t)
bool
is_constant_expression (tree t)
{
- return potential_constant_expression_1 (t, false, true, true, tf_none);
+ return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
+ /*now*/true, /*fundef_p*/false,
+ tf_none);
}
/* As above, but expect an rvalue. */
@@ -9942,7 +10101,9 @@ is_constant_expression (tree t)
bool
is_rvalue_constant_expression (tree t)
{
- return potential_constant_expression_1 (t, true, true, true, tf_none);
+ return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
+ /*now*/true, /*fundef_p*/false,
+ tf_none);
}
/* Like above, but complain about non-constant expressions. */
@@ -9950,7 +10111,8 @@ is_rvalue_constant_expression (tree t)
bool
require_constant_expression (tree t)
{
- return potential_constant_expression_1 (t, false, true, true,
+ return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
+ /*now*/true, /*fundef_p*/false,
tf_warning_or_error);
}
@@ -9960,7 +10122,9 @@ require_constant_expression (tree t)
bool
is_static_init_expression (tree t)
{
- return potential_constant_expression_1 (t, false, false, true, tf_none);
+ return potential_constant_expression_1 (t, /*want_rval*/false,
+ /*strict*/false, /*now*/true,
+ /*fundef_p*/false, tf_none);
}
/* Returns true if T is a potential constant expression that is not
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 5e6a3bc..37eae03 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -698,6 +698,45 @@ normalize_logical_operation (tree t, tree args, tree_code c, norm_info info)
return build2 (c, ci, t0, t1);
}
+/* Data types and hash functions for caching the normal form of a concept-id.
+ This essentially memoizes calls to normalize_concept_check. */
+
+struct GTY((for_user)) norm_entry
+{
+ /* The CONCEPT_DECL of the concept-id. */
+ tree tmpl;
+ /* The arguments of the concept-id. */
+ tree args;
+ /* The normal form of the concept-id. */
+ tree norm;
+};
+
+struct norm_hasher : ggc_ptr_hash<norm_entry>
+{
+ static hashval_t hash (norm_entry *e)
+ {
+ ++comparing_specializations;
+ hashval_t val = iterative_hash_template_arg (e->tmpl, 0);
+ val = iterative_hash_template_arg (e->args, val);
+ --comparing_specializations;
+ return val;
+ }
+
+ static bool equal (norm_entry *e1, norm_entry *e2)
+ {
+ ++comparing_specializations;
+ bool eq = e1->tmpl == e2->tmpl
+ && template_args_equal (e1->args, e2->args);
+ --comparing_specializations;
+ return eq;
+ }
+};
+
+static GTY((deletable)) hash_table<norm_hasher> *norm_cache;
+
+/* Normalize the concept check CHECK where ARGS are the
+ arguments to be substituted into CHECK's arguments. */
+
static tree
normalize_concept_check (tree check, tree args, norm_info info)
{
@@ -720,24 +759,52 @@ normalize_concept_check (tree check, tree args, norm_info info)
targs = tsubst_template_args (targs, args, info.complain, info.in_decl);
if (targs == error_mark_node)
return error_mark_node;
+ if (template_args_equal (targs, generic_targs_for (tmpl)))
+ /* Canonicalize generic arguments as NULL_TREE, as an optimization. */
+ targs = NULL_TREE;
/* Build the substitution for the concept definition. */
tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl));
- /* Turn on template processing; coercing non-type template arguments
- will automatically assume they're non-dependent. */
- ++processing_template_decl;
- tree subst = coerce_template_parms (parms, targs, tmpl, tf_none);
- --processing_template_decl;
- if (subst == error_mark_node)
+ if (targs && args)
+ /* As an optimization, coerce the arguments only if necessary
+ (i.e. if they were substituted). */
+ targs = coerce_template_parms (parms, targs, tmpl, tf_none);
+ if (targs == error_mark_node)
return error_mark_node;
+ if (!norm_cache)
+ norm_cache = hash_table<norm_hasher>::create_ggc (31);
+ norm_entry entry = {tmpl, targs, NULL_TREE};
+ norm_entry **slot = nullptr;
+ hashval_t hash = 0;
+ if (!info.generate_diagnostics ())
+ {
+ /* Cache the normal form of the substituted concept-id (when not
+ diagnosing). */
+ hash = norm_hasher::hash (&entry);
+ slot = norm_cache->find_slot_with_hash (&entry, hash, INSERT);
+ if (*slot)
+ return (*slot)->norm;
+ }
+
/* The concept may have been ill-formed. */
tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl));
if (def == error_mark_node)
return error_mark_node;
info.update_context (check, args);
- return normalize_expression (def, subst, info);
+ tree norm = normalize_expression (def, targs, info);
+ if (slot)
+ {
+ /* Recompute SLOT since norm_cache may have been expanded during
+ the recursive call. */
+ slot = norm_cache->find_slot_with_hash (&entry, hash, INSERT);
+ gcc_checking_assert (!*slot);
+ entry.norm = norm;
+ *slot = ggc_alloc<norm_entry> ();
+ **slot = entry;
+ }
+ return norm;
}
/* Used by normalize_atom to cache ATOMIC_CONSTRs. */
@@ -941,15 +1008,16 @@ get_normalized_constraints_from_decl (tree d, bool diag = false)
/* Returns the normal form of TMPL's definition. */
static tree
-normalize_concept_definition (tree tmpl, bool diag = false)
+normalize_concept_definition (tree tmpl, bool diag)
{
+ if (!norm_cache)
+ norm_cache = hash_table<norm_hasher>::create_ggc (31);
+ norm_entry entry = {tmpl, NULL_TREE, NULL_TREE};
+
if (!diag)
- if (tree *p = hash_map_safe_get (normalized_map, tmpl))
- return *p;
+ if (norm_entry *found = norm_cache->find (&entry))
+ return found->norm;
- gcc_assert (concept_definition_p (tmpl));
- if (OVL_P (tmpl))
- tmpl = OVL_FIRST (tmpl);
gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl));
++processing_template_decl;
@@ -958,7 +1026,12 @@ normalize_concept_definition (tree tmpl, bool diag = false)
--processing_template_decl;
if (!diag)
- hash_map_safe_put<hm_ggc> (normalized_map, tmpl, norm);
+ {
+ norm_entry **slot = norm_cache->find_slot (&entry, INSERT);
+ entry.norm = norm;
+ *slot = ggc_alloc<norm_entry> ();
+ **slot = entry;
+ }
return norm;
}
@@ -1396,6 +1469,8 @@ build_standard_check (tree tmpl, tree args, tsubst_flags_t complain)
{
gcc_assert (standard_concept_p (tmpl));
gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
+ if (TREE_DEPRECATED (DECL_TEMPLATE_RESULT (tmpl)))
+ warn_deprecated_use (DECL_TEMPLATE_RESULT (tmpl), NULL_TREE);
tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
args = coerce_template_parms (parms, args, tmpl, complain);
if (args == error_mark_node)
@@ -1921,7 +1996,7 @@ hash_placeholder_constraint (tree c)
static tree
tsubst_valid_expression_requirement (tree t, tree args, sat_info info)
{
- tree r = tsubst_expr (t, args, tf_none, info.in_decl, false);
+ tree r = tsubst_expr (t, args, tf_none, info.in_decl);
if (convert_to_void (r, ICV_STATEMENT, tf_none) != error_mark_node)
return r;
@@ -1932,7 +2007,7 @@ tsubst_valid_expression_requirement (tree t, tree args, sat_info info)
{
inform (loc, "the required expression %qE is invalid, because", t);
if (r == error_mark_node)
- tsubst_expr (t, args, info.complain, info.in_decl, false);
+ tsubst_expr (t, args, info.complain, info.in_decl);
else
convert_to_void (r, ICV_STATEMENT, info.complain);
}
@@ -1941,7 +2016,7 @@ tsubst_valid_expression_requirement (tree t, tree args, sat_info info)
}
else if (info.noisy ())
{
- r = tsubst_expr (t, args, info.complain, info.in_decl, false);
+ r = tsubst_expr (t, args, info.complain, info.in_decl);
convert_to_void (r, ICV_STATEMENT, info.complain);
}
@@ -2252,6 +2327,9 @@ tsubst_requires_expr (tree t, tree args, sat_info info)
{
local_specialization_stack stack (lss_copy);
+ /* We need to check access during the substitution. */
+ deferring_access_check_sentinel acs (dk_no_deferred);
+
/* A requires-expression is an unevaluated context. */
cp_unevaluated u;
@@ -2458,6 +2536,9 @@ struct sat_hasher : ggc_ptr_hash<sat_entry>
{
static hashval_t hash (sat_entry *e)
{
+ auto cso = make_temp_override (comparing_specializations);
+ ++comparing_specializations;
+
if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e->atom))
{
/* Atoms with instantiated mappings are built during satisfaction.
@@ -2492,6 +2573,9 @@ struct sat_hasher : ggc_ptr_hash<sat_entry>
static bool equal (sat_entry *e1, sat_entry *e2)
{
+ auto cso = make_temp_override (comparing_specializations);
+ ++comparing_specializations;
+
if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e1->atom)
!= ATOMIC_CONSTR_MAP_INSTANTIATED_P (e2->atom))
return false;
@@ -2703,7 +2787,7 @@ tsubst_constraint (tree t, tree args, tsubst_flags_t complain, tree in_decl)
constraint-expressions of a declaration. */
processing_constraint_expression_sentinel s;
cp_unevaluated u;
- tree expr = tsubst_expr (t, args, complain, in_decl, false);
+ tree expr = tsubst_expr (t, args, complain, in_decl);
return expr;
}
@@ -2951,13 +3035,13 @@ satisfy_atom (tree t, tree args, sat_info info)
/* Apply the parameter mapping (i.e., just substitute). */
tree expr = ATOMIC_CONSTR_EXPR (t);
- tree result = tsubst_expr (expr, args, quiet.complain, quiet.in_decl, false);
+ tree result = tsubst_expr (expr, args, quiet.complain, quiet.in_decl);
if (result == error_mark_node)
{
/* If substitution results in an invalid type or expression, the constraint
is not satisfied. Replay the substitution. */
if (info.diagnose_unsatisfaction_p ())
- tsubst_expr (expr, args, info.complain, info.in_decl, false);
+ tsubst_expr (expr, args, info.complain, info.in_decl);
return cache.save (inst_cache.save (boolean_false_node));
}
@@ -3584,7 +3668,7 @@ diagnose_trait_expr (tree expr, tree args)
/* Build a "fake" version of the instantiated trait, so we can
get the instantiated types from result. */
++processing_template_decl;
- expr = tsubst_expr (expr, args, tf_none, NULL_TREE, false);
+ expr = tsubst_expr (expr, args, tf_none, NULL_TREE);
--processing_template_decl;
tree t1 = TRAIT_EXPR_TYPE1 (expr);
diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc
new file mode 100644
index 0000000..45f52b2
--- /dev/null
+++ b/gcc/cp/contracts.cc
@@ -0,0 +1,2241 @@
+/* Definitions for C++ contract levels
+ Copyright (C) 2020-2022 Free Software Foundation, Inc.
+ Contributed by Jeff Chapman II (jchapman@lock3software.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* Design Notes
+
+ A function is called a "guarded" function if it has pre or post contract
+ attributes. A contract is considered an "active" contract if runtime code is
+ needed for the contract under the current contract configuration.
+
+ pre and post contract attributes are parsed and stored in DECL_ATTRIBUTES.
+ assert contracts are parsed and wrapped in statements. When genericizing, all
+ active and assumed contracts are transformed into an if block. An observed
+ contract:
+
+ [[ pre: v > 0 ]]
+
+ is transformed into:
+
+ if (!(v > 0)) {
+ handle_contract_violation(__pseudo_contract_violation{
+ 5, // line_number,
+ "main.cpp", // file_name,
+ "fun", // function_name,
+ "v > 0", // comment,
+ "default", // assertion_level,
+ "default", // assertion_role,
+ MAYBE_CONTINUE, // continuation_mode
+ });
+ terminate (); // if NEVER_CONTINUE
+ }
+
+ We use an internal type with the same layout as contract_violation rather
+ than try to define the latter internally and somehow deal with its actual
+ definition in a TU that includes <contract>.
+
+ ??? is it worth factoring out the calls to handle_contract_violation and
+ terminate into a local function?
+
+ Assumed contracts use the same implementation as C++23 [[assume]].
+
+ Parsing of pre and post contract conditions need to be deferred when the
+ contracts are attached to a member function. The postcondition identifier
+ cannot be used before the deduced return type of an auto function is used,
+ except when used in a defining declaration in which case they conditions are
+ fully parsed once the body is finished (see cpp2a/contracts-deduced{1,2}.C).
+
+ A list of pre and post contracts can either be repeated in their entirety or
+ completely absent in subsequent declarations. If contract lists appear on two
+ matching declarations, their contracts have to be equivalent. In general this
+ means that anything before the colon have to be token equivalent and the
+ condition must be cp_tree_equal (primarily to allow for parameter renaming).
+
+ Contracts on overrides must match those present on (all of) the overridee(s).
+
+ Template specializations may have their own contracts. If no contracts are
+ specified on the initial specialization they're assumed to be the same as
+ the primary template. Specialization redeclarations must then match either
+ the primary template (if they were unspecified originally), or those
+ specified on the specialization.
+
+
+ For non-cdtors two functions are generated for ease of implementation and to
+ avoid some cases where code bloat may occurr. These are the DECL_PRE_FN and
+ DECL_POST_FN. Each handles checking either the set of pre or post contracts
+ of a guarded function.
+
+ int fun(int v)
+ [[ pre: v > 0 ]]
+ [[ post r: r < 0 ]]
+ {
+ return -v;
+ }
+
+ The original decl is left alone and instead calls are generated to pre/post
+ functions within the body:
+
+ void fun.pre(int v)
+ {
+ [[ assert: v > 0 ]];
+ }
+ int fun.post(int v, int __r)
+ {
+ [[ assert: __r < 0 ]];
+ return __r;
+ }
+ int fun(int v)
+ {
+ fun.pre(v);
+ return fun.post(v, -v);
+ }
+
+ If fun returns in memory, the return value is not passed through the post
+ function; instead, the return object is initialized directly and then passed
+ to the post function by invisible reference.
+
+ This sides steps a number of issues with having to rewrite the bodies or
+ rewrite the parsed conditions as the parameters to the original function
+ changes (as happens during redeclaration). The ultimate goal is to get
+ something that optimizes well along the lines of
+
+ int fun(int v)
+ {
+ [[ assert: v > 0 ]];
+ auto &&__r = -v;
+ goto out;
+ out:
+ [[ assert: __r < 0 ]];
+ return __r;
+ }
+
+ With the idea being that multiple return statements could collapse the
+ function epilogue after inlining the pre/post functions. clang is able
+ to collapse common function epilogues, while gcc needs -O3 -Os combined.
+
+ Directly laying the pre contracts down in the function body doesn't have
+ many issues. The post contracts may need to be repeated multiple times, once
+ for each return, or a goto epilogue would need to be generated.
+ For this initial implementation, generating function calls and letting
+ later optimizations decide whether to inline and duplicate the actual
+ checks or whether to collapse the shared epilogue was chosen.
+
+ For cdtors a post contract is implemented using a CLEANUP_STMT.
+
+ FIXME the compiler already shores cleanup code on multiple exit paths, so
+ this outlining seems unnecessary if we represent the postcondition as a
+ cleanup for all functions.
+
+ More helpful for optimization might be to make the contracts a wrapper
+ function (for non-variadic functions), that could be inlined into a
+ caller while preserving the call to the actual function? Either that or
+ mirror a never-continue post contract with an assume in the caller. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "cp-tree.h"
+#include "stringpool.h"
+#include "diagnostic.h"
+#include "options.h"
+#include "contracts.h"
+#include "tree.h"
+#include "tree-inline.h"
+#include "attribs.h"
+#include "tree-iterator.h"
+#include "print-tree.h"
+#include "stor-layout.h"
+
+const int max_custom_roles = 32;
+static contract_role contract_build_roles[max_custom_roles] = {
+};
+
+bool valid_configs[CCS_MAYBE + 1][CCS_MAYBE + 1] = {
+ { 0, 0, 0, 0, 0, },
+ { 0, 1, 0, 0, 0, },
+ { 0, 1, 1, 1, 1, },
+ { 0, 1, 1, 1, 1, },
+ { 0, 1, 0, 0, 1, },
+};
+
+void
+validate_contract_role (contract_role *role)
+{
+ gcc_assert (role);
+ if (!unchecked_contract_p (role->axiom_semantic))
+ error ("axiom contract semantic must be %<assume%> or %<ignore%>");
+
+ if (!valid_configs[role->default_semantic][role->audit_semantic] )
+ warning (0, "the %<audit%> semantic should be at least as strong as "
+ "the %<default%> semantic");
+}
+
+contract_semantic
+lookup_concrete_semantic (const char *name)
+{
+ if (strcmp (name, "ignore") == 0)
+ return CCS_IGNORE;
+ if (strcmp (name, "assume") == 0)
+ return CCS_ASSUME;
+ if (strcmp (name, "check_never_continue") == 0
+ || strcmp (name, "never") == 0
+ || strcmp (name, "abort") == 0)
+ return CCS_NEVER;
+ if (strcmp (name, "check_maybe_continue") == 0
+ || strcmp (name, "maybe") == 0)
+ return CCS_MAYBE;
+ error ("'%s' is not a valid explicit concrete semantic", name);
+ return CCS_INVALID;
+}
+
+/* Compare role and name up to either the NUL terminator or the first
+ occurrence of colon. */
+
+static bool
+role_name_equal (const char *role, const char *name)
+{
+ size_t role_len = strcspn (role, ":");
+ size_t name_len = strcspn (name, ":");
+ if (role_len != name_len)
+ return false;
+ return strncmp (role, name, role_len) == 0;
+}
+
+static bool
+role_name_equal (contract_role *role, const char *name)
+{
+ if (role->name == NULL)
+ return false;
+ return role_name_equal (role->name, name);
+}
+
+contract_role *
+get_contract_role (const char *name)
+{
+ for (int i = 0; i < max_custom_roles; ++i)
+ {
+ contract_role *potential = contract_build_roles + i;
+ if (role_name_equal (potential, name))
+ return potential;
+ }
+ if (role_name_equal (name, "default") || role_name_equal (name, "review"))
+ {
+ setup_default_contract_role (false);
+ return get_contract_role (name);
+ }
+ return NULL;
+}
+
+contract_role *
+add_contract_role (const char *name,
+ contract_semantic des,
+ contract_semantic aus,
+ contract_semantic axs,
+ bool update)
+{
+ for (int i = 0; i < max_custom_roles; ++i)
+ {
+ contract_role *potential = contract_build_roles + i;
+ if (potential->name != NULL
+ && !role_name_equal (potential, name))
+ continue;
+ if (potential->name != NULL && !update)
+ return potential;
+ potential->name = name;
+ potential->default_semantic = des;
+ potential->audit_semantic = aus;
+ potential->axiom_semantic = axs;
+ return potential;
+ }
+ return NULL;
+}
+
+enum contract_build_level { OFF, DEFAULT, AUDIT };
+static bool flag_contract_continuation_mode = false;
+static bool flag_contract_assumption_mode = true;
+static int flag_contract_build_level = DEFAULT;
+
+static bool contracts_p1332_default = false, contracts_p1332_review = false,
+ contracts_std = false, contracts_p1429 = false;
+
+static contract_semantic
+get_concrete_check ()
+{
+ return flag_contract_continuation_mode ? CCS_MAYBE : CCS_NEVER;
+}
+
+static contract_semantic
+get_concrete_axiom_semantic ()
+{
+ return flag_contract_assumption_mode ? CCS_ASSUME : CCS_IGNORE;
+}
+
+void
+setup_default_contract_role (bool update)
+{
+ contract_semantic check = get_concrete_check ();
+ contract_semantic axiom = get_concrete_axiom_semantic ();
+ switch (flag_contract_build_level)
+ {
+ case OFF:
+ add_contract_role ("default", CCS_IGNORE, CCS_IGNORE, axiom, update);
+ add_contract_role ("review", CCS_IGNORE, CCS_IGNORE, CCS_IGNORE, update);
+ break;
+ case DEFAULT:
+ add_contract_role ("default", check, CCS_IGNORE, axiom, update);
+ add_contract_role ("review", check, CCS_IGNORE, CCS_IGNORE, update);
+ break;
+ case AUDIT:
+ add_contract_role ("default", check, check, axiom, update);
+ add_contract_role ("review", check, check, CCS_IGNORE, update);
+ break;
+ }
+}
+
+contract_semantic
+map_contract_semantic (const char *ident)
+{
+ if (strcmp (ident, "ignore") == 0)
+ return CCS_IGNORE;
+ else if (strcmp (ident, "assume") == 0)
+ return CCS_ASSUME;
+ else if (strcmp (ident, "check_never_continue") == 0)
+ return CCS_NEVER;
+ else if (strcmp (ident, "check_maybe_continue") == 0)
+ return CCS_MAYBE;
+ return CCS_INVALID;
+}
+
+contract_level
+map_contract_level (const char *ident)
+{
+ if (strcmp (ident, "default") == 0)
+ return CONTRACT_DEFAULT;
+ else if (strcmp (ident, "audit") == 0)
+ return CONTRACT_AUDIT;
+ else if (strcmp (ident, "axiom") == 0)
+ return CONTRACT_AXIOM;
+ return CONTRACT_INVALID;
+}
+
+
+void
+handle_OPT_fcontract_build_level_ (const char *arg)
+{
+ if (contracts_p1332_default || contracts_p1332_review || contracts_p1429)
+ {
+ error ("%<-fcontract-build-level=%> cannot be mixed with p1332/p1429");
+ return;
+ }
+ else
+ contracts_std = true;
+
+ if (strcmp (arg, "off") == 0)
+ flag_contract_build_level = OFF;
+ else if (strcmp (arg, "default") == 0)
+ flag_contract_build_level = DEFAULT;
+ else if (strcmp (arg, "audit") == 0)
+ flag_contract_build_level = AUDIT;
+ else
+ error ("%<-fcontract-build-level=%> must be off|default|audit");
+
+ setup_default_contract_role ();
+}
+
+void
+handle_OPT_fcontract_assumption_mode_ (const char *arg)
+{
+ if (contracts_p1332_default || contracts_p1332_review || contracts_p1429)
+ {
+ error ("%<-fcontract-assumption-mode=%> cannot be mixed with p1332/p1429");
+ return;
+ }
+ else
+ contracts_std = true;
+
+ if (strcmp (arg, "on") == 0)
+ flag_contract_assumption_mode = true;
+ else if (strcmp (arg, "off") == 0)
+ flag_contract_assumption_mode = false;
+ else
+ error ("%<-fcontract-assumption-mode=%> must be %<on%> or %<off%>");
+
+ setup_default_contract_role ();
+}
+
+void
+handle_OPT_fcontract_continuation_mode_ (const char *arg)
+{
+ if (contracts_p1332_default || contracts_p1332_review || contracts_p1429)
+ {
+ error ("%<-fcontract-continuation-mode=%> cannot be mixed with p1332/p1429");
+ return;
+ }
+ else
+ contracts_std = true;
+
+ if (strcmp (arg, "on") == 0)
+ flag_contract_continuation_mode = true;
+ else if (strcmp (arg, "off") == 0)
+ flag_contract_continuation_mode = false;
+ else
+ error ("%<-fcontract-continuation-mode=%> must be %<on%> or %<off%>");
+
+ setup_default_contract_role ();
+}
+
+void
+handle_OPT_fcontract_role_ (const char *arg)
+{
+ const char *name = arg;
+ const char *vals = strchr (name, ':');
+ if (vals == NULL)
+ {
+ error ("%<-fcontract-role=%> must be in the form role:semantics");
+ return;
+ }
+
+ contract_semantic dess = CCS_INVALID, auss = CCS_INVALID, axss = CCS_INVALID;
+ char *des = NULL, *aus = NULL, *axs = NULL;
+ des = xstrdup (vals + 1);
+
+ aus = strchr (des, ',');
+ if (aus == NULL)
+ {
+ error ("%<-fcontract-role=%> semantics must include default,audit,axiom values");
+ goto validate;
+ }
+ *aus = '\0'; // null terminate des
+ aus = aus + 1; // move past null
+
+ axs = strchr (aus, ',');
+ if (axs == NULL)
+ {
+ error ("%<-fcontract-role=%> semantics must include default,audit,axiom values");
+ goto validate;
+ }
+ *axs = '\0'; // null terminate aus
+ axs = axs + 1; // move past null
+
+ dess = lookup_concrete_semantic (des);
+ auss = lookup_concrete_semantic (aus);
+ axss = lookup_concrete_semantic (axs);
+validate:
+ free (des);
+ if (dess == CCS_INVALID || auss == CCS_INVALID || axss == CCS_INVALID)
+ return;
+
+ bool is_defalult_role = role_name_equal (name, "default");
+ bool is_review_role = role_name_equal (name, "review");
+ bool is_std_role = is_defalult_role || is_review_role;
+ if ((contracts_std && is_std_role) || (contracts_p1429 && is_defalult_role))
+ {
+ error ("%<-fcontract-role=%> cannot be mixed with std/p1429 contract flags");
+ return;
+ }
+ else if (is_std_role)
+ {
+ contracts_p1332_default |= is_defalult_role;
+ contracts_p1332_review |= is_review_role;
+ }
+
+ contract_role *role = add_contract_role (name, dess, auss, axss);
+
+ if (role == NULL)
+ {
+ // TODO: not enough space?
+ error ("%<-fcontract-level=%> too many custom roles");
+ return;
+ }
+ else
+ validate_contract_role (role);
+}
+
+void
+handle_OPT_fcontract_semantic_ (const char *arg)
+{
+ if (!strchr (arg, ':'))
+ {
+ error ("%<-fcontract-semantic=%> must be in the form level:semantic");
+ return;
+ }
+
+ if (contracts_std || contracts_p1332_default)
+ {
+ error ("%<-fcontract-semantic=%> cannot be mixed with std/p1332 contract flags");
+ return;
+ }
+ contracts_p1429 = true;
+
+ contract_role *role = get_contract_role ("default");
+ if (!role)
+ {
+ error ("%<-fcontract-semantic=%> cannot find default role");
+ return;
+ }
+
+ const char *semantic = strchr (arg, ':') + 1;
+ contract_semantic sem = lookup_concrete_semantic (semantic);
+ if (sem == CCS_INVALID)
+ return;
+
+ if (strncmp ("default:", arg, 8) == 0)
+ role->default_semantic = sem;
+ else if (strncmp ("audit:", arg, 6) == 0)
+ role->audit_semantic = sem;
+ else if (strncmp ("axiom:", arg, 6) == 0)
+ role->axiom_semantic = sem;
+ else
+ error ("%<-fcontract-semantic=%> level must be default, audit, or axiom");
+ validate_contract_role (role);
+}
+
+/* Convert a contract CONFIG into a contract_mode. */
+
+static contract_mode
+contract_config_to_mode (tree config)
+{
+ if (config == NULL_TREE)
+ return contract_mode (CONTRACT_DEFAULT, get_default_contract_role ());
+
+ /* TREE_LIST has TREE_VALUE is a level and TREE_PURPOSE is role. */
+ if (TREE_CODE (config) == TREE_LIST)
+ {
+ contract_role *role = NULL;
+ if (TREE_PURPOSE (config))
+ role = get_contract_role (IDENTIFIER_POINTER (TREE_PURPOSE (config)));
+ if (!role)
+ role = get_default_contract_role ();
+
+ contract_level level =
+ map_contract_level (IDENTIFIER_POINTER (TREE_VALUE (config)));
+ return contract_mode (level, role);
+ }
+
+ /* Literal semantic. */
+ gcc_assert (TREE_CODE (config) == IDENTIFIER_NODE);
+ contract_semantic semantic =
+ map_contract_semantic (IDENTIFIER_POINTER (config));
+ return contract_mode (semantic);
+}
+
+/* Convert a contract's config into a concrete semantic using the current
+ contract semantic mapping. */
+
+static contract_semantic
+compute_concrete_semantic (tree contract)
+{
+ contract_mode mode = contract_config_to_mode (CONTRACT_MODE (contract));
+ /* Compute the concrete semantic for the contract. */
+ if (!flag_contract_mode)
+ /* If contracts are off, treat all contracts as ignore. */
+ return CCS_IGNORE;
+ else if (mode.kind == contract_mode::cm_invalid)
+ return CCS_INVALID;
+ else if (mode.kind == contract_mode::cm_explicit)
+ return mode.get_semantic ();
+ else
+ {
+ gcc_assert (mode.get_role ());
+ gcc_assert (mode.get_level () != CONTRACT_INVALID);
+ contract_level level = mode.get_level ();
+ contract_role *role = mode.get_role ();
+ if (level == CONTRACT_DEFAULT)
+ return role->default_semantic;
+ else if (level == CONTRACT_AUDIT)
+ return role->audit_semantic;
+ else if (level == CONTRACT_AXIOM)
+ return role->axiom_semantic;
+ }
+ gcc_assert (false);
+}
+
+/* Return true if any contract in CONTRACT_ATTRs is not yet parsed. */
+
+bool
+contract_any_deferred_p (tree contract_attr)
+{
+ for (; contract_attr; contract_attr = CONTRACT_CHAIN (contract_attr))
+ if (CONTRACT_CONDITION_DEFERRED_P (CONTRACT_STATEMENT (contract_attr)))
+ return true;
+ return false;
+}
+
+/* Returns true if all attributes are contracts. */
+
+bool
+all_attributes_are_contracts_p (tree attributes)
+{
+ for (; attributes; attributes = TREE_CHAIN (attributes))
+ if (!cxx_contract_attribute_p (attributes))
+ return false;
+ return true;
+}
+
+/* Mark most of a contract as being invalid. */
+
+tree
+invalidate_contract (tree t)
+{
+ if (TREE_CODE (t) == POSTCONDITION_STMT && POSTCONDITION_IDENTIFIER (t))
+ POSTCONDITION_IDENTIFIER (t) = error_mark_node;
+ CONTRACT_CONDITION (t) = error_mark_node;
+ CONTRACT_COMMENT (t) = error_mark_node;
+ return t;
+}
+
+/* Returns an invented parameter declration of the form 'TYPE ID' for the
+ purpose of parsing the postcondition.
+
+ We use a PARM_DECL instead of a VAR_DECL so that tsubst forces a lookup
+ in local specializations when we instantiate these things later. */
+
+tree
+make_postcondition_variable (cp_expr id, tree type)
+{
+ if (id == error_mark_node)
+ return id;
+
+ tree decl = build_lang_decl (PARM_DECL, id, type);
+ DECL_ARTIFICIAL (decl) = true;
+ DECL_SOURCE_LOCATION (decl) = id.get_location ();
+
+ pushdecl (decl);
+ return decl;
+}
+
+/* As above, except that the type is unknown. */
+
+tree
+make_postcondition_variable (cp_expr id)
+{
+ return make_postcondition_variable (id, make_auto ());
+}
+
+/* Check that the TYPE is valid for a named postcondition variable. Emit a
+ diagnostic if it is not. Returns TRUE if the result is OK and false
+ otherwise. */
+
+bool
+check_postcondition_result (tree decl, tree type, location_t loc)
+{
+ if (VOID_TYPE_P (type))
+ {
+ const char* what;
+ if (DECL_CONSTRUCTOR_P (decl))
+ what = "constructor";
+ else if (DECL_DESTRUCTOR_P (decl))
+ what = "destructor";
+ else
+ what = "function";
+ error_at (loc, "%s does not return a value to test", what);
+ return false;
+ }
+
+ return true;
+}
+
+/* Instantiate each postcondition with the return type to finalize the
+ attribute. */
+
+void
+rebuild_postconditions (tree decl)
+{
+ tree type = TREE_TYPE (TREE_TYPE (decl));
+ tree attributes = DECL_CONTRACTS (decl);
+
+ for (; attributes ; attributes = TREE_CHAIN (attributes))
+ {
+ if (!cxx_contract_attribute_p (attributes))
+ continue;
+ tree contract = TREE_VALUE (TREE_VALUE (attributes));
+ if (TREE_CODE (contract) != POSTCONDITION_STMT)
+ continue;
+ tree condition = CONTRACT_CONDITION (contract);
+
+ /* If any conditions are deferred, they're all deferred. Note that
+ we don't have to instantiate postconditions in that case because
+ the type is available through the declaration. */
+ if (TREE_CODE (condition) == DEFERRED_PARSE)
+ return;
+
+ tree oldvar = POSTCONDITION_IDENTIFIER (contract);
+ if (!oldvar)
+ continue;
+
+ /* Always update the context of the result variable so that it can
+ be remapped by remap_contracts. */
+ DECL_CONTEXT (oldvar) = decl;
+
+ /* If the return type is undeduced, defer until later. */
+ if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+ return;
+
+ /* Check the postcondition variable. */
+ location_t loc = DECL_SOURCE_LOCATION (oldvar);
+ if (!check_postcondition_result (decl, type, loc))
+ {
+ invalidate_contract (contract);
+ continue;
+ }
+
+ /* "Instantiate" the result variable using the known type. Also update
+ the context so the inliner will actually remap this the parameter when
+ generating contract checks. */
+ tree newvar = copy_node (oldvar);
+ TREE_TYPE (newvar) = type;
+
+ /* Make parameters and result available for substitution. */
+ local_specialization_stack stack (lss_copy);
+ for (tree t = DECL_ARGUMENTS (decl); t != NULL_TREE; t = TREE_CHAIN (t))
+ register_local_identity (t);
+ register_local_specialization (newvar, oldvar);
+
+ ++processing_contract_condition;
+ condition = tsubst_expr (condition, make_tree_vec (0),
+ tf_warning_or_error, decl);
+ --processing_contract_condition;
+
+ /* Update the contract condition and result. */
+ POSTCONDITION_IDENTIFIER (contract) = newvar;
+ CONTRACT_CONDITION (contract) = finish_contract_condition (condition);
+ }
+}
+
+static tree
+build_comment (cp_expr condition)
+{
+ /* Try to get the actual source text for the condition; if that fails pretty
+ print the resulting tree. */
+ char *str = get_source_text_between (condition.get_start (),
+ condition.get_finish ());
+ if (!str)
+ {
+ /* FIXME cases where we end up here
+ #line macro usage (oof)
+ contracts10.C
+ contracts11.C */
+ const char *str = expr_to_string (condition);
+ return build_string_literal (strlen (str) + 1, str);
+ }
+
+ tree t = build_string_literal (strlen (str) + 1, str);
+ free (str);
+ return t;
+}
+
+/* Build a contract statement. */
+
+tree
+grok_contract (tree attribute, tree mode, tree result, cp_expr condition,
+ location_t loc)
+{
+ tree_code code;
+ if (is_attribute_p ("assert", attribute))
+ code = ASSERTION_STMT;
+ else if (is_attribute_p ("pre", attribute))
+ code = PRECONDITION_STMT;
+ else if (is_attribute_p ("post", attribute))
+ code = POSTCONDITION_STMT;
+ else
+ gcc_unreachable ();
+
+ /* Build the contract. The condition is added later. In the case that
+ the contract is deferred, result an plain identifier, not a result
+ variable. */
+ tree contract;
+ tree type = void_type_node;
+ if (code != POSTCONDITION_STMT)
+ contract = build3_loc (loc, code, type, mode, NULL_TREE, NULL_TREE);
+ else
+ contract = build4_loc (loc, code, type, mode, NULL_TREE, NULL_TREE, result);
+
+ /* Determine the concrete semantic. */
+ set_contract_semantic (contract, compute_concrete_semantic (contract));
+
+ /* If the contract is deferred, don't do anything with the condition. */
+ if (TREE_CODE (condition) == DEFERRED_PARSE)
+ {
+ CONTRACT_CONDITION (contract) = condition;
+ return contract;
+ }
+
+ /* Generate the comment from the original condition. */
+ CONTRACT_COMMENT (contract) = build_comment (condition);
+
+ /* The condition is converted to bool. */
+ condition = finish_contract_condition (condition);
+ CONTRACT_CONDITION (contract) = condition;
+
+ return contract;
+}
+
+/* Build the contract attribute specifier where IDENTIFIER is one of 'pre',
+ 'post' or 'assert' and CONTRACT is the underlying statement. */
+tree
+finish_contract_attribute (tree identifier, tree contract)
+{
+ if (contract == error_mark_node)
+ return error_mark_node;
+
+ tree attribute = build_tree_list (build_tree_list (NULL_TREE, identifier),
+ build_tree_list (NULL_TREE, contract));
+
+
+ /* Mark the attribute as dependent if the condition is dependent.
+
+ TODO: I'm not sure this is strictly necessary. It's going to be marked as
+ such by a subroutine of cplus_decl_attributes. */
+ tree condition = CONTRACT_CONDITION (contract);
+ if (TREE_CODE (condition) == DEFERRED_PARSE
+ || value_dependent_expression_p (condition))
+ ATTR_IS_DEPENDENT (attribute) = true;
+
+ return attribute;
+}
+
+/* Update condition of a late-parsed contract and postcondition variable,
+ if any. */
+
+void
+update_late_contract (tree contract, tree result, tree condition)
+{
+ if (TREE_CODE (contract) == POSTCONDITION_STMT)
+ POSTCONDITION_IDENTIFIER (contract) = result;
+
+ /* Generate the comment from the original condition. */
+ CONTRACT_COMMENT (contract) = build_comment (condition);
+
+ /* The condition is converted to bool. */
+ condition = finish_contract_condition (condition);
+ CONTRACT_CONDITION (contract) = condition;
+}
+
+/* Return TRUE iff ATTR has been parsed by the front-end as a c++2a contract
+ attribute. */
+
+bool
+cxx_contract_attribute_p (const_tree attr)
+{
+ if (attr == NULL_TREE
+ || TREE_CODE (attr) != TREE_LIST)
+ return false;
+
+ if (!TREE_PURPOSE (attr) || TREE_CODE (TREE_PURPOSE (attr)) != TREE_LIST)
+ return false;
+ if (!TREE_VALUE (attr) || TREE_CODE (TREE_VALUE (attr)) != TREE_LIST)
+ return false;
+ if (!TREE_VALUE (TREE_VALUE (attr)))
+ return false;
+
+ return (TREE_CODE (TREE_VALUE (TREE_VALUE (attr))) == PRECONDITION_STMT
+ || TREE_CODE (TREE_VALUE (TREE_VALUE (attr))) == POSTCONDITION_STMT
+ || TREE_CODE (TREE_VALUE (TREE_VALUE (attr))) == ASSERTION_STMT);
+}
+
+/* True if ATTR is an assertion. */
+
+bool
+cp_contract_assertion_p (const_tree attr)
+{
+ /* This is only an assertion if it is a valid cxx contract attribute and the
+ statement is an ASSERTION_STMT. */
+ return cxx_contract_attribute_p (attr)
+ && TREE_CODE (CONTRACT_STATEMENT (attr)) == ASSERTION_STMT;
+}
+
+/* Remove all c++2a style contract attributes from the DECL_ATTRIBUTEs of the
+ FUNCTION_DECL FNDECL. */
+
+void
+remove_contract_attributes (tree fndecl)
+{
+ tree list = NULL_TREE;
+ for (tree p = DECL_ATTRIBUTES (fndecl); p; p = TREE_CHAIN (p))
+ if (!cxx_contract_attribute_p (p))
+ list = tree_cons (TREE_PURPOSE (p), TREE_VALUE (p), list);
+ DECL_ATTRIBUTES (fndecl) = nreverse (list);
+}
+
+static tree find_first_non_contract (tree attributes)
+{
+ tree head = attributes;
+ tree p = find_contract (attributes);
+
+ /* There are no contracts. */
+ if (!p)
+ return head;
+
+ /* There are leading contracts. */
+ if (p == head)
+ {
+ while (cxx_contract_attribute_p (p))
+ p = TREE_CHAIN (p);
+ head = p;
+ }
+
+ return head;
+}
+
+/* Remove contracts from ATTRIBUTES. */
+
+tree splice_out_contracts (tree attributes)
+{
+ tree head = find_first_non_contract (attributes);
+ if (!head)
+ return NULL_TREE;
+
+ /* Splice out remaining contracts. */
+ tree p = TREE_CHAIN (head);
+ tree q = head;
+ while (p)
+ {
+ if (cxx_contract_attribute_p (p))
+ {
+ /* Skip a sequence of contracts and then link q to the next
+ non-contract attribute. */
+ do
+ p = TREE_CHAIN (p);
+ while (cxx_contract_attribute_p (p));
+ TREE_CHAIN (q) = p;
+ }
+ else
+ p = TREE_CHAIN (p);
+ }
+
+ return head;
+}
+
+/* Copy contract attributes from NEWDECL onto the attribute list of OLDDECL. */
+
+void copy_contract_attributes (tree olddecl, tree newdecl)
+{
+ tree attrs = NULL_TREE;
+ for (tree c = DECL_CONTRACTS (newdecl); c; c = TREE_CHAIN (c))
+ {
+ if (!cxx_contract_attribute_p (c))
+ continue;
+ attrs = tree_cons (TREE_PURPOSE (c), TREE_VALUE (c), attrs);
+ }
+ attrs = chainon (DECL_ATTRIBUTES (olddecl), nreverse (attrs));
+ DECL_ATTRIBUTES (olddecl) = attrs;
+
+ /* And update DECL_CONTEXT of the postcondition result identifier. */
+ rebuild_postconditions (olddecl);
+}
+
+/* Returns the parameter corresponding to the return value of a guarded
+ function D. Returns NULL_TREE if D has no postconditions or is void. */
+
+static tree
+get_postcondition_result_parameter (tree d)
+{
+ if (!d || d == error_mark_node)
+ return NULL_TREE;
+
+ if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (d))))
+ return NULL_TREE;
+
+ tree post = DECL_POST_FN (d);
+ if (!post || post == error_mark_node)
+ return NULL_TREE;
+
+ for (tree arg = DECL_ARGUMENTS (post); arg; arg = TREE_CHAIN (arg))
+ if (!TREE_CHAIN (arg))
+ return arg;
+
+ return NULL_TREE;
+}
+
+
+/* For use with the tree inliner. This preserves non-mapped local variables,
+ such as postcondition result variables, during remapping. */
+
+static tree
+retain_decl (tree decl, copy_body_data *)
+{
+ return decl;
+}
+
+/* Rewrite the condition of contract in place, so that references to SRC's
+ parameters are updated to refer to DST's parameters. The postcondition
+ result variable is left unchanged.
+
+ This, along with remap_contracts, are subroutines of duplicate_decls.
+ When declarations are merged, we sometimes need to update contracts to
+ refer to new parameters.
+
+ If DUPLICATE_P is true, this is called by duplicate_decls to rewrite contacts
+ in terms of a new set of parameters. In this case, we can retain local
+ variables appearing in the contract because the contract is not being
+ prepared for insertion into a new function. Importantly, this preserves the
+ references to postcondition results, which are not replaced during merging.
+
+ If false, we're preparing to emit the contract condition into the body
+ of a new function, so we need to make copies of all local variables
+ appearing in the contract (e.g., if it includes a lambda expression). Note
+ that in this case, postcondition results are mapped to the last parameter
+ of DST.
+
+ This is also used to reuse a parent type's contracts on virtual methods. */
+
+static void
+remap_contract (tree src, tree dst, tree contract, bool duplicate_p)
+{
+ copy_body_data id;
+ hash_map<tree, tree> decl_map;
+
+ memset (&id, 0, sizeof (id));
+ id.src_fn = src;
+ id.dst_fn = dst;
+ id.src_cfun = DECL_STRUCT_FUNCTION (src);
+ id.decl_map = &decl_map;
+
+ /* If we're merging contracts, don't copy local variables. */
+ id.copy_decl = duplicate_p ? retain_decl : copy_decl_no_change;
+
+ id.transform_call_graph_edges = CB_CGE_DUPLICATE;
+ id.transform_new_cfg = false;
+ id.transform_return_to_modify = false;
+ id.transform_parameter = true;
+
+ /* Make sure not to unshare trees behind the front-end's back
+ since front-end specific mechanisms may rely on sharing. */
+ id.regimplify = false;
+ id.do_not_unshare = true;
+ id.do_not_fold = true;
+
+ /* We're not inside any EH region. */
+ id.eh_lp_nr = 0;
+
+ bool do_remap = false;
+
+ /* Insert parameter remappings. */
+ if (TREE_CODE (src) == FUNCTION_DECL)
+ src = DECL_ARGUMENTS (src);
+ if (TREE_CODE (dst) == FUNCTION_DECL)
+ dst = DECL_ARGUMENTS (dst);
+
+ for (tree sp = src, dp = dst;
+ sp || dp;
+ sp = DECL_CHAIN (sp), dp = DECL_CHAIN (dp))
+ {
+ if (!sp && dp
+ && TREE_CODE (contract) == POSTCONDITION_STMT
+ && DECL_CHAIN (dp) == NULL_TREE)
+ {
+ gcc_assert (!duplicate_p);
+ if (tree result = POSTCONDITION_IDENTIFIER (contract))
+ {
+ gcc_assert (DECL_P (result));
+ insert_decl_map (&id, result, dp);
+ do_remap = true;
+ }
+ break;
+ }
+ gcc_assert (sp && dp);
+
+ if (sp == dp)
+ continue;
+
+ insert_decl_map (&id, sp, dp);
+ do_remap = true;
+ }
+ if (!do_remap)
+ return;
+
+ walk_tree (&CONTRACT_CONDITION (contract), copy_tree_body_r, &id, NULL);
+}
+
+/* Rewrite any references to SRC's PARM_DECLs to the corresponding PARM_DECL in
+ DST in all of the contract attributes in CONTRACTS by calling remap_contract
+ on each.
+
+ This is used for two purposes: to rewrite contract attributes during
+ duplicate_decls, and to prepare contracts for emission into a function's
+ respective precondition and postcondition functions. DUPLICATE_P is used
+ to determine the context in which this function is called. See above for
+ the behavior described by this flag. */
+
+void
+remap_contracts (tree src, tree dst, tree contracts, bool duplicate_p)
+{
+ for (tree attr = contracts; attr; attr = CONTRACT_CHAIN (attr))
+ {
+ if (!cxx_contract_attribute_p (attr))
+ continue;
+ tree contract = CONTRACT_STATEMENT (attr);
+ if (TREE_CODE (CONTRACT_CONDITION (contract)) != DEFERRED_PARSE)
+ remap_contract (src, dst, contract, duplicate_p);
+ }
+}
+
+/* Helper to replace references to dummy this parameters with references to
+ the first argument of the FUNCTION_DECL DATA. */
+
+static tree
+remap_dummy_this_1 (tree *tp, int *, void *data)
+{
+ if (!is_this_parameter (*tp))
+ return NULL_TREE;
+ tree fn = (tree)data;
+ *tp = DECL_ARGUMENTS (fn);
+ return NULL_TREE;
+}
+
+/* Replace all references to dummy this parameters in EXPR with references to
+ the first argument of the FUNCTION_DECL FN. */
+
+static void
+remap_dummy_this (tree fn, tree *expr)
+{
+ walk_tree (expr, remap_dummy_this_1, fn, NULL);
+}
+
+/* Contract matching. */
+
+/* True if the contract is valid. */
+
+static bool
+contract_valid_p (tree contract)
+{
+ return CONTRACT_CONDITION (contract) != error_mark_node;
+}
+
+/* True if the contract attribute is valid. */
+
+static bool
+contract_attribute_valid_p (tree attribute)
+{
+ return contract_valid_p (TREE_VALUE (TREE_VALUE (attribute)));
+}
+
+/* Compare the contract conditions of OLD_ATTR and NEW_ATTR. Returns false
+ if the conditions are equivalent, and true otherwise. */
+
+static bool
+check_for_mismatched_contracts (tree old_attr, tree new_attr,
+ contract_matching_context ctx)
+{
+ tree old_contract = CONTRACT_STATEMENT (old_attr);
+ tree new_contract = CONTRACT_STATEMENT (new_attr);
+
+ /* Different kinds of contracts do not match. */
+ if (TREE_CODE (old_contract) != TREE_CODE (new_contract))
+ {
+ auto_diagnostic_group d;
+ error_at (EXPR_LOCATION (new_contract),
+ ctx == cmc_declaration
+ ? "mismatched contract attribute in declaration"
+ : "mismatched contract attribute in override");
+ inform (EXPR_LOCATION (old_contract), "previous contract here");
+ return true;
+ }
+
+ /* A deferred contract tentatively matches. */
+ if (CONTRACT_CONDITION_DEFERRED_P (new_contract))
+ return false;
+
+ /* Compare the conditions of the contracts. We fold immediately to avoid
+ issues comparing contracts on overrides that use parameters -- see
+ contracts-pre3. */
+ tree t1 = cp_fully_fold_init (CONTRACT_CONDITION (old_contract));
+ tree t2 = cp_fully_fold_init (CONTRACT_CONDITION (new_contract));
+
+ /* Compare the contracts. The fold doesn't eliminate conversions to members.
+ Set the comparing_override_contracts flag to ensure that references
+ through 'this' are equal if they designate the same member, regardless of
+ the path those members. */
+ bool saved_comparing_contracts = comparing_override_contracts;
+ comparing_override_contracts = (ctx == cmc_override);
+ bool matching_p = cp_tree_equal (t1, t2);
+ comparing_override_contracts = saved_comparing_contracts;
+
+ if (!matching_p)
+ {
+ auto_diagnostic_group d;
+ error_at (EXPR_LOCATION (CONTRACT_CONDITION (new_contract)),
+ ctx == cmc_declaration
+ ? "mismatched contract condition in declaration"
+ : "mismatched contract condition in override");
+ inform (EXPR_LOCATION (CONTRACT_CONDITION (old_contract)),
+ "previous contract here");
+ return true;
+ }
+
+ return false;
+}
+
+/* Compare the contract attributes of OLDDECL and NEWDECL. Returns true
+ if the contracts match, and false if they differ. */
+
+bool
+match_contract_conditions (location_t oldloc, tree old_attrs,
+ location_t newloc, tree new_attrs,
+ contract_matching_context ctx)
+{
+ /* Contracts only match if they are both specified. */
+ if (!old_attrs || !new_attrs)
+ return true;
+
+ /* Compare each contract in turn. */
+ while (old_attrs && new_attrs)
+ {
+ /* If either contract is ill-formed, skip the rest of the comparison,
+ since we've already diagnosed an error. */
+ if (!contract_attribute_valid_p (new_attrs)
+ || !contract_attribute_valid_p (old_attrs))
+ return false;
+
+ if (check_for_mismatched_contracts (old_attrs, new_attrs, ctx))
+ return false;
+ old_attrs = CONTRACT_CHAIN (old_attrs);
+ new_attrs = CONTRACT_CHAIN (new_attrs);
+ }
+
+ /* If we didn't compare all attributes, the contracts don't match. */
+ if (old_attrs || new_attrs)
+ {
+ auto_diagnostic_group d;
+ error_at (newloc,
+ ctx == cmc_declaration
+ ? "declaration has a different number of contracts than "
+ "previously declared"
+ : "override has a different number of contracts than "
+ "previously declared");
+ inform (oldloc,
+ new_attrs
+ ? "original declaration with fewer contracts here"
+ : "original declaration with more contracts here");
+ return false;
+ }
+
+ return true;
+}
+
+/* Deferred contract mapping.
+
+ This is used to compare late-parsed contracts on overrides with their
+ base class functions.
+
+ TODO: It seems like this could be replaced by a simple list that maps from
+ overrides to their base functions. It's not clear that we really need
+ a map to a function + a list of contracts. */
+
+/* Map from FNDECL to a tree list of contracts that have not been matched or
+ diagnosed yet. The TREE_PURPOSE is the basefn we're overriding, and the
+ TREE_VALUE is the list of contract attrs for BASEFN. */
+
+static hash_map<tree_decl_hash, tree> pending_guarded_decls;
+
+void
+defer_guarded_contract_match (tree fndecl, tree fn, tree contracts)
+{
+ if (!pending_guarded_decls.get (fndecl))
+ {
+ pending_guarded_decls.put (fndecl, build_tree_list (fn, contracts));
+ return;
+ }
+ for (tree pending = *pending_guarded_decls.get (fndecl);
+ pending;
+ pending = TREE_CHAIN (pending))
+ {
+ if (TREE_VALUE (pending) == contracts)
+ return;
+ if (TREE_CHAIN (pending) == NULL_TREE)
+ TREE_CHAIN (pending) = build_tree_list (fn, contracts);
+ }
+}
+
+/* If the FUNCTION_DECL DECL has any contracts that had their matching
+ deferred earlier, do that checking now. */
+
+void
+match_deferred_contracts (tree decl)
+{
+ tree *tp = pending_guarded_decls.get (decl);
+ if (!tp)
+ return;
+
+ gcc_assert(!contract_any_deferred_p (DECL_CONTRACTS (decl)));
+
+ processing_template_decl_sentinel ptds;
+ processing_template_decl = uses_template_parms (decl);
+
+ /* Do late contract matching. */
+ for (tree pending = *tp; pending; pending = TREE_CHAIN (pending))
+ {
+ tree new_contracts = TREE_VALUE (pending);
+ location_t new_loc = CONTRACT_SOURCE_LOCATION (new_contracts);
+ tree old_contracts = DECL_CONTRACTS (decl);
+ location_t old_loc = CONTRACT_SOURCE_LOCATION (old_contracts);
+ tree base = TREE_PURPOSE (pending);
+ match_contract_conditions (new_loc, new_contracts,
+ old_loc, old_contracts,
+ base ? cmc_override : cmc_declaration);
+ }
+
+ /* Clear out deferred match list so we don't check it twice. */
+ pending_guarded_decls.remove (decl);
+}
+
+/* Map from FUNCTION_DECL to a FUNCTION_DECL for either the PRE_FN or POST_FN.
+ These are used to parse contract conditions and are called inside the body
+ of the guarded function. */
+static GTY(()) hash_map<tree, tree> *decl_pre_fn;
+static GTY(()) hash_map<tree, tree> *decl_post_fn;
+
+/* Returns the precondition funtion for D, or null if not set. */
+
+tree
+get_precondition_function (tree d)
+{
+ hash_map_maybe_create<hm_ggc> (decl_pre_fn);
+ tree *result = decl_pre_fn->get (d);
+ return result ? *result : NULL_TREE;
+}
+
+/* Returns the postcondition funtion for D, or null if not set. */
+
+tree
+get_postcondition_function (tree d)
+{
+ hash_map_maybe_create<hm_ggc> (decl_post_fn);
+ tree *result = decl_post_fn->get (d);
+ return result ? *result : NULL_TREE;
+}
+
+/* Makes PRE the precondition function for D. */
+
+void
+set_precondition_function (tree d, tree pre)
+{
+ gcc_assert (pre);
+ hash_map_maybe_create<hm_ggc> (decl_pre_fn);
+ gcc_assert (!decl_pre_fn->get (d));
+ decl_pre_fn->put (d, pre);
+}
+
+/* Makes POST the postcondition function for D. */
+
+void
+set_postcondition_function (tree d, tree post)
+{
+ gcc_assert (post);
+ hash_map_maybe_create<hm_ggc> (decl_post_fn);
+ gcc_assert (!decl_post_fn->get (d));
+ decl_post_fn->put (d, post);
+}
+
+/* Set the PRE and POST functions for D. Note that PRE and POST can be
+ null in this case. If so the functions are not recorded. */
+
+void
+set_contract_functions (tree d, tree pre, tree post)
+{
+ if (pre)
+ set_precondition_function (d, pre);
+ if (post)
+ set_postcondition_function (d, post);
+}
+
+/* Return a copy of the FUNCTION_DECL IDECL with its own unshared
+ PARM_DECL and DECL_ATTRIBUTEs. */
+
+static tree
+copy_fn_decl (tree idecl)
+{
+ tree decl = copy_decl (idecl);
+ DECL_ATTRIBUTES (decl) = copy_list (DECL_ATTRIBUTES (idecl));
+
+ if (DECL_RESULT (idecl))
+ {
+ DECL_RESULT (decl) = copy_decl (DECL_RESULT (idecl));
+ DECL_CONTEXT (DECL_RESULT (decl)) = decl;
+ }
+ if (!DECL_ARGUMENTS (idecl) || VOID_TYPE_P (DECL_ARGUMENTS (idecl)))
+ return decl;
+
+ tree last = DECL_ARGUMENTS (decl) = copy_decl (DECL_ARGUMENTS (decl));
+ DECL_CONTEXT (last) = decl;
+ for (tree p = TREE_CHAIN (DECL_ARGUMENTS (idecl)); p; p = TREE_CHAIN (p))
+ {
+ if (VOID_TYPE_P (p))
+ {
+ TREE_CHAIN (last) = void_list_node;
+ break;
+ }
+ last = TREE_CHAIN (last) = copy_decl (p);
+ DECL_CONTEXT (last) = decl;
+ }
+ return decl;
+}
+
+/* Build a declaration for the pre- or postcondition of a guarded FNDECL. */
+
+static tree
+build_contract_condition_function (tree fndecl, bool pre)
+{
+ if (TREE_TYPE (fndecl) == error_mark_node)
+ return error_mark_node;
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
+ && !TYPE_METHOD_BASETYPE (TREE_TYPE (fndecl)))
+ return error_mark_node;
+
+ /* Create and rename the unchecked function and give an internal name. */
+ tree fn = copy_fn_decl (fndecl);
+ DECL_RESULT (fn) = NULL_TREE;
+ tree value_type = pre ? void_type_node : TREE_TYPE (TREE_TYPE (fn));
+
+ /* Don't propagate declaration attributes to the checking function,
+ including the original contracts. */
+ DECL_ATTRIBUTES (fn) = NULL_TREE;
+
+ tree arg_types = NULL_TREE;
+ tree *last = &arg_types;
+
+ /* FIXME will later optimizations delete unused args to prevent extra arg
+ passing? do we care? */
+ tree class_type = NULL_TREE;
+ for (tree arg_type = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ arg_type && arg_type != void_list_node;
+ arg_type = TREE_CHAIN (arg_type))
+ {
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
+ && TYPE_ARG_TYPES (TREE_TYPE (fn)) == arg_type)
+ {
+ class_type = TREE_TYPE (TREE_VALUE (arg_type));
+ continue;
+ }
+ *last = build_tree_list (TREE_PURPOSE (arg_type), TREE_VALUE (arg_type));
+ last = &TREE_CHAIN (*last);
+ }
+
+ if (pre || VOID_TYPE_P (value_type))
+ *last = void_list_node;
+ else
+ {
+ tree name = get_identifier ("__r");
+ tree parm = build_lang_decl (PARM_DECL, name, value_type);
+ DECL_CONTEXT (parm) = fn;
+ DECL_ARTIFICIAL (parm) = true;
+ DECL_ARGUMENTS (fn) = chainon (DECL_ARGUMENTS (fn), parm);
+
+ *last = build_tree_list (NULL_TREE, value_type);
+ TREE_CHAIN (*last) = void_list_node;
+
+ if (aggregate_value_p (value_type, fndecl))
+ /* If FNDECL returns in memory, don't return the value from the
+ postcondition. */
+ value_type = void_type_node;
+ }
+
+ TREE_TYPE (fn) = build_function_type (value_type, arg_types);
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl))
+ TREE_TYPE (fn) = build_method_type (class_type, TREE_TYPE (fn));
+
+ DECL_NAME (fn) = copy_node (DECL_NAME (fn));
+ DECL_INITIAL (fn) = error_mark_node;
+ DECL_ABSTRACT_ORIGIN (fn) = fndecl;
+
+ IDENTIFIER_VIRTUAL_P (DECL_NAME (fn)) = false;
+ DECL_VIRTUAL_P (fn) = false;
+
+ /* Make these functions internal if we can, i.e. if the guarded function is
+ not vague linkage, or if we can put them in a comdat group with the
+ guarded function. */
+ if (!DECL_WEAK (fndecl) || HAVE_COMDAT_GROUP)
+ {
+ TREE_PUBLIC (fn) = false;
+ DECL_EXTERNAL (fn) = false;
+ DECL_WEAK (fn) = false;
+ DECL_COMDAT (fn) = false;
+
+ /* We haven't set the comdat group on the guarded function yet, we'll add
+ this to the same group in comdat_linkage later. */
+ gcc_assert (!DECL_ONE_ONLY (fndecl));
+
+ DECL_INTERFACE_KNOWN (fn) = true;
+ }
+
+ DECL_ARTIFICIAL (fn) = true;
+
+ /* Update various inline related declaration properties. */
+ //DECL_DECLARED_INLINE_P (fn) = true;
+ DECL_DISREGARD_INLINE_LIMITS (fn) = true;
+ TREE_NO_WARNING (fn) = 1;
+
+ return fn;
+}
+
+/* Return true if CONTRACT is checked or assumed under the current build
+ configuration. */
+
+bool
+contract_active_p (tree contract)
+{
+ return get_contract_semantic (contract) != CCS_IGNORE;
+}
+
+static bool
+has_active_contract_condition (tree d, tree_code c)
+{
+ for (tree as = DECL_CONTRACTS (d) ; as != NULL_TREE; as = TREE_CHAIN (as))
+ {
+ tree contract = TREE_VALUE (TREE_VALUE (as));
+ if (TREE_CODE (contract) == c && contract_active_p (contract))
+ return true;
+ }
+ return false;
+}
+
+/* True if D has any checked or assumed preconditions. */
+
+static bool
+has_active_preconditions (tree d)
+{
+ return has_active_contract_condition (d, PRECONDITION_STMT);
+}
+
+/* True if D has any checked or assumed postconditions. */
+
+static bool
+has_active_postconditions (tree d)
+{
+ return has_active_contract_condition (d, POSTCONDITION_STMT);
+}
+
+/* Return true if any contract in the CONTRACT list is checked or assumed
+ under the current build configuration. */
+
+bool
+contract_any_active_p (tree contract)
+{
+ for (; contract != NULL_TREE; contract = CONTRACT_CHAIN (contract))
+ if (contract_active_p (TREE_VALUE (TREE_VALUE (contract))))
+ return true;
+ return false;
+}
+
+/* Do we need to mess with contracts for DECL1? */
+
+static bool
+handle_contracts_p (tree decl1)
+{
+ return (flag_contracts
+ && !processing_template_decl
+ && DECL_ABSTRACT_ORIGIN (decl1) == NULL_TREE
+ && contract_any_active_p (DECL_CONTRACTS (decl1)));
+}
+
+/* Should we break out DECL1's pre/post contracts into separate functions?
+ FIXME I'd like this to default to 0, but that will need an overhaul to the
+ return identifier handling to just refer to the RESULT_DECL. */
+
+static bool
+outline_contracts_p (tree decl1)
+{
+ return (!DECL_CONSTRUCTOR_P (decl1)
+ && !DECL_DESTRUCTOR_P (decl1));
+}
+
+/* Build the precondition checking function for D. */
+
+static tree
+build_precondition_function (tree d)
+{
+ if (!has_active_preconditions (d))
+ return NULL_TREE;
+
+ return build_contract_condition_function (d, /*pre=*/true);
+}
+
+/* Build the postcondition checking function for D. If the return
+ type is undeduced, don't build the function yet. We do that in
+ apply_deduced_return_type. */
+
+static tree
+build_postcondition_function (tree d)
+{
+ if (!has_active_postconditions (d))
+ return NULL_TREE;
+
+ tree type = TREE_TYPE (TREE_TYPE (d));
+ if (is_auto (type))
+ return NULL_TREE;
+
+ return build_contract_condition_function (d, /*pre=*/false);
+}
+
+static void
+build_contract_function_decls (tree d)
+{
+ /* Constructors and destructors have their contracts inserted inline. */
+ if (!outline_contracts_p (d))
+ return;
+
+ /* Build the pre/post functions (or not). */
+ tree pre = build_precondition_function (d);
+ tree post = build_postcondition_function (d);
+ set_contract_functions (d, pre, post);
+}
+
+static const char *
+get_contract_level_name (tree contract)
+{
+ if (CONTRACT_LITERAL_MODE_P (contract))
+ return "";
+ if (tree mode = CONTRACT_MODE (contract))
+ if (tree level = TREE_VALUE (mode))
+ return IDENTIFIER_POINTER (level);
+ return "default";
+}
+
+static const char *
+get_contract_role_name (tree contract)
+{
+ if (CONTRACT_LITERAL_MODE_P (contract))
+ return "";
+ if (tree mode = CONTRACT_MODE (contract))
+ if (tree role = TREE_PURPOSE (mode))
+ return IDENTIFIER_POINTER (role);
+ return "default";
+}
+
+/* Build a layout-compatible internal version of std::contract_violation. */
+
+static tree
+get_pseudo_contract_violation_type ()
+{
+ if (!pseudo_contract_violation_type)
+ {
+ /* Must match <contract>:
+ class contract_violation {
+ const char* _M_file;
+ const char* _M_function;
+ const char* _M_comment;
+ const char* _M_level;
+ const char* _M_role;
+ uint_least32_t _M_line;
+ signed char _M_continue;
+ If this changes, also update the initializer in
+ build_contract_violation. */
+ const tree types[] = { const_string_type_node,
+ const_string_type_node,
+ const_string_type_node,
+ const_string_type_node,
+ const_string_type_node,
+ uint_least32_type_node,
+ signed_char_type_node };
+ tree fields = NULL_TREE;
+ for (tree type : types)
+ {
+ /* finish_builtin_struct wants fieldss chained in reverse. */
+ tree next = build_decl (BUILTINS_LOCATION, FIELD_DECL,
+ NULL_TREE, type);
+ DECL_CHAIN (next) = fields;
+ fields = next;
+ }
+ iloc_sentinel ils (input_location);
+ input_location = BUILTINS_LOCATION;
+ pseudo_contract_violation_type = make_class_type (RECORD_TYPE);
+ finish_builtin_struct (pseudo_contract_violation_type,
+ "__pseudo_contract_violation",
+ fields, NULL_TREE);
+ CLASSTYPE_AS_BASE (pseudo_contract_violation_type)
+ = pseudo_contract_violation_type;
+ DECL_CONTEXT (TYPE_NAME (pseudo_contract_violation_type))
+ = FROB_CONTEXT (global_namespace);
+ TREE_PUBLIC (TYPE_NAME (pseudo_contract_violation_type)) = true;
+ CLASSTYPE_LITERAL_P (pseudo_contract_violation_type) = true;
+ CLASSTYPE_LAZY_COPY_CTOR (pseudo_contract_violation_type) = true;
+ xref_basetypes (pseudo_contract_violation_type, /*bases=*/NULL_TREE);
+ pseudo_contract_violation_type
+ = cp_build_qualified_type (pseudo_contract_violation_type,
+ TYPE_QUAL_CONST);
+ }
+ return pseudo_contract_violation_type;
+}
+
+/* Return a VAR_DECL to pass to handle_contract_violation. */
+
+static tree
+build_contract_violation (tree contract, contract_continuation cmode)
+{
+ expanded_location loc = expand_location (EXPR_LOCATION (contract));
+ const char *function = fndecl_name (DECL_ORIGIN (current_function_decl));
+ const char *level = get_contract_level_name (contract);
+ const char *role = get_contract_role_name (contract);
+
+ /* Must match the type layout in get_pseudo_contract_violation_type. */
+ tree ctor = build_constructor_va
+ (init_list_type_node, 7,
+ NULL_TREE, build_string_literal (loc.file),
+ NULL_TREE, build_string_literal (function),
+ NULL_TREE, CONTRACT_COMMENT (contract),
+ NULL_TREE, build_string_literal (level),
+ NULL_TREE, build_string_literal (role),
+ NULL_TREE, build_int_cst (uint_least32_type_node, loc.line),
+ NULL_TREE, build_int_cst (signed_char_type_node, cmode));
+
+ ctor = finish_compound_literal (get_pseudo_contract_violation_type (),
+ ctor, tf_none);
+ protected_set_expr_location (ctor, EXPR_LOCATION (contract));
+ return ctor;
+}
+
+/* Return handle_contract_violation(), declaring it if needed. */
+
+static tree
+declare_handle_contract_violation ()
+{
+ tree fnname = get_identifier ("handle_contract_violation");
+ tree viol_name = get_identifier ("contract_violation");
+ tree l = lookup_qualified_name (global_namespace, fnname,
+ LOOK_want::HIDDEN_FRIEND);
+ for (tree f: lkp_range (l))
+ if (TREE_CODE (f) == FUNCTION_DECL)
+ {
+ tree parms = TYPE_ARG_TYPES (TREE_TYPE (f));
+ if (remaining_arguments (parms) != 1)
+ continue;
+ tree parmtype = non_reference (TREE_VALUE (parms));
+ if (CLASS_TYPE_P (parmtype)
+ && TYPE_IDENTIFIER (parmtype) == viol_name)
+ return f;
+ }
+
+ tree id_exp = get_identifier ("experimental");
+ tree ns_exp = lookup_qualified_name (std_node, id_exp);
+
+ tree violation = error_mark_node;
+ if (TREE_CODE (ns_exp) == NAMESPACE_DECL)
+ violation = lookup_qualified_name (ns_exp, viol_name,
+ LOOK_want::TYPE
+ |LOOK_want::HIDDEN_FRIEND);
+
+ if (TREE_CODE (violation) == TYPE_DECL)
+ violation = TREE_TYPE (violation);
+ else
+ {
+ push_nested_namespace (std_node);
+ push_namespace (id_exp, /*inline*/false);
+ violation = make_class_type (RECORD_TYPE);
+ create_implicit_typedef (viol_name, violation);
+ DECL_SOURCE_LOCATION (TYPE_NAME (violation)) = BUILTINS_LOCATION;
+ DECL_CONTEXT (TYPE_NAME (violation)) = current_namespace;
+ pushdecl_namespace_level (TYPE_NAME (violation), /*hidden*/true);
+ pop_namespace ();
+ pop_nested_namespace (std_node);
+ }
+
+ tree argtype = cp_build_qualified_type (violation, TYPE_QUAL_CONST);
+ argtype = cp_build_reference_type (argtype, /*rval*/false);
+ tree fntype = build_function_type_list (void_type_node, argtype, NULL_TREE);
+
+ push_nested_namespace (global_namespace);
+ tree fn = build_cp_library_fn_ptr ("handle_contract_violation", fntype,
+ ECF_COLD);
+ pushdecl_namespace_level (fn, /*hiding*/true);
+ pop_nested_namespace (global_namespace);
+
+ return fn;
+}
+
+/* Build the call to handle_contract_violation for CONTRACT. */
+
+static void
+build_contract_handler_call (tree contract,
+ contract_continuation cmode)
+{
+ tree violation = build_contract_violation (contract, cmode);
+ tree violation_fn = declare_handle_contract_violation ();
+ tree call = build_call_n (violation_fn, 1, build_address (violation));
+ finish_expr_stmt (call);
+}
+
+/* Generate the code that checks or assumes a contract, but do not attach
+ it to the current context. This is called during genericization. */
+
+tree
+build_contract_check (tree contract)
+{
+ contract_semantic semantic = get_contract_semantic (contract);
+ if (semantic == CCS_INVALID)
+ return NULL_TREE;
+
+ /* Ignored contracts are never checked or assumed. */
+ if (semantic == CCS_IGNORE)
+ return void_node;
+
+ remap_dummy_this (current_function_decl, &CONTRACT_CONDITION (contract));
+ tree condition = CONTRACT_CONDITION (contract);
+ if (condition == error_mark_node)
+ return NULL_TREE;
+
+ location_t loc = EXPR_LOCATION (contract);
+
+ if (semantic == CCS_ASSUME)
+ return build_assume_call (loc, condition);
+
+ tree if_stmt = begin_if_stmt ();
+ tree cond = build_x_unary_op (loc,
+ TRUTH_NOT_EXPR,
+ condition, NULL_TREE,
+ tf_warning_or_error);
+ finish_if_stmt_cond (cond, if_stmt);
+
+ /* Get the continuation mode. */
+ contract_continuation cmode;
+ switch (semantic)
+ {
+ case CCS_NEVER: cmode = NEVER_CONTINUE; break;
+ case CCS_MAYBE: cmode = MAYBE_CONTINUE; break;
+ default: gcc_unreachable ();
+ }
+
+ build_contract_handler_call (contract, cmode);
+ if (cmode == NEVER_CONTINUE)
+ finish_expr_stmt (build_call_a (terminate_fn, 0, nullptr));
+
+ finish_then_clause (if_stmt);
+ tree scope = IF_SCOPE (if_stmt);
+ IF_SCOPE (if_stmt) = NULL;
+ return do_poplevel (scope);
+}
+
+/* Add the contract statement CONTRACT to the current block if valid. */
+
+static void
+emit_contract_statement (tree contract)
+{
+ /* Only add valid contracts. */
+ if (get_contract_semantic (contract) != CCS_INVALID
+ && CONTRACT_CONDITION (contract) != error_mark_node)
+ add_stmt (contract);
+}
+
+/* Generate the statement for the given contract attribute by adding the
+ statement to the current block. Returns the next contract in the chain. */
+
+static tree
+emit_contract_attr (tree attr)
+{
+ gcc_assert (TREE_CODE (attr) == TREE_LIST);
+
+ emit_contract_statement (CONTRACT_STATEMENT (attr));
+
+ return CONTRACT_CHAIN (attr);
+}
+
+/* Add the statements of contract attributes ATTRS to the current block. */
+
+static void
+emit_contract_conditions (tree attrs, tree_code code)
+{
+ if (!attrs) return;
+ gcc_assert (TREE_CODE (attrs) == TREE_LIST);
+ gcc_assert (code == PRECONDITION_STMT || code == POSTCONDITION_STMT);
+ while (attrs)
+ {
+ tree contract = CONTRACT_STATEMENT (attrs);
+ if (TREE_CODE (contract) == code)
+ attrs = emit_contract_attr (attrs);
+ else
+ attrs = CONTRACT_CHAIN (attrs);
+ }
+}
+
+/* Emit the statement for an assertion attribute. */
+
+void
+emit_assertion (tree attr)
+{
+ emit_contract_attr (attr);
+}
+
+/* Emit statements for precondition attributes. */
+
+static void
+emit_preconditions (tree attr)
+{
+ return emit_contract_conditions (attr, PRECONDITION_STMT);
+}
+
+/* Emit statements for postcondition attributes. */
+
+static void
+emit_postconditions_cleanup (tree contracts)
+{
+ tree stmts = push_stmt_list ();
+ emit_contract_conditions (contracts, POSTCONDITION_STMT);
+ stmts = pop_stmt_list (stmts);
+ push_cleanup (NULL_TREE, stmts, /*eh_only*/false);
+}
+
+/* We're compiling the pre/postcondition function CONDFN; remap any FN
+ attributes that match CODE and emit them. */
+
+static void
+remap_and_emit_conditions (tree fn, tree condfn, tree_code code)
+{
+ gcc_assert (code == PRECONDITION_STMT || code == POSTCONDITION_STMT);
+ for (tree attr = DECL_CONTRACTS (fn); attr;
+ attr = CONTRACT_CHAIN (attr))
+ {
+ tree contract = CONTRACT_STATEMENT (attr);
+ if (TREE_CODE (contract) == code)
+ {
+ contract = copy_node (contract);
+ remap_contract (fn, condfn, contract, /*duplicate_p=*/false);
+ emit_contract_statement (contract);
+ }
+ }
+}
+
+/* Converts a contract condition to bool and ensures it has a locaiton. */
+
+tree
+finish_contract_condition (cp_expr condition)
+{
+ /* Ensure we have the condition location saved in case we later need to
+ emit a conversion error during template instantiation and wouldn't
+ otherwise have it. */
+ if (!CAN_HAVE_LOCATION_P (condition) || EXCEPTIONAL_CLASS_P (condition))
+ {
+ condition = build1_loc (condition.get_location (), VIEW_CONVERT_EXPR,
+ TREE_TYPE (condition), condition);
+ EXPR_LOCATION_WRAPPER_P (condition) = 1;
+ }
+
+ if (condition == error_mark_node || type_dependent_expression_p (condition))
+ return condition;
+
+ return condition_conversion (condition);
+}
+
+void
+maybe_update_postconditions (tree fco)
+{
+ /* Update any postconditions and the postcondition checking function
+ as needed. If there are postconditions, we'll use those to rewrite
+ return statements to check postconditions. */
+ if (has_active_postconditions (fco))
+ {
+ rebuild_postconditions (fco);
+ tree post = build_postcondition_function (fco);
+ set_postcondition_function (fco, post);
+ }
+}
+
+/* Called on attribute lists that must not contain contracts. If any
+ contracts are present, issue an error diagnostic and return true. */
+
+bool
+diagnose_misapplied_contracts (tree attributes)
+{
+ if (attributes == NULL_TREE)
+ return false;
+
+ tree contract_attr = find_contract (attributes);
+ if (!contract_attr)
+ return false;
+
+ error_at (EXPR_LOCATION (CONTRACT_STATEMENT (contract_attr)),
+ "contracts must appertain to a function type");
+
+ /* Invalidate the contract so we don't treat it as valid later on. */
+ invalidate_contract (TREE_VALUE (TREE_VALUE (contract_attr)));
+
+ return true;
+}
+
+/* Build and return an argument list containing all the parameters of the
+ (presumably guarded) FUNCTION_DECL FN. This can be used to forward all of
+ FN's arguments to a function taking the same list of arguments -- namely
+ the unchecked form of FN.
+
+ We use CALL_FROM_THUNK_P instead of forward_parm for forwarding
+ semantics. */
+
+static vec<tree, va_gc> *
+build_arg_list (tree fn)
+{
+ vec<tree, va_gc> *args = make_tree_vector ();
+ for (tree t = DECL_ARGUMENTS (fn); t; t = DECL_CHAIN (t))
+ vec_safe_push (args, t);
+ return args;
+}
+
+void
+start_function_contracts (tree decl1)
+{
+ if (!handle_contracts_p (decl1))
+ return;
+
+ if (!outline_contracts_p (decl1))
+ {
+ emit_preconditions (DECL_CONTRACTS (current_function_decl));
+ emit_postconditions_cleanup (DECL_CONTRACTS (current_function_decl));
+ return;
+ }
+
+ /* Contracts may have just been added without a chance to parse them, though
+ we still need the PRE_FN available to generate a call to it. */
+ if (!DECL_PRE_FN (decl1))
+ build_contract_function_decls (decl1);
+
+ /* If we're starting a guarded function with valid contracts, we need to
+ insert a call to the pre function. */
+ if (DECL_PRE_FN (decl1)
+ && DECL_PRE_FN (decl1) != error_mark_node)
+ {
+ releasing_vec args = build_arg_list (decl1);
+ tree call = build_call_a (DECL_PRE_FN (decl1),
+ args->length (),
+ args->address ());
+ CALL_FROM_THUNK_P (call) = true;
+ finish_expr_stmt (call);
+ }
+}
+
+/* Finish up the pre & post function definitions for a guarded FNDECL,
+ and compile those functions all the way to assembler language output. */
+
+void
+finish_function_contracts (tree fndecl)
+{
+ if (!handle_contracts_p (fndecl)
+ || !outline_contracts_p (fndecl))
+ return;
+
+ for (tree ca = DECL_CONTRACTS (fndecl); ca; ca = CONTRACT_CHAIN (ca))
+ {
+ tree contract = CONTRACT_STATEMENT (ca);
+ if (!CONTRACT_CONDITION (contract)
+ || CONTRACT_CONDITION_DEFERRED_P (contract)
+ || CONTRACT_CONDITION (contract) == error_mark_node)
+ return;
+ }
+
+ int flags = SF_DEFAULT | SF_PRE_PARSED;
+
+ /* If either the pre or post functions are bad, don't bother emitting
+ any contracts. The program is already ill-formed. */
+ tree pre = DECL_PRE_FN (fndecl);
+ tree post = DECL_POST_FN (fndecl);
+ if (pre == error_mark_node || post == error_mark_node)
+ return;
+
+ if (pre && DECL_INITIAL (fndecl) != error_mark_node)
+ {
+ DECL_PENDING_INLINE_P (pre) = false;
+ start_preparsed_function (pre, DECL_ATTRIBUTES (pre), flags);
+ remap_and_emit_conditions (fndecl, pre, PRECONDITION_STMT);
+ tree finished_pre = finish_function (false);
+ expand_or_defer_fn (finished_pre);
+ }
+
+ if (post && DECL_INITIAL (fndecl) != error_mark_node)
+ {
+ DECL_PENDING_INLINE_P (post) = false;
+ start_preparsed_function (post,
+ DECL_ATTRIBUTES (post),
+ flags);
+ remap_and_emit_conditions (fndecl, post, POSTCONDITION_STMT);
+ if (!VOID_TYPE_P (TREE_TYPE (TREE_TYPE (post))))
+ finish_return_stmt (get_postcondition_result_parameter (fndecl));
+
+ tree finished_post = finish_function (false);
+ expand_or_defer_fn (finished_post);
+ }
+}
+
+/* Rewrite the expression of a returned expression so that it invokes the
+ postcondition function as needed. */
+
+tree
+apply_postcondition_to_return (tree expr)
+{
+ tree fn = current_function_decl;
+ tree post = DECL_POST_FN (fn);
+ if (!post)
+ return NULL_TREE;
+
+ /* If FN returns in memory, POST has a void return type and we call it when
+ EXPR is DECL_RESULT (fn). If FN returns a scalar, POST has the same
+ return type and we call it when EXPR is the value being returned. */
+ if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (post)))
+ != (expr == DECL_RESULT (fn)))
+ return NULL_TREE;
+
+ releasing_vec args = build_arg_list (fn);
+ if (get_postcondition_result_parameter (fn))
+ vec_safe_push (args, expr);
+ tree call = build_call_a (post,
+ args->length (),
+ args->address ());
+ CALL_FROM_THUNK_P (call) = true;
+
+ return call;
+}
+
+/* A subroutine of duplicate_decls. Diagnose issues in the redeclaration of
+ guarded functions. */
+
+void
+duplicate_contracts (tree newdecl, tree olddecl)
+{
+ if (TREE_CODE (newdecl) == TEMPLATE_DECL)
+ newdecl = DECL_TEMPLATE_RESULT (newdecl);
+ if (TREE_CODE (olddecl) == TEMPLATE_DECL)
+ olddecl = DECL_TEMPLATE_RESULT (olddecl);
+
+ /* Compare contracts to see if they match. */
+ tree old_contracts = DECL_CONTRACTS (olddecl);
+ tree new_contracts = DECL_CONTRACTS (newdecl);
+
+ if (!old_contracts && !new_contracts)
+ return;
+
+ location_t old_loc = DECL_SOURCE_LOCATION (olddecl);
+ location_t new_loc = DECL_SOURCE_LOCATION (newdecl);
+
+ /* If both declarations specify contracts, ensure they match.
+
+ TODO: This handles a potential error a little oddly. Consider:
+
+ struct B {
+ virtual void f(int n) [[pre: n == 0]];
+ };
+ struct D : B {
+ void f(int n) override; // inherits contracts
+ };
+ void D::f(int n) [[pre: n == 0]] // OK
+ { }
+
+ It's okay because we're explicitly restating the inherited contract.
+ Changing the precondition on the definition D::f causes match_contracts
+ to complain about the mismatch.
+
+ This would previously have been diagnosed as adding contracts to an
+ override, but this seems like it should be well-formed. */
+ if (old_contracts && new_contracts)
+ {
+ if (!match_contract_conditions (old_loc, old_contracts,
+ new_loc, new_contracts,
+ cmc_declaration))
+ return;
+ if (DECL_UNIQUE_FRIEND_P (newdecl))
+ /* Newdecl's contracts are still DEFERRED_PARSE, and we're about to
+ collapse it into olddecl, so stash away olddecl's contracts for
+ later comparison. */
+ defer_guarded_contract_match (olddecl, olddecl, old_contracts);
+ }
+
+ /* Handle cases where contracts are omitted in one or the other
+ declaration. */
+ if (old_contracts)
+ {
+ /* Contracts have been previously specified by are no omitted. The
+ new declaration inherits the existing contracts. */
+ if (!new_contracts)
+ copy_contract_attributes (newdecl, olddecl);
+
+ /* In all cases, remove existing contracts from OLDDECL to prevent the
+ attribute merging function from adding excess contracts. */
+ remove_contract_attributes (olddecl);
+ }
+ else if (!old_contracts)
+ {
+ /* We are adding contracts to a declaration. */
+ if (new_contracts)
+ {
+ /* We can't add to a previously defined function. */
+ if (DECL_INITIAL (olddecl))
+ {
+ auto_diagnostic_group d;
+ error_at (new_loc, "cannot add contracts after definition");
+ inform (DECL_SOURCE_LOCATION (olddecl), "original definition here");
+ return;
+ }
+
+ /* We can't add to an unguarded virtual function declaration. */
+ if (DECL_VIRTUAL_P (olddecl) && new_contracts)
+ {
+ auto_diagnostic_group d;
+ error_at (new_loc, "cannot add contracts to a virtual function");
+ inform (DECL_SOURCE_LOCATION (olddecl), "original declaration here");
+ return;
+ }
+
+ /* Depending on the "first declaration" rule, we may not be able
+ to add contracts to a function after the fact. */
+ if (flag_contract_strict_declarations)
+ {
+ warning_at (new_loc,
+ OPT_fcontract_strict_declarations_,
+ "declaration adds contracts to %q#D",
+ olddecl);
+ return;
+ }
+
+ /* Copy the contracts from NEWDECL to OLDDECL. We shouldn't need to
+ remap them because NEWDECL's parameters will replace those of
+ OLDDECL. Remove the contracts from NEWDECL so they aren't
+ cloned when merging. */
+ copy_contract_attributes (olddecl, newdecl);
+ remove_contract_attributes (newdecl);
+ }
+ }
+}
+
+/* Replace the any contract attributes on OVERRIDER with a copy where any
+ references to BASEFN's PARM_DECLs have been rewritten to the corresponding
+ PARM_DECL in OVERRIDER. */
+
+void
+inherit_base_contracts (tree overrider, tree basefn)
+{
+ tree last = NULL_TREE, contract_attrs = NULL_TREE;
+ for (tree a = DECL_CONTRACTS (basefn);
+ a != NULL_TREE;
+ a = CONTRACT_CHAIN (a))
+ {
+ tree c = copy_node (a);
+ TREE_VALUE (c) = build_tree_list (TREE_PURPOSE (TREE_VALUE (c)),
+ copy_node (CONTRACT_STATEMENT (c)));
+
+ tree src = basefn;
+ tree dst = overrider;
+ remap_contract (src, dst, CONTRACT_STATEMENT (c), /*duplicate_p=*/true);
+
+ CONTRACT_COMMENT (CONTRACT_STATEMENT (c)) =
+ copy_node (CONTRACT_COMMENT (CONTRACT_STATEMENT (c)));
+
+ chainon (last, c);
+ last = c;
+ if (!contract_attrs)
+ contract_attrs = c;
+ }
+
+ set_decl_contracts (overrider, contract_attrs);
+}
+
+#include "gt-cp-contracts.h"
diff --git a/gcc/cp/contracts.h b/gcc/cp/contracts.h
new file mode 100644
index 0000000..4050a38
--- /dev/null
+++ b/gcc/cp/contracts.h
@@ -0,0 +1,305 @@
+/* Definitions for C++ contract levels. Implements functionality described in
+ the N4820 working draft version of contracts, P1290, P1332, and P1429.
+ Copyright (C) 2020-2022 Free Software Foundation, Inc.
+ Contributed by Jeff Chapman II (jchapman@lock3software.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_CP_CONTRACT_H
+#define GCC_CP_CONTRACT_H
+
+/* Contract levels approximate the complexity of the expression. */
+
+enum contract_level
+{
+ CONTRACT_INVALID,
+ CONTRACT_DEFAULT,
+ CONTRACT_AUDIT,
+ CONTRACT_AXIOM
+};
+
+/* The concrete semantics determine the behavior of a contract. */
+
+enum contract_semantic
+{
+ CCS_INVALID,
+ CCS_IGNORE,
+ CCS_ASSUME,
+ CCS_NEVER,
+ CCS_MAYBE
+};
+
+/* True if the contract is unchecked. */
+
+inline bool
+unchecked_contract_p (contract_semantic cs)
+{
+ return cs == CCS_IGNORE || cs == CCS_ASSUME;
+}
+
+/* True if the contract is checked. */
+
+inline bool
+checked_contract_p (contract_semantic cs)
+{
+ return cs >= CCS_NEVER;
+}
+
+/* Must match std::contract_violation_continuation_mode in <contract>. */
+enum contract_continuation
+{
+ NEVER_CONTINUE,
+ MAYBE_CONTINUE
+};
+
+/* Assertion role info. */
+struct contract_role
+{
+ const char *name;
+ contract_semantic default_semantic;
+ contract_semantic audit_semantic;
+ contract_semantic axiom_semantic;
+};
+
+/* Information for configured contract semantics. */
+
+struct contract_configuration
+{
+ contract_level level;
+ contract_role* role;
+};
+
+/* A contract mode contains information used to derive the checking
+ and assumption semantics of a contract. This is either a dynamic
+ configuration, meaning it derives from the build mode, or it is
+ explicitly specified. */
+
+struct contract_mode
+{
+ contract_mode () : kind(cm_invalid) {}
+ contract_mode (contract_level level, contract_role *role = NULL)
+ : kind(cm_dynamic)
+ {
+ contract_configuration cc;
+ cc.level = level;
+ cc.role = role;
+ u.config = cc;
+ }
+ contract_mode (contract_semantic semantic) : kind(cm_explicit)
+ {
+ u.semantic = semantic;
+ }
+
+ contract_level get_level () const
+ {
+ gcc_assert (kind == cm_dynamic);
+ return u.config.level;
+ }
+
+ contract_role *get_role () const
+ {
+ gcc_assert (kind == cm_dynamic);
+ return u.config.role;
+ }
+
+ contract_semantic get_semantic () const
+ {
+ gcc_assert (kind == cm_explicit);
+ return u.semantic;
+ }
+
+ enum { cm_invalid, cm_dynamic, cm_explicit } kind;
+
+ union
+ {
+ contract_configuration config;
+ contract_semantic semantic;
+ } u;
+};
+
+extern contract_role *get_contract_role (const char *);
+extern contract_role *add_contract_role (const char *,
+ contract_semantic,
+ contract_semantic,
+ contract_semantic,
+ bool = true);
+extern void validate_contract_role (contract_role *);
+extern void setup_default_contract_role (bool = true);
+extern contract_semantic lookup_concrete_semantic (const char *);
+
+/* Map a source level semantic or level name to its value, or invalid. */
+extern contract_semantic map_contract_semantic (const char *);
+extern contract_level map_contract_level (const char *);
+
+/* Check if an attribute is a cxx contract attribute. */
+extern bool cxx_contract_attribute_p (const_tree);
+extern bool cp_contract_assertion_p (const_tree);
+
+/* Returns the default role. */
+
+inline contract_role *
+get_default_contract_role ()
+{
+ return get_contract_role ("default");
+}
+
+/* Handle various command line arguments related to semantic mapping. */
+extern void handle_OPT_fcontract_build_level_ (const char *);
+extern void handle_OPT_fcontract_assumption_mode_ (const char *);
+extern void handle_OPT_fcontract_continuation_mode_ (const char *);
+extern void handle_OPT_fcontract_role_ (const char *);
+extern void handle_OPT_fcontract_semantic_ (const char *);
+
+enum contract_matching_context
+{
+ cmc_declaration,
+ cmc_override
+};
+
+/* True if NODE is any kind of contract. */
+#define CONTRACT_P(NODE) \
+ (TREE_CODE (NODE) == ASSERTION_STMT \
+ || TREE_CODE (NODE) == PRECONDITION_STMT \
+ || TREE_CODE (NODE) == POSTCONDITION_STMT)
+
+/* True if NODE is a contract condition. */
+#define CONTRACT_CONDITION_P(NODE) \
+ (TREE_CODE (NODE) == PRECONDITION_STMT \
+ || TREE_CODE (NODE) == POSTCONDITION_STMT)
+
+/* True if NODE is a precondition. */
+#define PRECONDITION_P(NODE) \
+ (TREE_CODE (NODE) == PRECONDITION_STMT)
+
+/* True if NODE is a postcondition. */
+#define POSTCONDITION_P(NODE) \
+ (TREE_CODE (NODE) == POSTCONDITION_STMT)
+
+#define CONTRACT_CHECK(NODE) \
+ (TREE_CHECK3 (NODE, ASSERTION_STMT, PRECONDITION_STMT, POSTCONDITION_STMT))
+
+/* True iff the FUNCTION_DECL NODE currently has any contracts. */
+#define DECL_HAS_CONTRACTS_P(NODE) \
+ (DECL_CONTRACTS (NODE) != NULL_TREE)
+
+/* For a FUNCTION_DECL of a guarded function, this points to a list of the pre
+ and post contracts of the first decl of NODE in original order. */
+#define DECL_CONTRACTS(NODE) \
+ (find_contract (DECL_ATTRIBUTES (NODE)))
+
+/* The next contract (if any) after this one in an attribute list. */
+#define CONTRACT_CHAIN(NODE) \
+ (find_contract (TREE_CHAIN (NODE)))
+
+/* The wrapper of the original source location of a list of contracts. */
+#define CONTRACT_SOURCE_LOCATION_WRAPPER(NODE) \
+ (TREE_PURPOSE (TREE_VALUE (NODE)))
+
+/* The original source location of a list of contracts. */
+#define CONTRACT_SOURCE_LOCATION(NODE) \
+ (EXPR_LOCATION (CONTRACT_SOURCE_LOCATION_WRAPPER (NODE)))
+
+/* The actual code _STMT for a contract attribute. */
+#define CONTRACT_STATEMENT(NODE) \
+ (TREE_VALUE (TREE_VALUE (NODE)))
+
+/* True if the contract semantic was specified literally. If true, the
+ contract mode is an identifier containing the semantic. Otherwise,
+ it is a TREE_LIST whose TREE_VALUE is the level and whose TREE_PURPOSE
+ is the role. */
+#define CONTRACT_LITERAL_MODE_P(NODE) \
+ (CONTRACT_MODE (NODE) != NULL_TREE \
+ && TREE_CODE (CONTRACT_MODE (NODE)) == IDENTIFIER_NODE)
+
+/* The identifier denoting the literal semantic of the contract. */
+#define CONTRACT_LITERAL_SEMANTIC(NODE) \
+ (TREE_OPERAND (NODE, 0))
+
+/* The written "mode" of the contract. Either an IDENTIFIER with the
+ literal semantic or a TREE_LIST containing the level and role. */
+#define CONTRACT_MODE(NODE) \
+ (TREE_OPERAND (CONTRACT_CHECK (NODE), 0))
+
+/* The identifier denoting the build level of the contract. */
+#define CONTRACT_LEVEL(NODE) \
+ (TREE_VALUE (CONTRACT_MODE (NODE)))
+
+/* The identifier denoting the role of the contract */
+#define CONTRACT_ROLE(NODE) \
+ (TREE_PURPOSE (CONTRACT_MODE (NODE)))
+
+/* The parsed condition of the contract. */
+#define CONTRACT_CONDITION(NODE) \
+ (TREE_OPERAND (CONTRACT_CHECK (NODE), 1))
+
+/* True iff the condition of the contract NODE is not yet parsed. */
+#define CONTRACT_CONDITION_DEFERRED_P(NODE) \
+ (TREE_CODE (CONTRACT_CONDITION (NODE)) == DEFERRED_PARSE)
+
+/* The raw comment of the contract. */
+#define CONTRACT_COMMENT(NODE) \
+ (TREE_OPERAND (CONTRACT_CHECK (NODE), 2))
+
+/* The VAR_DECL of a postcondition result. For deferred contracts, this
+ is an IDENTIFIER. */
+#define POSTCONDITION_IDENTIFIER(NODE) \
+ (TREE_OPERAND (POSTCONDITION_STMT_CHECK (NODE), 3))
+
+/* For a FUNCTION_DECL of a guarded function, this holds the function decl
+ where pre contract checks are emitted. */
+#define DECL_PRE_FN(NODE) \
+ (get_precondition_function ((NODE)))
+
+/* For a FUNCTION_DECL of a guarded function, this holds the function decl
+ where post contract checks are emitted. */
+#define DECL_POST_FN(NODE) \
+ (get_postcondition_function ((NODE)))
+
+/* True iff the FUNCTION_DECL is the pre function for a guarded function. */
+#define DECL_IS_PRE_FN_P(NODE) \
+ (DECL_ABSTRACT_ORIGIN (NODE) && DECL_PRE_FN (DECL_ABSTRACT_ORIGIN (NODE)) == NODE)
+
+/* True iff the FUNCTION_DECL is the post function for a guarded function. */
+#define DECL_IS_POST_FN_P(NODE) \
+ (DECL_ABSTRACT_ORIGIN (NODE) && DECL_POST_FN (DECL_ABSTRACT_ORIGIN (NODE)) == NODE)
+
+extern void remove_contract_attributes (tree);
+extern void copy_contract_attributes (tree, tree);
+extern void remap_contracts (tree, tree, tree, bool);
+extern void maybe_update_postconditions (tree);
+extern void rebuild_postconditions (tree);
+extern bool check_postcondition_result (tree, tree, location_t);
+extern tree get_precondition_function (tree);
+extern tree get_postcondition_function (tree);
+extern void duplicate_contracts (tree, tree);
+extern void match_deferred_contracts (tree);
+extern void defer_guarded_contract_match (tree, tree, tree);
+extern bool diagnose_misapplied_contracts (tree);
+extern tree finish_contract_attribute (tree, tree);
+extern tree invalidate_contract (tree);
+extern void update_late_contract (tree, tree, tree);
+extern tree splice_out_contracts (tree);
+extern bool all_attributes_are_contracts_p (tree);
+extern void inherit_base_contracts (tree, tree);
+extern tree apply_postcondition_to_return (tree);
+extern void start_function_contracts (tree);
+extern void finish_function_contracts (tree);
+extern void set_contract_functions (tree, tree, tree);
+extern tree build_contract_check (tree);
+extern void emit_assertion (tree);
+
+#endif /* ! GCC_CP_CONTRACT_H */
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 01a3e83..3f23317 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -2685,6 +2685,7 @@ find_interesting_subtree (tree *expr_p, int *dosub, void *d)
}
}
else if (tmp_target_expr_p (expr)
+ && !TARGET_EXPR_ELIDING_P (expr)
&& !p->temps_used->contains (expr))
{
p->entry = expr_p;
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index cc8bfad..983f2a5 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -1427,6 +1427,23 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
wtd->bind_expr_stack.pop ();
break;
+ case ASSERTION_STMT:
+ case PRECONDITION_STMT:
+ case POSTCONDITION_STMT:
+ {
+ if (tree check = build_contract_check (stmt))
+ {
+ *stmt_p = check;
+ return cp_genericize_r (stmt_p, walk_subtrees, data);
+ }
+
+ /* If we didn't build a check, replace it with void_node so we don't
+ leak contracts into GENERIC. */
+ *stmt_p = void_node;
+ *walk_subtrees = 0;
+ }
+ break;
+
case USING_STMT:
{
tree block = NULL_TREE;
diff --git a/gcc/cp/cp-lang.cc b/gcc/cp/cp-lang.cc
index c3cfde5..a3f29ed 100644
--- a/gcc/cp/cp-lang.cc
+++ b/gcc/cp/cp-lang.cc
@@ -116,8 +116,7 @@ tree
objcp_tsubst_copy_and_build (tree /*t*/,
tree /*args*/,
tsubst_flags_t /*complain*/,
- tree /*in_decl*/,
- bool /*function_p*/)
+ tree /*in_decl*/)
{
return NULL_TREE;
}
diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc
index e4df30d..6ed3826 100644
--- a/gcc/cp/cp-objcp-common.cc
+++ b/gcc/cp/cp-objcp-common.cc
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "cp-objcp-common.h"
#include "dwarf2.h"
#include "stringpool.h"
+#include "contracts.h"
/* Special routine to get the alias set for C++. */
@@ -86,6 +87,9 @@ cp_tree_size (enum tree_code code)
case CONSTRAINT_INFO: return sizeof (tree_constraint_info);
case USERDEF_LITERAL: return sizeof (tree_userdef_literal);
case TEMPLATE_DECL: return sizeof (tree_template_decl);
+ case ASSERTION_STMT: return sizeof (tree_exp);
+ case PRECONDITION_STMT: return sizeof (tree_exp);
+ case POSTCONDITION_STMT: return sizeof (tree_exp);
default:
switch (TREE_CODE_CLASS (code))
{
@@ -473,7 +477,6 @@ cp_common_init_ts (void)
/* New decls. */
MARK_TS_DECL_COMMON (TEMPLATE_DECL);
MARK_TS_DECL_COMMON (WILDCARD_DECL);
- MARK_TS_DECL_COMMON (CONCEPT_DECL);
MARK_TS_DECL_NON_COMMON (USING_DECL);
@@ -565,6 +568,10 @@ cp_common_init_ts (void)
MARK_TS_EXP (CO_YIELD_EXPR);
MARK_TS_EXP (CO_RETURN_EXPR);
+ MARK_TS_EXP (ASSERTION_STMT);
+ MARK_TS_EXP (PRECONDITION_STMT);
+ MARK_TS_EXP (POSTCONDITION_STMT);
+
c_common_init_ts ();
}
@@ -577,6 +584,39 @@ cp_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
{
if (handle_module_option (unsigned (scode), arg, value))
return true;
+
+ enum opt_code code = (enum opt_code) scode;
+ bool handled_p = true;
+
+ switch (code)
+ {
+ case OPT_fcontract_build_level_:
+ handle_OPT_fcontract_build_level_ (arg);
+ break;
+
+ case OPT_fcontract_assumption_mode_:
+ handle_OPT_fcontract_assumption_mode_ (arg);
+ break;
+
+ case OPT_fcontract_continuation_mode_:
+ handle_OPT_fcontract_continuation_mode_ (arg);
+ break;
+
+ case OPT_fcontract_role_:
+ handle_OPT_fcontract_role_ (arg);
+ break;
+
+ case OPT_fcontract_semantic_:
+ handle_OPT_fcontract_semantic_ (arg);
+ break;
+
+ default:
+ handled_p = false;
+ break;
+ }
+ if (handled_p)
+ return handled_p;
+
return c_common_handle_option (scode, arg, value, kind, loc, handlers);
}
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index 1a67f14..f4ba0c9 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -24,8 +24,7 @@ along with GCC; see the file COPYING3. If not see
/* In cp/objcp-common.c, cp/cp-lang.cc and objcp/objcp-lang.cc. */
extern tree cp_get_debug_type (const_tree);
-extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t,
- tree, bool);
+extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t, tree);
extern int cp_decl_dwarf_attribute (const_tree, int);
extern int cp_type_dwarf_attribute (const_tree, int);
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index f83b4c5..d8aab10 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -495,11 +495,6 @@ DEFTREECODE (OMP_DEPOBJ, "omp_depobj", tcc_statement, 2)
/* Extensions for Concepts. */
-/* Concept definition. This is not entirely different than a VAR_DECL
- except that a) it must be a template, and b) doesn't have the wide
- range of value and linkage options available to variables. */
-DEFTREECODE (CONCEPT_DECL, "concept_decl", tcc_declaration, 0)
-
/* Used to represent information associated with constrained declarations. */
DEFTREECODE (CONSTRAINT_INFO, "constraint_info", tcc_exceptional, 0)
@@ -587,6 +582,17 @@ DEFTREECODE (CO_YIELD_EXPR, "co_yield", tcc_expression, 2)
DEFTREECODE (CO_RETURN_EXPR, "co_return", tcc_statement, 2)
+/* Different flavors of contracts.
+
+ Assertions and preconditions have two operands: a node containing
+ the their mode and condition. Postconditions have an additional
+ operand to store the optional name for the result value.
+
+ CONTRACT_SEMANTIC has the computed behavior of the contract. */
+DEFTREECODE (ASSERTION_STMT, "assertion_stmt", tcc_statement, 3)
+DEFTREECODE (PRECONDITION_STMT, "precondition_stmt", tcc_statement, 3)
+DEFTREECODE (POSTCONDITION_STMT, "postcondition_stmt", tcc_statement, 4)
+
/*
Local variables:
mode:c
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4c0bacb..0d6c234 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "hard-reg-set.h"
#include "function.h"
#include "tristate.h"
+#include "contracts.h"
/* In order for the format checking to accept the C++ front end
diagnostic framework extensions, you must include this file before
@@ -232,6 +233,8 @@ enum cp_tree_index
CPTI_DSO_HANDLE,
CPTI_DCAST,
+ CPTI_PSEUDO_CONTRACT_VIOLATION,
+
CPTI_SOURCE_LOCATION_IMPL,
CPTI_FALLBACK_DFLOAT32_TYPE,
@@ -266,6 +269,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
#define current_aggr cp_global_trees[CPTI_AGGR_TAG]
/* std::align_val_t */
#define align_type_node cp_global_trees[CPTI_ALIGN_TYPE]
+#define pseudo_contract_violation_type cp_global_trees[CPTI_PSEUDO_CONTRACT_VIOLATION]
/* We cache these tree nodes so as to call get_identifier less frequently.
For identifiers for functions, including special member functions such
@@ -455,6 +459,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
ALIGNOF_EXPR_STD_P (in ALIGNOF_EXPR)
OVL_DEDUP_P (in OVERLOAD)
ATOMIC_CONSTR_MAP_INSTANTIATED_P (in ATOMIC_CONSTR)
+ contract_semantic (in ASSERTION_, PRECONDITION_, POSTCONDITION_STMT)
1: IDENTIFIER_KIND_BIT_1 (in IDENTIFIER_NODE)
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
@@ -493,6 +498,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
LAMBDA_EXPR_CAPTURE_OPTIMIZED (in LAMBDA_EXPR)
IMPLICIT_CONV_EXPR_BRACED_INIT (in IMPLICIT_CONV_EXPR)
PACK_EXPANSION_AUTO_P (in *_PACK_EXPANSION)
+ contract_semantic (in ASSERTION_, PRECONDITION_, POSTCONDITION_STMT)
3: IMPLICIT_RVALUE_P (in NON_LVALUE_EXPR or STATIC_CAST_EXPR)
ICS_BAD_FLAG (in _CONV)
FN_TRY_BLOCK_P (in TRY_BLOCK)
@@ -505,6 +511,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
PACK_EXPANSION_FORCE_EXTRA_ARGS_P (in *_PACK_EXPANSION)
LAMBDA_EXPR_STATIC_P (in LAMBDA_EXPR)
TARGET_EXPR_ELIDING_P (in TARGET_EXPR)
+ contract_semantic (in ASSERTION_, PRECONDITION_, POSTCONDITION_STMT)
4: IDENTIFIER_MARKED (IDENTIFIER_NODEs)
TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
CALL_EXPR, or FIELD_DECL).
@@ -1501,9 +1508,12 @@ enum cp_lambda_default_capture_mode_type {
(((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->extra_scope)
/* Lambdas in the same extra scope might need a discriminating count.
- This is a single per-scope count. */
+ For ABI 17, we have single per-scope count, for ABI 18, we have
+ per-scope, per-signature numbering. */
#define LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR(NODE) \
(((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->discriminator_scope)
+#define LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR(NODE) \
+ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->discriminator_sig)
/* During parsing of the lambda, a vector of capture proxies which need
to be pushed once we're done processing a nested lambda. */
@@ -1533,6 +1543,7 @@ struct GTY (()) tree_lambda_expr
location_t locus;
enum cp_lambda_default_capture_mode_type default_capture_mode : 2;
unsigned discriminator_scope : 15; // Per-scope discriminator
+ unsigned discriminator_sig : 15; // Per-scope, per-signature discriminator
};
/* Non-zero if this template specialization has access violations that
@@ -1859,6 +1870,7 @@ struct GTY(()) saved_scope {
int x_processing_template_decl;
int x_processing_specialization;
int x_processing_constraint;
+ int x_processing_contract_condition;
int suppress_location_wrappers;
BOOL_BITFIELD x_processing_explicit_instantiation : 1;
BOOL_BITFIELD need_pop_function_context : 1;
@@ -1933,6 +1945,12 @@ extern GTY(()) struct saved_scope *scope_chain;
#define processing_specialization scope_chain->x_processing_specialization
#define processing_explicit_instantiation scope_chain->x_processing_explicit_instantiation
+/* Nonzero if we are parsing the conditional expression of a contract
+ condition. These expressions appear outside the paramter list (like a
+ trailing return type), but are potentially evaluated. */
+
+#define processing_contract_condition scope_chain->x_processing_contract_condition
+
#define in_discarded_stmt scope_chain->discarded_stmt
#define in_consteval_if_p scope_chain->consteval_if_p
@@ -5647,6 +5665,11 @@ extern int comparing_specializations;
FIXME we should always do this except during deduction/ordering. */
extern int comparing_dependent_aliases;
+/* Nonzero if we want to consider different member expressions to compare
+ equal if they designate the same entity. This is set when comparing
+ contract conditions of overrides. */
+extern bool comparing_override_contracts;
+
/* In parser.cc. */
/* Nonzero if we are parsing an unevaluated operand: an operand to
@@ -6816,6 +6839,7 @@ extern void note_break_stmt (void);
extern bool note_iteration_stmt_body_start (void);
extern void note_iteration_stmt_body_end (bool);
extern void determine_local_discriminator (tree);
+extern bool fns_correspond (tree, tree);
extern int decls_match (tree, tree, bool = true);
extern bool maybe_version_functions (tree, tree, bool);
extern bool merge_default_template_args (tree, tree, bool);
@@ -7063,6 +7087,7 @@ extern void set_global_friend (tree);
extern bool is_global_friend (tree);
/* in init.cc */
+extern tree find_temps_r (tree *, int *, void *);
extern tree expand_member_init (tree);
extern void emit_mem_initializers (tree);
extern tree build_aggr_init (tree, tree, int,
@@ -7378,10 +7403,8 @@ extern void instantiate_pending_templates (int);
extern tree tsubst_default_argument (tree, int, tree, tree,
tsubst_flags_t);
extern tree tsubst (tree, tree, tsubst_flags_t, tree);
-extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t,
- tree, bool = false, bool = false);
-extern tree tsubst_expr (tree, tree, tsubst_flags_t,
- tree, bool);
+extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t, tree);
+extern tree tsubst_expr (tree, tree, tsubst_flags_t, tree);
extern tree tsubst_pack_expansion (tree, tree, tsubst_flags_t, tree);
extern tree tsubst_argument_pack (tree, tree, tsubst_flags_t, tree);
extern tree tsubst_template_args (tree, tree, tsubst_flags_t, tree);
@@ -7450,8 +7473,10 @@ extern hashval_t iterative_hash_template_arg (tree arg, hashval_t val);
extern tree coerce_template_parms (tree, tree, tree, tsubst_flags_t,
bool = true);
extern tree canonicalize_type_argument (tree, tsubst_flags_t);
+extern void register_local_identity (tree);
extern void register_local_specialization (tree, tree);
extern tree retrieve_local_specialization (tree);
+extern void register_parameter_specializations (tree, tree);
extern tree extract_fnparm_pack (tree, tree *);
extern tree template_parm_to_arg (tree);
extern tree dguide_name (tree);
@@ -7783,6 +7808,7 @@ extern void start_lambda_scope (tree decl);
extern void finish_lambda_scope (void);
extern void record_lambda_scope (tree lambda);
extern void record_lambda_scope_discriminator (tree lambda);
+extern void record_lambda_scope_sig_discriminator (tree lambda, tree fn);
extern tree start_lambda_function (tree fn, tree lambda_expr);
extern void finish_lambda_function (tree body);
extern bool regenerated_lambda_fn_p (tree);
@@ -7976,7 +8002,7 @@ extern bool comp_except_specs (const_tree, const_tree, int);
extern bool comptypes (tree, tree, int);
extern bool same_type_ignoring_top_level_qualifiers_p (tree, tree);
extern bool similar_type_p (tree, tree);
-extern bool next_common_initial_seqence (tree &, tree &);
+extern bool next_common_initial_sequence (tree &, tree &);
extern bool layout_compatible_type_p (tree, tree);
extern bool compparms (const_tree, const_tree);
extern int comp_cv_qualification (const_tree, const_tree);
@@ -8318,7 +8344,7 @@ struct diagnosing_failed_constraint
extern cp_expr finish_constraint_or_expr (location_t, cp_expr, cp_expr);
extern cp_expr finish_constraint_and_expr (location_t, cp_expr, cp_expr);
extern cp_expr finish_constraint_primary_expr (cp_expr);
-extern tree finish_concept_definition (cp_expr, tree);
+extern tree finish_concept_definition (cp_expr, tree, tree);
extern tree combine_constraint_expressions (tree, tree);
extern tree append_constraint (tree, tree);
extern tree get_constraints (const_tree);
@@ -8393,12 +8419,18 @@ struct atom_hasher : default_hash_traits<tree>
{
static hashval_t hash (tree t)
{
- return hash_atomic_constraint (t);
+ ++comparing_specializations;
+ hashval_t val = hash_atomic_constraint (t);
+ --comparing_specializations;
+ return val;
}
static bool equal (tree t1, tree t2)
{
- return atomic_constraints_identical_p (t1, t2);
+ ++comparing_specializations;
+ bool eq = atomic_constraints_identical_p (t1, t2);
+ --comparing_specializations;
+ return eq;
}
};
@@ -8441,11 +8473,13 @@ extern bool is_rvalue_constant_expression (tree);
extern bool is_nondependent_constant_expression (tree);
extern bool is_nondependent_static_init_expression (tree);
extern bool is_static_init_expression (tree);
+extern bool is_std_allocator (tree);
extern bool potential_rvalue_constant_expression (tree);
extern bool require_potential_constant_expression (tree);
extern bool require_constant_expression (tree);
extern bool require_rvalue_constant_expression (tree);
extern bool require_potential_rvalue_constant_expression (tree);
+extern bool require_potential_rvalue_constant_expression_fncheck (tree);
extern tree cxx_constant_value (tree, tree = NULL_TREE,
tsubst_flags_t = tf_error);
inline tree cxx_constant_value (tree t, tsubst_flags_t complain)
@@ -8521,6 +8555,49 @@ extern tree coro_get_actor_function (tree);
extern tree coro_get_destroy_function (tree);
extern tree coro_get_ramp_function (tree);
+/* contracts.cc */
+extern tree make_postcondition_variable (cp_expr);
+extern tree make_postcondition_variable (cp_expr, tree);
+extern tree grok_contract (tree, tree, tree, cp_expr, location_t);
+extern tree finish_contract_condition (cp_expr);
+
+/* Return the first contract in ATTRS, or NULL_TREE if there are none. */
+
+inline tree
+find_contract (tree attrs)
+{
+ while (attrs && !cxx_contract_attribute_p (attrs))
+ attrs = TREE_CHAIN (attrs);
+ return attrs;
+}
+
+inline void
+set_decl_contracts (tree decl, tree contract_attrs)
+{
+ remove_contract_attributes (decl);
+ DECL_ATTRIBUTES (decl) = chainon (DECL_ATTRIBUTES (decl), contract_attrs);
+}
+
+/* Returns the computed semantic of the node. */
+
+inline contract_semantic
+get_contract_semantic (const_tree t)
+{
+ return (contract_semantic) (TREE_LANG_FLAG_3 (CONTRACT_CHECK (t))
+ | (TREE_LANG_FLAG_2 (t) << 1)
+ | (TREE_LANG_FLAG_0 ((t)) << 2));
+}
+
+/* Sets the computed semantic of the node. */
+
+inline void
+set_contract_semantic (tree t, contract_semantic semantic)
+{
+ TREE_LANG_FLAG_3 (CONTRACT_CHECK (t)) = semantic & 0x01;
+ TREE_LANG_FLAG_2 (t) = (semantic & 0x02) >> 1;
+ TREE_LANG_FLAG_0 (t) = (semantic & 0x04) >> 2;
+}
+
/* Inline bodies. */
inline tree
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 6e98ea3..5081563 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -956,9 +956,7 @@ static bool
function_requirements_equivalent_p (tree newfn, tree oldfn)
{
/* In the concepts TS, the combined constraints are compared. */
- if (cxx_dialect < cxx20
- && (DECL_TEMPLATE_SPECIALIZATION (newfn)
- <= DECL_TEMPLATE_SPECIALIZATION (oldfn)))
+ if (cxx_dialect < cxx20)
{
tree ci1 = get_constraints (oldfn);
tree ci2 = get_constraints (newfn);
@@ -980,6 +978,72 @@ function_requirements_equivalent_p (tree newfn, tree oldfn)
return cp_tree_equal (reqs1, reqs2);
}
+/* Two functions of the same name correspond [basic.scope.scope] if
+
+ + both declare functions with the same non-object-parameter-type-list,
+ equivalent ([temp.over.link]) trailing requires-clauses (if any, except as
+ specified in [temp.friend]), and, if both are non-static members, they have
+ corresponding object parameters, or
+
+ + both declare function templates with equivalent
+ non-object-parameter-type-lists, return types (if any), template-heads, and
+ trailing requires-clauses (if any), and, if both are non-static members,
+ they have corresponding object parameters.
+
+ This is a subset of decls_match: it identifies declarations that cannot be
+ overloaded with one another. This function does not consider DECL_NAME. */
+
+bool
+fns_correspond (tree newdecl, tree olddecl)
+{
+ if (TREE_CODE (newdecl) != TREE_CODE (olddecl))
+ return false;
+
+ if (TREE_CODE (newdecl) == TEMPLATE_DECL)
+ {
+ if (!template_heads_equivalent_p (newdecl, olddecl))
+ return 0;
+ newdecl = DECL_TEMPLATE_RESULT (newdecl);
+ olddecl = DECL_TEMPLATE_RESULT (olddecl);
+ }
+
+ tree f1 = TREE_TYPE (newdecl);
+ tree f2 = TREE_TYPE (olddecl);
+
+ int rq1 = type_memfn_rqual (f1);
+ int rq2 = type_memfn_rqual (f2);
+
+ /* If only one is a non-static member function, ignore ref-quals. */
+ if (TREE_CODE (f1) != TREE_CODE (f2))
+ rq1 = rq2;
+ /* Two non-static member functions have corresponding object parameters if:
+ + exactly one is an implicit object member function with no ref-qualifier
+ and the types of their object parameters ([dcl.fct]), after removing
+ top-level references, are the same, or
+ + their object parameters have the same type. */
+ /* ??? We treat member functions of different classes as corresponding even
+ though that means the object parameters have different types. */
+ else if ((rq1 == REF_QUAL_NONE) != (rq2 == REF_QUAL_NONE))
+ rq1 = rq2;
+
+ bool types_match = rq1 == rq2;
+
+ if (types_match)
+ {
+ tree p1 = FUNCTION_FIRST_USER_PARMTYPE (newdecl);
+ tree p2 = FUNCTION_FIRST_USER_PARMTYPE (olddecl);
+ types_match = compparms (p1, p2);
+ }
+
+ /* Two function declarations match if either has a requires-clause
+ then both have a requires-clause and their constraints-expressions
+ are equivalent. */
+ if (types_match && flag_concepts)
+ types_match = function_requirements_equivalent_p (newdecl, olddecl);
+
+ return types_match;
+}
+
/* Subroutine of duplicate_decls: return truthvalue of whether
or not types of these decls match.
@@ -2202,6 +2266,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
= DECL_OVERLOADED_OPERATOR_CODE_RAW (olddecl);
new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;
+ duplicate_contracts (newdecl, olddecl);
+
/* Optionally warn about more than one declaration for the same
name, but don't warn about a function declaration followed by a
definition. */
@@ -2275,6 +2341,13 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
specializations. */
gcc_assert (!DECL_TEMPLATE_SPECIALIZATIONS (newdecl));
+ /* Make sure the contracts are equivalent. */
+ duplicate_contracts (newdecl, olddecl);
+
+ /* Remove contracts from old_result so they aren't appended to
+ old_result by the merge function. */
+ remove_contract_attributes (old_result);
+
DECL_ATTRIBUTES (old_result)
= (*targetm.merge_decl_attributes) (old_result, new_result);
@@ -2797,11 +2870,23 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
}
if (! types_match || new_defines_function)
{
+ /* These are the final DECL_ARGUMENTS that will be used within the
+ body; update any references to old DECL_ARGUMENTS in the
+ contracts, if present. */
+ if (tree contracts = DECL_CONTRACTS (newdecl))
+ remap_contracts (olddecl, newdecl, contracts, true);
+
/* These need to be copied so that the names are available.
Note that if the types do match, we'll preserve inline
info and other bits, but if not, we won't. */
DECL_ARGUMENTS (olddecl) = DECL_ARGUMENTS (newdecl);
DECL_RESULT (olddecl) = DECL_RESULT (newdecl);
+
+ /* In some cases, duplicate_contracts will remove contracts from
+ OLDDECL, to avoid duplications. Sometimes, the contracts end up
+ shared. If we removed them, re-add them. */
+ if (!DECL_CONTRACTS (olddecl))
+ copy_contract_attributes (olddecl, newdecl);
}
/* If redeclaring a builtin function, it stays built in
if newdecl is a gnu_inline definition, or if newdecl is just
@@ -2845,7 +2930,38 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
/* Don't clear out the arguments if we're just redeclaring a
function. */
if (DECL_ARGUMENTS (olddecl))
- DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
+ {
+ /* If we removed contracts from previous definition, re-attach
+ them. Otherwise, rewrite the contracts so they match the
+ parameters of the new declaration. */
+ if (DECL_INITIAL (olddecl)
+ && DECL_CONTRACTS (newdecl)
+ && !DECL_CONTRACTS (olddecl))
+ copy_contract_attributes (olddecl, newdecl);
+ else
+ {
+ /* Temporarily undo the re-contexting of parameters so we can
+ actually remap parameters. The inliner won't replace
+ parameters if we don't do this. */
+ tree args = DECL_ARGUMENTS (newdecl);
+ for (tree p = args; p; p = DECL_CHAIN (p))
+ DECL_CONTEXT (p) = newdecl;
+
+ /* Save new argument names for use in contracts parsing,
+ unless we've already started parsing the body of olddecl
+ (particular issues arise when newdecl is from a prior
+ friend decl with no argument names, see
+ modules/contracts-tpl-friend-1). */
+ if (tree contracts = DECL_CONTRACTS (olddecl))
+ remap_contracts (newdecl, olddecl, contracts, true);
+
+ /* And reverse this operation again. */
+ for (tree p = args; p; p = DECL_CHAIN (p))
+ DECL_CONTEXT (p) = olddecl;
+ }
+
+ DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
+ }
}
}
else if (TREE_CODE (newdecl) == NAMESPACE_DECL)
@@ -5456,6 +5572,12 @@ check_tag_decl (cp_decl_specifier_seq *declspecs,
warn_misplaced_attr_for_class_type (loc, declared_type);
}
+ /* Diagnose invalid application of contracts, if any. */
+ if (find_contract (declspecs->attributes))
+ diagnose_misapplied_contracts (declspecs->attributes);
+ else
+ diagnose_misapplied_contracts (declspecs->std_attributes);
+
return declared_type;
}
@@ -5747,9 +5869,16 @@ start_decl (const cp_declarator *declarator,
if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl)
/* Aliases are definitions. */
&& !alias)
- permerror (declarator->id_loc,
- "declaration of %q#D outside of class is not definition",
- decl);
+ {
+ if (DECL_VIRTUAL_P (decl) || !flag_contracts)
+ permerror (declarator->id_loc,
+ "declaration of %q#D outside of class is not definition",
+ decl);
+ else if (flag_contract_strict_declarations)
+ warning_at (declarator->id_loc, OPT_fcontract_strict_declarations_,
+ "declaration of %q#D outside of class is not definition",
+ decl);
+ }
}
/* Create a DECL_LANG_SPECIFIC so that DECL_DECOMPOSITION_P works. */
@@ -10531,6 +10660,9 @@ grokfndecl (tree ctype,
*attrlist = NULL_TREE;
}
+ if (DECL_HAS_CONTRACTS_P (decl))
+ rebuild_postconditions (decl);
+
/* Check main's type after attributes have been applied. */
if (ctype == NULL_TREE && DECL_MAIN_P (decl))
{
@@ -12598,6 +12730,7 @@ grokdeclarator (const cp_declarator *declarator,
{
if (type != error_mark_node)
{
+ auto_diagnostic_group d;
error_at (loc, "structured binding declaration cannot have "
"type %qT", type);
inform (loc,
@@ -12607,6 +12740,10 @@ grokdeclarator (const cp_declarator *declarator,
type = build_qualified_type (make_auto (), type_quals);
declspecs->type = type;
}
+ else if (PLACEHOLDER_TYPE_CONSTRAINTS_INFO (type))
+ pedwarn (loc, OPT_Wpedantic,
+ "structured binding declaration cannot have constrained "
+ "%<auto%> type %qT", type);
inlinep = 0;
typedef_p = 0;
constexpr_p = 0;
@@ -12731,7 +12868,8 @@ grokdeclarator (const cp_declarator *declarator,
}
}
- if (declspecs->std_attributes)
+ if (declspecs->std_attributes
+ && !diagnose_misapplied_contracts (declspecs->std_attributes))
{
location_t attr_loc = declspecs->locations[ds_std_attribute];
if (warning_at (attr_loc, OPT_Wattributes, "attribute ignored"))
@@ -12739,6 +12877,9 @@ grokdeclarator (const cp_declarator *declarator,
"is ignored");
}
+ if (attrlist)
+ diagnose_misapplied_contracts (*attrlist);
+
/* Determine the type of the entity declared by recurring on the
declarator. */
for (; declarator; declarator = declarator->declarator)
@@ -12776,6 +12917,12 @@ grokdeclarator (const cp_declarator *declarator,
inner_declarator = declarator->declarator;
+ /* Check that contracts aren't misapplied. */
+ if (tree contract_attr = find_contract (declarator->std_attributes))
+ if (declarator->kind != cdk_function
+ || innermost_code != cdk_function)
+ diagnose_misapplied_contracts (contract_attr);
+
/* We don't want to warn in parameter context because we don't
yet know if the parse will succeed, and this might turn out
to be a constructor call. */
@@ -12972,7 +13119,11 @@ grokdeclarator (const cp_declarator *declarator,
if (type_quals != TYPE_UNQUALIFIED)
{
- if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type))
+ /* It's wrong, for instance, to issue a -Wignored-qualifiers
+ warning for
+ static_assert(!is_same_v<void(*)(), const void(*)()>);
+ because there the qualifier matters. */
+ if (funcdecl_p && (SCALAR_TYPE_P (type) || VOID_TYPE_P (type)))
warning_at (typespec_loc, OPT_Wignored_qualifiers, "type "
"qualifiers ignored on function return type");
/* [dcl.fct] "A volatile-qualified return type is
@@ -13001,7 +13152,7 @@ grokdeclarator (const cp_declarator *declarator,
"an array", name);
return error_mark_node;
}
- if (constinit_p)
+ if (constinit_p && funcdecl_p)
{
error_at (declspecs->locations[ds_constinit],
"%<constinit%> on function return type is not "
@@ -13168,6 +13319,23 @@ grokdeclarator (const cp_declarator *declarator,
else
returned_attrs = attr_chainon (returned_attrs, att);
}
+
+ /* Actually apply the contract attributes to the declaration. */
+ for (tree *p = &attrs; *p;)
+ {
+ tree l = *p;
+ if (cxx_contract_attribute_p (l))
+ {
+ *p = TREE_CHAIN (l);
+ /* Intentionally reverse order of contracts so they're
+ reversed back into their lexical order. */
+ TREE_CHAIN (l) = NULL_TREE;
+ returned_attrs = chainon (l, returned_attrs);
+ }
+ else
+ p = &TREE_CHAIN (l);
+ }
+
if (attrs)
/* [dcl.fct]/2:
@@ -14190,7 +14358,10 @@ grokdeclarator (const cp_declarator *declarator,
{
/* Packages tend to use GNU attributes on friends, so we only
warn for standard attributes. */
- if (attrlist && !funcdef_flag && cxx11_attribute_p (*attrlist))
+ if (attrlist
+ && !funcdef_flag
+ && cxx11_attribute_p (*attrlist)
+ && !all_attributes_are_contracts_p (*attrlist))
{
*attrlist = NULL_TREE;
if (warning_at (id_loc, OPT_Wattributes, "attribute ignored"))
@@ -14601,6 +14772,19 @@ grokdeclarator (const cp_declarator *declarator,
else if (constinit_p)
DECL_DECLARED_CONSTINIT_P (decl) = true;
}
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ /* If we saw a return type, record its location. */
+ location_t loc = declspecs->locations[ds_type_spec];
+ if (loc != UNKNOWN_LOCATION)
+ {
+ tree restype = TREE_TYPE (TREE_TYPE (decl));
+ tree resdecl = build_decl (loc, RESULT_DECL, 0, restype);
+ DECL_ARTIFICIAL (resdecl) = 1;
+ DECL_IGNORED_P (resdecl) = 1;
+ DECL_RESULT (decl) = resdecl;
+ }
+ }
/* Record constancy and volatility on the DECL itself . There's
no need to do this when processing a template; we'll do this
@@ -15311,7 +15495,15 @@ grok_op_properties (tree decl, bool complain)
an enumeration, or a reference to an enumeration. 13.4.0.6 */
if (! methodp || DECL_STATIC_FUNCTION_P (decl))
{
- if (operator_code == CALL_EXPR)
+ if (operator_code == TYPE_EXPR
+ || operator_code == COMPONENT_REF
+ || operator_code == NOP_EXPR)
+ {
+ error_at (loc, "%qD must be a non-static member function", decl);
+ return false;
+ }
+
+ if (operator_code == CALL_EXPR || operator_code == ARRAY_REF)
{
if (! DECL_STATIC_FUNCTION_P (decl))
{
@@ -15320,52 +15512,45 @@ grok_op_properties (tree decl, bool complain)
}
if (cxx_dialect < cxx23
/* For lambdas we diagnose static lambda specifier elsewhere. */
- && ! LAMBDA_FUNCTION_P (decl)
+ && (operator_code == ARRAY_REF || ! LAMBDA_FUNCTION_P (decl))
/* For instantiations, we have diagnosed this already. */
&& ! DECL_USE_TEMPLATE (decl))
pedwarn (loc, OPT_Wc__23_extensions, "%qD may be a static member "
- "function only with %<-std=c++23%> or %<-std=gnu++23%>", decl);
- /* There are no further restrictions on the arguments to an
- overloaded "operator ()". */
- return true;
+ "function only with %<-std=c++23%> or %<-std=gnu++23%>",
+ decl);
+ if (operator_code == ARRAY_REF)
+ /* static operator[] should have exactly one argument
+ for C++20 and earlier, so that it isn't multidimensional. */
+ op_flags = OVL_OP_FLAG_UNARY;
}
- if (operator_code == TYPE_EXPR
- || operator_code == COMPONENT_REF
- || operator_code == ARRAY_REF
- || operator_code == NOP_EXPR)
- {
- error_at (loc, "%qD must be a non-static member function", decl);
- return false;
- }
-
- if (DECL_STATIC_FUNCTION_P (decl))
+ else if (DECL_STATIC_FUNCTION_P (decl))
{
error_at (loc, "%qD must be either a non-static member "
"function or a non-member function", decl);
return false;
}
-
- for (tree arg = argtypes; ; arg = TREE_CHAIN (arg))
- {
- if (!arg || arg == void_list_node)
- {
- if (complain)
- error_at(loc, "%qD must have an argument of class or "
- "enumerated type", decl);
- return false;
- }
+ else
+ for (tree arg = argtypes; ; arg = TREE_CHAIN (arg))
+ {
+ if (!arg || arg == void_list_node)
+ {
+ if (complain)
+ error_at (loc, "%qD must have an argument of class or "
+ "enumerated type", decl);
+ return false;
+ }
- tree type = non_reference (TREE_VALUE (arg));
- if (type == error_mark_node)
- return false;
-
- /* MAYBE_CLASS_TYPE_P, rather than CLASS_TYPE_P, is used
- because these checks are performed even on template
- functions. */
- if (MAYBE_CLASS_TYPE_P (type)
- || TREE_CODE (type) == ENUMERAL_TYPE)
- break;
- }
+ tree type = non_reference (TREE_VALUE (arg));
+ if (type == error_mark_node)
+ return false;
+
+ /* MAYBE_CLASS_TYPE_P, rather than CLASS_TYPE_P, is used
+ because these checks are performed even on template
+ functions. */
+ if (MAYBE_CLASS_TYPE_P (type)
+ || TREE_CODE (type) == ENUMERAL_TYPE)
+ break;
+ }
}
if (operator_code == CALL_EXPR)
@@ -17154,9 +17339,17 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
if (DECL_RESULT (decl1) == NULL_TREE)
{
- tree resdecl;
+ /* In a template instantiation, copy the return type location. When
+ parsing, the location will be set in grokdeclarator. */
+ location_t loc = input_location;
+ if (DECL_TEMPLATE_INSTANTIATION (decl1))
+ {
+ tree tmpl = template_for_substitution (decl1);
+ if (tree res = DECL_RESULT (DECL_TEMPLATE_RESULT (tmpl)))
+ loc = DECL_SOURCE_LOCATION (res);
+ }
- resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
+ tree resdecl = build_decl (loc, RESULT_DECL, 0, restype);
DECL_ARTIFICIAL (resdecl) = 1;
DECL_IGNORED_P (resdecl) = 1;
DECL_RESULT (decl1) = resdecl;
@@ -17410,6 +17603,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
store_parm_decls (current_function_parms);
+ start_function_contracts (decl1);
+
if (!processing_template_decl
&& (flag_lifetime_dse > 1)
&& DECL_CONSTRUCTOR_P (decl1)
@@ -18130,6 +18325,9 @@ finish_function (bool inline_p)
current_function_decl = NULL_TREE;
invoke_plugin_callbacks (PLUGIN_FINISH_PARSE_FUNCTION, fndecl);
+
+ finish_function_contracts (fndecl);
+
return fndecl;
}
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index e677926..f95529a 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -1561,6 +1561,9 @@ cp_check_const_attributes (tree attributes)
tree attr;
for (attr = attributes; attr; attr = TREE_CHAIN (attr))
{
+ if (cxx_contract_attribute_p (attr))
+ continue;
+
tree arg;
/* As we implement alignas using gnu::aligned attribute and
alignas argument is a constant expression, force manifestly
@@ -2106,7 +2109,17 @@ void
comdat_linkage (tree decl)
{
if (flag_weak)
- make_decl_one_only (decl, cxx_comdat_group (decl));
+ {
+ make_decl_one_only (decl, cxx_comdat_group (decl));
+ if (HAVE_COMDAT_GROUP && flag_contracts && DECL_CONTRACTS (decl))
+ {
+ symtab_node *n = symtab_node::get (decl);
+ if (tree pre = DECL_PRE_FN (decl))
+ cgraph_node::get_create (pre)->add_to_same_comdat_group (n);
+ if (tree post = DECL_POST_FN (decl))
+ cgraph_node::get_create (post)->add_to_same_comdat_group (n);
+ }
+ }
else if (TREE_CODE (decl) == FUNCTION_DECL
|| (VAR_P (decl) && DECL_ARTIFICIAL (decl)))
/* We can just emit function and compiler-generated variables
@@ -5788,14 +5801,6 @@ mark_used (tree decl, tsubst_flags_t complain /* = tf_warning_or_error */)
&& !DECL_DEFAULTED_OUTSIDE_CLASS_P (decl)
&& ! DECL_INITIAL (decl))
{
- /* Defer virtual destructors so that thunks get the right
- linkage. */
- if (DECL_VIRTUAL_P (decl) && !at_eof)
- {
- note_vague_linkage_fn (decl);
- return true;
- }
-
/* Remember the current location for a function we will end up
synthesizing. Then we can inform the user where it was
required in the case of error. */
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index da8c95c..12b28e8 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -567,7 +567,8 @@ dump_type (cxx_pretty_printer *pp, tree t, int flags)
else
{
pp_cxx_cv_qualifier_seq (pp, t);
- pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
+ if (tree id = TYPE_IDENTIFIER (t))
+ pp_cxx_tree_identifier (pp, id);
}
break;
diff --git a/gcc/cp/g++spec.cc b/gcc/cp/g++spec.cc
index b63d835..3d3b042 100644
--- a/gcc/cp/g++spec.cc
+++ b/gcc/cp/g++spec.cc
@@ -31,6 +31,8 @@ along with GCC; see the file COPYING3. If not see
#define WITHLIBC (1<<3)
/* Skip this option. */
#define SKIPOPT (1<<4)
+/* Add -lstdc++exp for experimental features that need library support. */
+#define EXPERIMENTAL (1<<5)
#ifndef MATH_LIBRARY
#define MATH_LIBRARY "m"
@@ -126,6 +128,9 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
/* By default, we throw on the math library if we have one. */
int need_math = (MATH_LIBRARY[0] != '\0');
+ /* By default, we don't add -lstdc++exp. */
+ bool need_experimental = false;
+
/* True if we saw -static. */
int static_link = 0;
@@ -158,8 +163,14 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
switch (decoded_options[i].opt_index)
{
- case OPT_nostdlib:
+ case OPT_fcontracts:
+ need_experimental = true;
+ break;
+
case OPT_nostdlib__:
+ args[i] |= SKIPOPT;
+ /* FALLTHRU */
+ case OPT_nostdlib:
case OPT_nodefaultlibs:
library = -1;
break;
@@ -285,7 +296,8 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
#endif
/* Add one for shared_libgcc or extra static library. */
- num_args = argc + added + need_math + (library > 0) * 4 + 1;
+ num_args = (argc + added + need_math + need_experimental
+ + (library > 0) * 4 + 1);
/* For libc++, on most platforms, the ABI library (usually called libc++abi)
is provided as a separate DSO, which we must also append.
However, a platform might have the ability to forward the ABI library
@@ -358,6 +370,12 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
/* Add `-lstdc++' if we haven't already done so. */
if (library > 0)
{
+ if (need_experimental && which_library == USE_LIBSTDCXX)
+ {
+ generate_option (OPT_l, "stdc++exp", 1, CL_DRIVER,
+ &new_decoded_options[j++]);
+ ++added_libraries;
+ }
#ifdef HAVE_LD_STATIC_DYNAMIC
if (library > 1 && !static_link)
{
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index 3d5d390..428fac5 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -620,10 +620,8 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)
start_lambda_scope (member);
/* Do deferred instantiation of the NSDMI. */
- init = (tsubst_copy_and_build
- (init, DECL_TI_ARGS (member),
- complain, member, /*function_p=*/false,
- /*integral_constant_expression_p=*/false));
+ init = tsubst_copy_and_build (init, DECL_TI_ARGS (member),
+ complain, member);
init = digest_nsdmi_init (member, init, complain);
finish_lambda_scope ();
@@ -4310,6 +4308,51 @@ finish_length_check (tree atype, tree iterator, tree obase, unsigned n)
}
}
+/* walk_tree callback to collect temporaries in an expression. */
+
+tree
+find_temps_r (tree *tp, int *walk_subtrees, void *data)
+{
+ vec<tree*> &temps = *static_cast<auto_vec<tree*> *>(data);
+ tree t = *tp;
+ if (TREE_CODE (t) == TARGET_EXPR
+ && !TARGET_EXPR_ELIDING_P (t))
+ temps.safe_push (tp);
+ else if (TYPE_P (t))
+ *walk_subtrees = 0;
+
+ return NULL_TREE;
+}
+
+/* If INIT initializes a standard library class, and involves a temporary
+ std::allocator<T>, return a pointer to the temp.
+
+ Used by build_vec_init when initializing an array of e.g. strings to reuse
+ the same temporary allocator for all of the strings. We can do this because
+ std::allocator has no data and the standard library doesn't care about the
+ address of allocator objects.
+
+ ??? Add an attribute to allow users to assert the same property for other
+ classes, i.e. one object of the type is interchangeable with any other? */
+
+static tree*
+find_allocator_temp (tree init)
+{
+ if (TREE_CODE (init) == EXPR_STMT)
+ init = EXPR_STMT_EXPR (init);
+ if (TREE_CODE (init) == CONVERT_EXPR)
+ init = TREE_OPERAND (init, 0);
+ tree type = TREE_TYPE (init);
+ if (!CLASS_TYPE_P (type) || !decl_in_std_namespace_p (TYPE_NAME (type)))
+ return NULL;
+ auto_vec<tree*> temps;
+ cp_walk_tree_without_duplicates (&init, find_temps_r, &temps);
+ for (tree *p : temps)
+ if (is_std_allocator (TREE_TYPE (*p)))
+ return p;
+ return NULL;
+}
+
/* `build_vec_init' returns tree structure that performs
initialization of a vector of aggregate types.
@@ -4591,6 +4634,8 @@ build_vec_init (tree base, tree maxindex, tree init,
if (try_const)
vec_alloc (const_vec, CONSTRUCTOR_NELTS (init));
+ tree alloc_obj = NULL_TREE;
+
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, field, elt)
{
tree baseref = build1 (INDIRECT_REF, type, base);
@@ -4640,7 +4685,17 @@ build_vec_init (tree base, tree maxindex, tree init,
}
if (one_init)
- finish_expr_stmt (one_init);
+ {
+ /* Only create one std::allocator temporary. */
+ if (tree *this_alloc = find_allocator_temp (one_init))
+ {
+ if (alloc_obj)
+ *this_alloc = alloc_obj;
+ else
+ alloc_obj = TARGET_EXPR_SLOT (*this_alloc);
+ }
+ finish_expr_stmt (one_init);
+ }
one_init = cp_build_unary_op (PREINCREMENT_EXPR, base, false,
complain);
diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
index d2673e2..c7a9268 100644
--- a/gcc/cp/lambda.cc
+++ b/gcc/cp/lambda.cc
@@ -1447,13 +1447,21 @@ is_lambda_ignored_entity (tree val)
/* Lambdas that appear in variable initializer or default argument
scope get that in their mangling, so we need to record it. Also,
multiple lambdas in the same scope may need a mangling
- discriminator. Record in the same data structure. */
+ discriminator. In ABI <= 17, there is a single per-scope sequence
+ number. In ABI >= 18, there are per-scope per-signature sequence
+ numbers. */
+struct GTY(()) lambda_sig_count
+{
+ tree fn; // The lambda fn whose sig this is.
+ unsigned count;
+};
struct GTY(()) lambda_discriminator
{
tree scope;
unsigned nesting; // Inside a function, VAR_DECLs get the function
// as scope. This counts that nesting.
unsigned count; // The per-scope counter.
+ vec<lambda_sig_count, va_gc> *discriminators; // Per-signature counters
};
// The current scope.
static GTY(()) lambda_discriminator lambda_scope;
@@ -1475,6 +1483,7 @@ start_lambda_scope (tree decl)
lambda_scope.scope = decl;
lambda_scope.nesting = 0;
lambda_scope.count = 0;
+ lambda_scope.discriminators = nullptr;
}
}
@@ -1504,6 +1513,116 @@ record_lambda_scope (tree lambda)
}
}
+// Compare lambda template heads TMPL_A and TMPL_B, used for both
+// templated lambdas, and template template parameters of said lambda.
+
+static bool
+compare_lambda_template_head (tree tmpl_a, tree tmpl_b)
+{
+ // We only need one level of template parms
+ tree inner_a = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl_a));
+ tree inner_b = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl_b));
+
+ // We only compare explicit template parms, ignoring trailing
+ // synthetic ones.
+ int len_a = TREE_VEC_LENGTH (inner_a);
+ int len_b = TREE_VEC_LENGTH (inner_b);
+
+ for (int ix = 0, len = MAX (len_a, len_b); ix != len; ix++)
+ {
+ tree parm_a = NULL_TREE;
+ if (ix < len_a)
+ {
+ parm_a = TREE_VEC_ELT (inner_a, ix);
+ if (parm_a == error_mark_node)
+ return false;
+ parm_a = TREE_VALUE (parm_a);
+ if (DECL_VIRTUAL_P (parm_a))
+ parm_a = NULL_TREE;
+ }
+
+ tree parm_b = NULL_TREE;
+ if (ix < len_b)
+ {
+ parm_b = TREE_VEC_ELT (inner_b, ix);
+ if (parm_b == error_mark_node)
+ return false;
+ parm_b = TREE_VALUE (parm_b);
+ if (DECL_VIRTUAL_P (parm_b))
+ parm_b = NULL_TREE;
+ }
+
+ if (!parm_a && !parm_b)
+ // we're done
+ break;
+
+ if (!(parm_a && parm_b))
+ return false;
+
+ if (TREE_CODE (parm_a) != TREE_CODE (parm_b))
+ return false;
+
+ if (TREE_CODE (parm_a) == PARM_DECL)
+ {
+ if (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm_a))
+ != TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm_b)))
+ return false;
+
+ if (!same_type_p (TREE_TYPE (parm_a), TREE_TYPE (parm_b)))
+ return false;
+ }
+ else
+ {
+ if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm_a))
+ != TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm_b)))
+ return false;
+
+ if (TREE_CODE (parm_a) != TEMPLATE_DECL)
+ gcc_checking_assert (TREE_CODE (parm_a) == TYPE_DECL);
+ else if (!compare_lambda_template_head (parm_a, parm_b))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// Compare lambda signatures FN_A and FN_B, they may be TEMPLATE_DECLs too.
+
+static bool
+compare_lambda_sig (tree fn_a, tree fn_b)
+{
+ if (TREE_CODE (fn_a) == TEMPLATE_DECL
+ && TREE_CODE (fn_b) == TEMPLATE_DECL)
+ {
+ if (!compare_lambda_template_head (fn_a, fn_b))
+ return false;
+ fn_a = DECL_TEMPLATE_RESULT (fn_a);
+ fn_b = DECL_TEMPLATE_RESULT (fn_b);
+ }
+ else if (TREE_CODE (fn_a) == TEMPLATE_DECL
+ || TREE_CODE (fn_b) == TEMPLATE_DECL)
+ return false;
+
+ if (fn_a == error_mark_node
+ || fn_b == error_mark_node)
+ return false;
+
+ for (tree args_a = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_a))),
+ args_b = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_b)));
+ args_a || args_b;
+ args_a = TREE_CHAIN (args_a), args_b = TREE_CHAIN (args_b))
+ {
+ if (!args_a || !args_b)
+ return false;
+ // This check also deals with differing varadicness
+ if (!same_type_p (TREE_VALUE (args_a), TREE_VALUE (args_b)))
+ return false;
+ }
+
+ return true;
+}
+
// Record the per-scope discriminator of LAMBDA. If the extra scope
// is empty, we must use the empty scope counter, which might not be
// the live one.
@@ -1517,6 +1636,33 @@ record_lambda_scope_discriminator (tree lambda)
LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda) = slot->count++;
}
+// Record the per-scope per-signature discriminator of LAMBDA. If the
+// extra scope is empty, we must use the empty scope counter, which
+// might not be the live one.
+
+void
+record_lambda_scope_sig_discriminator (tree lambda, tree fn)
+{
+ auto *slot = (vec_safe_is_empty (lambda_scope_stack)
+ || LAMBDA_EXPR_EXTRA_SCOPE (lambda)
+ ? &lambda_scope : lambda_scope_stack->begin ());
+ gcc_checking_assert (LAMBDA_EXPR_EXTRA_SCOPE (lambda) == slot->scope);
+
+ // A linear search, we're not expecting this to be a big list, and
+ // this avoids needing a signature hash function.
+ lambda_sig_count *sig;
+ if (unsigned ix = vec_safe_length (slot->discriminators))
+ for (sig = slot->discriminators->begin (); ix--; sig++)
+ if (compare_lambda_sig (fn, sig->fn))
+ goto found;
+ {
+ lambda_sig_count init = {fn, 0};
+ sig = vec_safe_push (slot->discriminators, init);
+ }
+ found:
+ LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR (lambda) = sig->count++;
+}
+
tree
start_lambda_function (tree fco, tree lambda_expr)
{
diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index a62c975..e363ef3 100644
--- a/gcc/cp/mangle.cc
+++ b/gcc/cp/mangle.cc
@@ -856,6 +856,13 @@ write_encoding (const tree decl)
mangle_return_type_p (decl),
d);
+ /* If this is the pre/post function for a guarded function, append
+ .pre/post, like something from create_virtual_clone. */
+ if (DECL_IS_PRE_FN_P (decl))
+ write_string (".pre");
+ else if (DECL_IS_POST_FN_P (decl))
+ write_string (".post");
+
/* If this is a coroutine helper, then append an appropriate string to
identify which. */
if (tree ramp = DECL_RAMP_FN (decl))
@@ -1810,7 +1817,13 @@ write_closure_type_name (const tree type)
write_method_parms (parms, /*method_p=*/1, fn);
write_char ('E');
- write_compact_number (LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda));
+ if ((LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR (lambda)
+ != LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda))
+ && abi_warn_or_compat_version_crosses (18))
+ G.need_abi_warning = true;
+ write_compact_number (abi_version_at_least (18)
+ ? LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR (lambda)
+ : LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda));
}
/* Convert NUMBER to ascii using base BASE and generating at least
diff --git a/gcc/cp/mapper-client.cc b/gcc/cp/mapper-client.cc
index fe9544b..8e331c0 100644
--- a/gcc/cp/mapper-client.cc
+++ b/gcc/cp/mapper-client.cc
@@ -227,6 +227,8 @@ module_client::open_module_client (location_t loc, const char *o,
int fd = -1;
#if CODY_NETWORKING
fd = Cody::OpenLocal (&errmsg, name.c_str () + 1);
+#else
+ errmsg = "disabled";
#endif
if (fd >= 0)
c = new module_client (fd, fd);
@@ -254,6 +256,8 @@ module_client::open_module_client (location_t loc, const char *o,
int fd = -1;
#if CODY_NETWORKING
fd = Cody::OpenInet6 (&errmsg, name.c_str (), port);
+#else
+ errmsg = "disabled";
#endif
name[colon] = ':';
diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index c217d7e..7b4d5a5 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -1332,7 +1332,7 @@ struct comp_info
&& !potential_rvalue_constant_expression (expr))
{
if (was_constexp)
- require_potential_rvalue_constant_expression (expr);
+ require_potential_rvalue_constant_expression_fncheck (expr);
else
constexp = false;
}
@@ -2670,13 +2670,17 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
requirements of a constexpr constructor (7.1.5), the
implicitly-defined default constructor is constexpr.
+ C++20:
The implicitly-defined copy/move assignment operator is constexpr if
- X is a literal type, and
- the assignment operator selected to copy/move each direct base class
subobject is a constexpr function, and
- for each non-static data member of X that is of class type (or array
thereof), the assignment operator selected to copy/move that
- member is a constexpr function. */
+ member is a constexpr function.
+
+ C++23:
+ The implicitly-defined copy/move assignment operator is constexpr. */
if (constexpr_p)
*constexpr_p = (SFK_CTOR_P (sfk)
|| (SFK_ASSIGN_P (sfk) && cxx_dialect >= cxx14)
@@ -3075,7 +3079,7 @@ implicitly_declare_fn (special_function_kind kind, tree type,
{
fn = copy_operator_fn (pattern_fn, EQ_EXPR);
DECL_ARTIFICIAL (fn) = 1;
- TREE_TYPE (fn) = change_return_type (boolean_type_node, TREE_TYPE (fn));
+ apply_deduced_return_type (fn, boolean_type_node);
return fn;
}
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index df05b52..7133009 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -6328,6 +6328,7 @@ trees_out::core_vals (tree t)
{
WU (((lang_tree_node *)t)->lambda_expression.default_capture_mode);
WU (((lang_tree_node *)t)->lambda_expression.discriminator_scope);
+ WU (((lang_tree_node *)t)->lambda_expression.discriminator_sig);
}
break;
@@ -6820,6 +6821,7 @@ trees_in::core_vals (tree t)
RUC (cp_lambda_default_capture_mode_type,
((lang_tree_node *)t)->lambda_expression.default_capture_mode);
RU (((lang_tree_node *)t)->lambda_expression.discriminator_scope);
+ RU (((lang_tree_node *)t)->lambda_expression.discriminator_sig);
break;
case OVERLOAD:
@@ -10184,6 +10186,20 @@ trees_out::fn_parms_init (tree fn)
base_tag - ix, ix, parm, fn);
tree_node_vals (parm);
}
+
+ if (!streaming_p ())
+ {
+ /* We must walk contract attrs so the dependency graph is complete. */
+ for (tree contract = DECL_CONTRACTS (fn);
+ contract;
+ contract = CONTRACT_CHAIN (contract))
+ tree_node (contract);
+ }
+
+ /* Write a reference to contracts pre/post functions, if any, to avoid
+ regenerating them in importers. */
+ tree_node (DECL_PRE_FN (fn));
+ tree_node (DECL_POST_FN (fn));
}
/* Build skeleton parm nodes, read their flags, type & parm indices. */
@@ -10218,6 +10234,11 @@ trees_in::fn_parms_init (tree fn)
return 0;
}
+ /* Reload references to contract functions, if any. */
+ tree pre_fn = tree_node ();
+ tree post_fn = tree_node ();
+ set_contract_functions (fn, pre_fn, post_fn);
+
return base_tag;
}
@@ -10805,7 +10826,15 @@ check_mergeable_decl (merge_kind mk, tree decl, tree ovl, merge_key const &key)
Matches decls_match behaviour. */
&& (!DECL_IS_UNDECLARED_BUILTIN (m_inner)
|| !DECL_EXTERN_C_P (m_inner)
- || DECL_EXTERN_C_P (d_inner)))
+ || DECL_EXTERN_C_P (d_inner))
+ /* Reject if one is a different member of a
+ guarded/pre/post fn set. */
+ && (!flag_contracts
+ || (DECL_IS_PRE_FN_P (d_inner)
+ == DECL_IS_PRE_FN_P (m_inner)))
+ && (!flag_contracts
+ || (DECL_IS_POST_FN_P (d_inner)
+ == DECL_IS_POST_FN_P (m_inner))))
{
tree m_reqs = get_constraints (m_inner);
if (m_reqs)
@@ -13958,7 +13987,15 @@ get_module (tree name, module_state *parent, bool partition)
static module_state *
get_module (const char *ptr)
{
- if (ptr[0] == '.' ? IS_DIR_SEPARATOR (ptr[1]) : IS_ABSOLUTE_PATH (ptr))
+ /* On DOS based file systems, there is an ambiguity with A:B which can be
+ interpreted as a module Module:Partition or Drive:PATH. Interpret strings
+ which clearly starts as pathnames as header-names and everything else is
+ treated as a (possibly malformed) named moduled. */
+ if (IS_DIR_SEPARATOR (ptr[ptr[0] == '.']) // ./FOO or /FOO
+#if HAVE_DOS_BASED_FILE_SYSTEM
+ || (HAS_DRIVE_SPEC (ptr) && IS_DIR_SEPARATOR (ptr[2])) // A:/FOO
+#endif
+ || false)
/* A header name. */
return get_module (build_string (strlen (ptr), ptr));
@@ -14573,6 +14610,7 @@ module_state_config::get_dialect ()
cxx_dialect < cxx20 && flag_concepts ? "/concepts" : "",
flag_coroutines ? "/coroutines" : "",
flag_module_implicit_inline ? "/implicit-inline" : "",
+ flag_contracts ? "/contracts" : "",
NULL);
return dialect;
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index e0e3cf3..4798aae 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "cp-name-hint.h"
#include "memmodel.h"
#include "c-family/known-headers.h"
+#include "contracts.h"
#include "bitmap.h"
@@ -2192,11 +2193,14 @@ cp_parser_context_new (cp_parser_context* next)
parser->unparsed_queues->last ().nsdmis
#define unparsed_noexcepts \
parser->unparsed_queues->last ().noexcepts
+#define unparsed_contracts \
+ parser->unparsed_queues->last ().contracts
static void
push_unparsed_function_queues (cp_parser *parser)
{
- cp_unparsed_functions_entry e = { NULL, make_tree_vector (), NULL, NULL };
+ cp_unparsed_functions_entry e
+ = { NULL, make_tree_vector (), NULL, NULL, NULL };
vec_safe_push (parser->unparsed_queues, e);
}
@@ -2338,7 +2342,7 @@ static tree cp_parser_c_for
static tree cp_parser_range_for
(cp_parser *, tree, tree, tree, bool, unsigned short, bool);
static void do_range_for_auto_deduction
- (tree, tree);
+ (tree, tree, tree, unsigned int);
static tree cp_parser_perform_range_for_lookup
(tree, tree *, tree *);
static tree cp_parser_range_for_member_function
@@ -2695,6 +2699,10 @@ static tree cp_parser_transaction_cancel
static tree cp_parser_yield_expression
(cp_parser *);
+/* Contracts */
+
+static void cp_parser_late_contract_condition
+ (cp_parser *, tree, tree);
enum pragma_context {
pragma_external,
@@ -2907,6 +2915,8 @@ static bool cp_parser_array_designator_p
(cp_parser *);
static bool cp_parser_init_statement_p
(cp_parser *);
+static bool cp_parser_skip_up_to_closing_square_bracket
+ (cp_parser *);
static bool cp_parser_skip_to_closing_square_bracket
(cp_parser *);
static size_t cp_parser_skip_balanced_tokens (cp_parser *, size_t);
@@ -11712,6 +11722,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
fco = finish_fully_implicit_template (parser, fco);
finish_member_declaration (fco);
+ record_lambda_scope_sig_discriminator (lambda_expr, fco);
obstack_free (&declarator_obstack, p);
@@ -12023,6 +12034,16 @@ cp_parser_handle_statement_omp_attributes (cp_parser *parser, tree attrs)
return attrs;
}
+/* True if and only if the name is one of the contract types. */
+
+static bool
+contract_attribute_p (const_tree id)
+{
+ return is_attribute_p ("assert", id)
+ || is_attribute_p ("pre", id)
+ || is_attribute_p ("post", id);
+}
+
/* Handle omp::directive and omp::sequence attributes in *PATTRS
(if any) at the start or after declaration-id of a declaration. */
@@ -12156,7 +12177,10 @@ cp_parser_handle_directive_omp_attributes (cp_parser *parser, tree *pattrs,
is a (possibly labeled) if statement which is not enclosed in braces
and has an else clause. This is used to implement -Wparentheses.
- CHAIN is a vector of if-else-if conditions. */
+ CHAIN is a vector of if-else-if conditions.
+
+ Note that this version of parsing restricts assertions to be attached to
+ empty statements. */
static void
cp_parser_statement (cp_parser* parser, tree in_statement_expr,
@@ -12198,6 +12222,23 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
+
+ /* If we have contracts, check that they're valid in this context. */
+ if (std_attrs != error_mark_node)
+ {
+ if (tree pre = lookup_attribute ("pre", std_attrs))
+ error_at (EXPR_LOCATION (TREE_VALUE (pre)),
+ "preconditions cannot be statements");
+ else if (tree post = lookup_attribute ("post", std_attrs))
+ error_at (EXPR_LOCATION (TREE_VALUE (post)),
+ "postconditions cannot be statements");
+
+ /* Check that assertions are null statements. */
+ if (cp_contract_assertion_p (std_attrs))
+ if (token->type != CPP_SEMICOLON)
+ error_at (token->location, "assertions must be followed by %<;%>");
+ }
+
bool omp_attrs_forbidden_p;
omp_attrs_forbidden_p = parser->omp_attrs_forbidden_p;
@@ -12513,6 +12554,15 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
"%<fallthrough%> attribute not followed by %<;%>");
std_attrs = NULL_TREE;
}
+
+ /* Handle [[assert: ...]]; */
+ if (cp_contract_assertion_p (std_attrs))
+ {
+ /* Add the assertion as a statement in the current block. */
+ gcc_assert (!statement || statement == error_mark_node);
+ emit_assertion (std_attrs);
+ std_attrs = NULL_TREE;
+ }
}
/* Set the line number for the statement. */
@@ -13618,7 +13668,8 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl,
if (!type_dependent_expression_p (range_expr)
/* do_auto_deduction doesn't mess with template init-lists. */
&& !BRACE_ENCLOSED_INITIALIZER_P (range_expr))
- do_range_for_auto_deduction (range_decl, range_expr);
+ do_range_for_auto_deduction (range_decl, range_expr, decomp_first_name,
+ decomp_cnt);
}
else
{
@@ -13657,7 +13708,8 @@ build_range_temp (tree range_expr)
a shortcut version of cp_convert_range_for. */
static void
-do_range_for_auto_deduction (tree decl, tree range_expr)
+do_range_for_auto_deduction (tree decl, tree range_expr,
+ tree decomp_first_name, unsigned int decomp_cnt)
{
tree auto_node = type_uses_auto (TREE_TYPE (decl));
if (auto_node)
@@ -13677,6 +13729,8 @@ do_range_for_auto_deduction (tree decl, tree range_expr)
iter_decl, auto_node,
tf_warning_or_error,
adc_variable_type);
+ if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl))
+ cp_finish_decomp (decl, decomp_first_name, decomp_cnt);
}
}
}
@@ -15696,7 +15750,12 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
declared. */;
else
{
- if (decl_specs->type && CLASS_TYPE_P (decl_specs->type))
+ if (find_contract (attrs))
+ {
+ diagnose_misapplied_contracts (attrs);
+ attrs = NULL_TREE;
+ }
+ else if (decl_specs->type && CLASS_TYPE_P (decl_specs->type))
{
/* This is an attribute following a
class-specifier. */
@@ -15776,11 +15835,11 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
{
cp_token *next = cp_lexer_peek_token (parser->lexer);
if (next->keyword == RID_BOOL)
- pedwarn (next->location, 0, "the %<bool%> keyword is not "
- "allowed in a C++20 concept definition");
+ permerror (next->location, "the %<bool%> keyword is not "
+ "allowed in a C++20 concept definition");
else
- pedwarn (token->location, 0, "C++20 concept definition syntax "
- "is %<concept <name> = <expr>%>");
+ error_at (token->location, "C++20 concept definition syntax "
+ "is %<concept <name> = <expr>%>");
}
/* In C++20 a concept definition is just 'concept name = expr;'
@@ -25386,6 +25445,7 @@ cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
location_t finish_loc = cp_lexer_peek_token (parser->lexer)->location;
braces.require_close (parser);
TREE_TYPE (initializer) = init_list_type_node;
+ recompute_constructor_flags (initializer);
cp_expr result (initializer);
/* Build a location of the form:
@@ -25397,11 +25457,11 @@ cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
return result;
}
-/* Consume tokens up to, and including, the next non-nested closing `]'.
+/* Consume tokens up to, but not including, the next non-nested closing `]'.
Returns true iff we found a closing `]'. */
static bool
-cp_parser_skip_to_closing_square_bracket (cp_parser *parser)
+cp_parser_skip_up_to_closing_square_bracket (cp_parser *parser)
{
unsigned square_depth = 0;
@@ -25426,21 +25486,30 @@ cp_parser_skip_to_closing_square_bracket (cp_parser *parser)
case CPP_CLOSE_SQUARE:
if (!square_depth--)
- {
- cp_lexer_consume_token (parser->lexer);
- return true;
- }
+ return true;
break;
default:
break;
}
- /* Consume the token. */
+ /* Consume the current token, skipping it. */
cp_lexer_consume_token (parser->lexer);
}
}
+/* Consume tokens up to, and including, the next non-nested closing `]'.
+ Returns true iff we found a closing `]'. */
+
+static bool
+cp_parser_skip_to_closing_square_bracket (cp_parser *parser)
+{
+ bool found = cp_parser_skip_up_to_closing_square_bracket (parser);
+ if (found)
+ cp_lexer_consume_token (parser->lexer);
+ return found;
+}
+
/* Return true if we are looking at an array-designator, false otherwise. */
static bool
@@ -26283,6 +26352,56 @@ cp_parser_class_specifier (cp_parser* parser)
cp_parser_late_parsing_nsdmi (parser, decl);
}
vec_safe_truncate (unparsed_nsdmis, 0);
+
+ /* Now contract attributes. */
+ FOR_EACH_VEC_SAFE_ELT (unparsed_contracts, ix, decl)
+ {
+ tree ctx = DECL_CONTEXT (decl);
+ if (class_type != ctx)
+ {
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+ class_type = ctx;
+ pushed_scope = push_scope (class_type);
+ }
+
+ temp_override<tree> cfd(current_function_decl, decl);
+
+ /* Make sure that any template parameters are in scope. */
+ maybe_begin_member_template_processing (decl);
+
+ /* Make sure that any member-function parameters are in scope.
+ This function doesn't expect ccp to be set. */
+ current_class_ptr = current_class_ref = NULL_TREE;
+ inject_parm_decls (decl);
+
+ /* 'this' is not allowed in static member functions. */
+ unsigned char local_variables_forbidden_p
+ = parser->local_variables_forbidden_p;
+ if (DECL_THIS_STATIC (decl))
+ parser->local_variables_forbidden_p |= THIS_FORBIDDEN;
+
+ /* Now we can parse contract conditions. */
+ for (tree a = DECL_ATTRIBUTES (decl); a; a = TREE_CHAIN (a))
+ {
+ if (cxx_contract_attribute_p (a))
+ cp_parser_late_contract_condition (parser, decl, a);
+ }
+
+ /* Restore the state of local_variables_forbidden_p. */
+ parser->local_variables_forbidden_p = local_variables_forbidden_p;
+
+ /* Remove any member-function parameters from the symbol table. */
+ pop_injected_parms ();
+
+ /* Remove any template parameters from the symbol table. */
+ maybe_end_member_template_processing ();
+
+ /* Perform any deferred contract matching. */
+ match_deferred_contracts (decl);
+ }
+ vec_safe_truncate (unparsed_contracts, 0);
+
current_class_ptr = save_ccp;
current_class_ref = save_ccr;
if (pushed_scope)
@@ -26386,6 +26505,8 @@ cp_parser_class_head (cp_parser* parser,
/* Parse the attributes. */
attributes = cp_parser_attributes_opt (parser);
+ if (find_contract (attributes))
+ diagnose_misapplied_contracts (attributes);
/* If the next token is `::', that is invalid -- but sometimes
people do try to write:
@@ -29238,8 +29359,7 @@ cp_parser_std_attribute (cp_parser *parser, tree attr_ns)
/* Warn if the attribute ATTRIBUTE appears more than once in the
attribute-list ATTRIBUTES. This used to be enforced for certain
- attributes, but the restriction was removed in P2156. Note that
- carries_dependency ([dcl.attr.depend]) isn't implemented yet in GCC.
+ attributes, but the restriction was removed in P2156.
LOC is the location of ATTRIBUTE. Returns true if ATTRIBUTE was not
found in ATTRIBUTES. */
@@ -29248,7 +29368,7 @@ cp_parser_check_std_attribute (location_t loc, tree attributes, tree attribute)
{
static auto alist = { "noreturn", "deprecated", "nodiscard", "maybe_unused",
"likely", "unlikely", "fallthrough",
- "no_unique_address" };
+ "no_unique_address", "carries_dependency" };
if (attributes)
for (const auto &a : alist)
if (is_attribute_p (a, get_attribute_name (attribute))
@@ -29316,10 +29436,361 @@ cp_parser_std_attribute_list (cp_parser *parser, tree attr_ns)
return attributes;
}
+/* Optionally parse a C++20 contract role. A NULL return means that no
+ contract role was specified.
+
+ contract-role:
+ % default
+ % identifier
+
+ If the identifier does not name a known contract role, it will
+ be assumed to be default. Returns the identifier for the role
+ token. */
+
+static tree
+cp_parser_contract_role (cp_parser *parser)
+{
+ gcc_assert (cp_lexer_next_token_is (parser->lexer, CPP_MOD));
+ cp_lexer_consume_token (parser->lexer);
+
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ tree role_id = NULL_TREE;
+ if (token->type == CPP_NAME)
+ role_id = token->u.value;
+ else if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
+ role_id = get_identifier ("default");
+ else
+ {
+ error_at (token->location, "expected contract-role");
+ return error_mark_node;
+ }
+ cp_lexer_consume_token (parser->lexer);
+
+ /* FIXME: Warn about invalid/unknown roles? */
+ return role_id;
+}
+
+/* Parse an optional contract mode.
+
+ contract-mode:
+ contract-semantic
+ [contract-level] [contract-role]
+
+ contract-semantic:
+ check_never_continue
+ check_maybe_continue
+ check_always_continue
+
+ contract-level:
+ default
+ audit
+ axiom
+
+ contract-role:
+ default
+ identifier
+
+ This grammar is taken from P1332R0. During parsing, this sets options
+ on the MODE object to determine the configuration of the contract.
+
+ Returns a tree containing the identifiers used in the configuration.
+ This is either an IDENTIFIER with the literal semantic or a TREE_LIST
+ whose TREE_VALUE is the contract-level and whose TREE_PURPOSE is the
+ contract-role, if any. NULL_TREE is returned if no information is
+ given (i.e., all defaults selected). */
+
+static tree
+cp_parser_contract_mode_opt (cp_parser *parser,
+ bool postcondition_p)
+{
+ /* The mode is empty; the level and role are default. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ return NULL_TREE;
+
+ /* There is only a role; the level is default. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_MOD))
+ {
+ tree role_id = cp_parser_contract_role (parser);
+ return build_tree_list (role_id, get_identifier ("default"));
+ }
+
+ /* Otherwise, match semantic or level. */
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ contract_level level = CONTRACT_INVALID;
+ contract_semantic semantic = CCS_INVALID;
+ tree config_id;
+ if (token->type == CPP_NAME)
+ {
+ config_id = token->u.value;
+
+ /* Either a named level, a concrete semantic, or an identifier
+ for a postcondition. */
+ const char *ident = IDENTIFIER_POINTER (token->u.value);
+ level = map_contract_level (ident);
+ semantic = map_contract_semantic (ident);
+
+ /* The identifier is the return value for a postcondition. */
+ if (level == CONTRACT_INVALID && semantic == CCS_INVALID
+ && postcondition_p)
+ return NULL_TREE;
+ }
+ else if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
+ {
+ config_id = get_identifier ("default");
+ level = CONTRACT_DEFAULT;
+ }
+ else
+ {
+ /* We got some other token other than a ':'. */
+ error_at (token->location, "expected contract semantic or level");
+ return NULL_TREE;
+ }
+
+ /* Consume the literal semantic or level token. */
+ cp_lexer_consume_token (parser->lexer);
+
+ if (semantic == CCS_INVALID && level == CONTRACT_INVALID)
+ {
+ error_at (token->location,
+ "expected contract level: "
+ "%<default%>, %<audit%>, or %<axiom%>");
+ return NULL_TREE;
+ }
+
+ /* We matched an explicit semantic. */
+ if (semantic != CCS_INVALID)
+ {
+ if (cp_lexer_next_token_is (parser->lexer, CPP_MOD))
+ {
+ error ("invalid use of contract role for explicit semantic");
+ cp_lexer_consume_token (parser->lexer);
+ cp_lexer_consume_token (parser->lexer);
+ }
+ return config_id;
+ }
+
+ /* We matched a level, there may be a role; otherwise this is default. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_MOD))
+ {
+ tree role_id = cp_parser_contract_role (parser);
+ return build_tree_list (role_id, config_id);
+ }
+
+ return build_tree_list (NULL_TREE, config_id);
+}
+
+static tree
+find_error (tree *tp, int *, void *)
+{
+ if (*tp == error_mark_node)
+ return *tp;
+ return NULL_TREE;
+}
+
+static bool
+contains_error_p (tree t)
+{
+ return walk_tree (&t, find_error, NULL, NULL);
+}
+
+/* Parse a standard C++20 contract attribute specifier.
+
+ contract-attribute-specifier:
+ [ [ assert contract-level [opt] : conditional-expression ] ]
+ [ [ pre contract-level [opt] : conditional-expression ] ]
+ [ [ post contract-level [opt] identifier [opt] : conditional-expression ] ]
+
+ For free functions, we cannot determine the type of the postcondition
+ identifier because the we haven't called grokdeclarator yet. In those
+ cases we parse the postcondition as if the identifier was declared as
+ 'auto <identifier>'. We then instantiate the postcondition once the
+ return type is known.
+
+ For member functions, contracts are in the complete-class context, so the
+ parse is deferred. We also have the return type avaialable (unless it's
+ deduced), so we don't need to parse the postcondition in terms of a
+ placeholder. */
+
+static tree
+cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute)
+{
+ gcc_assert (contract_attribute_p (attribute));
+ cp_token *token = cp_lexer_consume_token (parser->lexer);
+ location_t loc = token->location;
+
+ bool assertion_p = is_attribute_p ("assert", attribute);
+ bool postcondition_p = is_attribute_p ("post", attribute);
+
+ /* Parse the optional mode. */
+ tree mode = cp_parser_contract_mode_opt (parser, postcondition_p);
+
+ /* Check for postcondition identifiers. */
+ cp_expr identifier;
+ if (postcondition_p && cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ identifier = cp_parser_identifier (parser);
+ if (identifier == error_mark_node)
+ return error_mark_node;
+
+ cp_parser_require (parser, CPP_COLON, RT_COLON);
+
+ /* Defer the parsing of pre/post contracts inside class definitions. */
+ tree contract;
+ if (!assertion_p &&
+ current_class_type &&
+ TYPE_BEING_DEFINED (current_class_type))
+ {
+ /* Skip until we reach an unenclose ']'. If we ran into an unnested ']'
+ that doesn't close the attribute, return an error and let the attribute
+ handling code emit an error for missing ']]'. */
+ cp_token *first = cp_lexer_peek_token (parser->lexer);
+ cp_parser_skip_to_closing_parenthesis_1 (parser,
+ /*recovering=*/false,
+ CPP_CLOSE_SQUARE,
+ /*consume_paren=*/false);
+ if (cp_lexer_peek_token (parser->lexer)->type != CPP_CLOSE_SQUARE
+ || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_CLOSE_SQUARE)
+ return error_mark_node;
+ cp_token *last = cp_lexer_peek_token (parser->lexer);
+
+ /* Build a deferred-parse node. */
+ tree condition = make_node (DEFERRED_PARSE);
+ DEFPARSE_TOKENS (condition) = cp_token_cache_new (first, last);
+ DEFPARSE_INSTANTIATIONS (condition) = NULL;
+
+ /* And its corresponding contract. */
+ contract = grok_contract (attribute, mode, identifier, condition, loc);
+ }
+ else
+ {
+ /* Enable location wrappers when parsing contracts. */
+ auto suppression = make_temp_override (suppress_location_wrappers, 0);
+
+ /* Build a fake variable for the result identifier. */
+ tree result = NULL_TREE;
+ if (identifier)
+ {
+ begin_scope (sk_block, NULL_TREE);
+ result = make_postcondition_variable (identifier);
+ ++processing_template_decl;
+ }
+
+ /* Parse the condition, ensuring that parameters or the return variable
+ aren't flagged for use outside the body of a function. */
+ ++processing_contract_condition;
+ cp_expr condition = cp_parser_conditional_expression (parser);
+ --processing_contract_condition;
+
+ /* Try to recover from errors by scanning up to the end of the
+ attribute. Sometimes we get partially parsed expressions, so
+ we need to search the condition for errors. */
+ if (contains_error_p (condition))
+ cp_parser_skip_up_to_closing_square_bracket (parser);
+
+ /* Build the contract. */
+ contract = grok_contract (attribute, mode, result, condition, loc);
+
+ /* Leave our temporary scope for the postcondition result. */
+ if (result)
+ {
+ --processing_template_decl;
+ pop_bindings_and_leave_scope ();
+ }
+ }
+
+ if (!flag_contracts)
+ {
+ error_at (loc, "contracts are only available with %<-fcontracts%>");
+ return error_mark_node;
+ }
+
+ return finish_contract_attribute (attribute, contract);
+}
+
+/* Parse a contract condition for a deferred contract. */
+
+void cp_parser_late_contract_condition (cp_parser *parser,
+ tree fn,
+ tree attribute)
+{
+ tree contract = TREE_VALUE (TREE_VALUE (attribute));
+
+ /* Make sure we've gotten something that hasn't been parsed yet or that
+ we're not parsing an invalid contract. */
+ tree condition = CONTRACT_CONDITION (contract);
+ if (TREE_CODE (condition) != DEFERRED_PARSE)
+ return;
+
+ tree identifier = NULL_TREE;
+ if (TREE_CODE (contract) == POSTCONDITION_STMT)
+ identifier = POSTCONDITION_IDENTIFIER (contract);
+
+ /* Build a fake variable for the result identifier. */
+ tree result = NULL_TREE;
+ if (identifier)
+ {
+ /* TODO: Can we guarantee that the identifier has a location? */
+ location_t loc = cp_expr_location (contract);
+ tree type = TREE_TYPE (TREE_TYPE (fn));
+ if (!check_postcondition_result (fn, type, loc))
+ {
+ invalidate_contract (contract);
+ return;
+ }
+
+ begin_scope (sk_block, NULL_TREE);
+ result = make_postcondition_variable (identifier, type);
+ ++processing_template_decl;
+ }
+
+ /* 'this' is not allowed in preconditions of constructors or in postconditions
+ of destructors. Note that the previous value of this variable is
+ established by the calling function, so we need to save it here. */
+ tree saved_ccr = current_class_ref;
+ tree saved_ccp = current_class_ptr;
+ if ((DECL_CONSTRUCTOR_P (fn) && PRECONDITION_P (contract)) ||
+ (DECL_DESTRUCTOR_P (fn) && POSTCONDITION_P (contract)))
+ {
+ current_class_ref = current_class_ptr = NULL_TREE;
+ parser->local_variables_forbidden_p |= THIS_FORBIDDEN;
+ }
+
+ push_unparsed_function_queues (parser);
+
+ /* Push the saved tokens onto the parser's lexer stack. */
+ cp_token_cache *tokens = DEFPARSE_TOKENS (condition);
+ cp_parser_push_lexer_for_tokens (parser, tokens);
+
+ /* Parse the condition, ensuring that parameters or the return variable
+ aren't flagged for use outside the body of a function. */
+ ++processing_contract_condition;
+ condition = cp_parser_conditional_expression (parser);
+ --processing_contract_condition;
+
+ /* Revert to the main lexer. */
+ cp_parser_pop_lexer (parser);
+
+ /* Restore the queue. */
+ pop_unparsed_function_queues (parser);
+
+ current_class_ref = saved_ccr;
+ current_class_ptr = saved_ccp;
+
+ /* Commit to changes. */
+ update_late_contract (contract, result, condition);
+
+ /* Leave our temporary scope for the postcondition result. */
+ if (result)
+ {
+ --processing_template_decl;
+ pop_bindings_and_leave_scope ();
+ }
+}
+
/* Parse a standard C++-11 attribute specifier.
attribute-specifier:
[ [ attribute-using-prefix [opt] attribute-list ] ]
+ contract-attribute-specifier
alignment-specifier
attribute-using-prefix:
@@ -29327,7 +29798,15 @@ cp_parser_std_attribute_list (cp_parser *parser, tree attr_ns)
alignment-specifier:
alignas ( type-id ... [opt] )
- alignas ( alignment-expression ... [opt] ). */
+ alignas ( alignment-expression ... [opt] ).
+
+ Extensions for contracts:
+
+ contract-attribute-specifier:
+ [ [ assert : contract-mode [opt] : conditional-expression ] ]
+ [ [ pre : contract-mode [opt] : conditional-expression ] ]
+ [ [ post : contract-mode [opt] identifier [opt] :
+ conditional-expression ] ] */
static tree
cp_parser_std_attribute_spec (cp_parser *parser)
@@ -29339,10 +29818,27 @@ cp_parser_std_attribute_spec (cp_parser *parser)
&& cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_OPEN_SQUARE)
{
tree attr_ns = NULL_TREE;
+ tree attr_name = NULL_TREE;
cp_lexer_consume_token (parser->lexer);
cp_lexer_consume_token (parser->lexer);
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_NAME)
+ {
+ attr_name = token->u.value;
+ attr_name = canonicalize_attr_name (attr_name);
+ }
+
+ /* Handle contract-attribute-specs specially. */
+ if (attr_name && contract_attribute_p (attr_name))
+ {
+ tree attrs = cp_parser_contract_attribute_spec (parser, attr_name);
+ if (attrs != error_mark_node)
+ attributes = attrs;
+ goto finish_attrs;
+ }
+
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
{
token = cp_lexer_peek_nth_token (parser->lexer, 2);
@@ -29371,6 +29867,7 @@ cp_parser_std_attribute_spec (cp_parser *parser)
attributes = cp_parser_std_attribute_list (parser, attr_ns);
+ finish_attrs:
if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE)
|| !cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
cp_parser_skip_to_end_of_statement (parser);
@@ -29672,6 +30169,8 @@ cp_parser_concept_definition (cp_parser *parser)
return NULL_TREE;
}
+ tree attrs = cp_parser_attributes_opt (parser);
+
if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
{
cp_parser_skip_to_end_of_statement (parser);
@@ -29688,7 +30187,7 @@ cp_parser_concept_definition (cp_parser *parser)
but continue as if it were. */
cp_parser_consume_semicolon_at_end_of_statement (parser);
- return finish_concept_definition (id, init);
+ return finish_concept_definition (id, init, attrs);
}
// -------------------------------------------------------------------------- //
@@ -30243,7 +30742,20 @@ cp_parser_requirement (cp_parser *parser)
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
return cp_parser_compound_requirement (parser);
else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
- return cp_parser_type_requirement (parser);
+ {
+ /* It's probably a type-requirement. */
+ cp_parser_parse_tentatively (parser);
+ tree req = cp_parser_type_requirement (parser);
+ if (cp_parser_parse_definitely (parser))
+ return req;
+ /* No, maybe it's something like typename T::type(); */
+ cp_parser_parse_tentatively (parser);
+ req = cp_parser_simple_requirement (parser);
+ if (cp_parser_parse_definitely (parser))
+ return req;
+ /* Non-tentative for the error. */
+ return cp_parser_type_requirement (parser);
+ }
else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_REQUIRES))
return cp_parser_nested_requirement (parser);
else
@@ -31449,10 +31961,11 @@ cp_parser_template_declaration_after_parameters (cp_parser* parser,
else if (cxx_dialect >= cxx11
&& cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
decl = cp_parser_alias_declaration (parser);
- else if (cxx_dialect >= cxx20 /* Implies flag_concept. */
+ else if (flag_concepts
&& cp_lexer_next_token_is_keyword (parser->lexer, RID_CONCEPT)
- && !cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_BOOL))
- /* Allow 'concept bool' to be handled as per the TS. */
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
+ /* -fconcept-ts 'concept bool' syntax is handled below, in
+ cp_parser_single_declaration. */
decl = cp_parser_concept_definition (parser);
else
{
@@ -32394,6 +32907,14 @@ cp_parser_save_default_args (cp_parser* parser, tree decl)
tree spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl));
if (UNPARSED_NOEXCEPT_SPEC_P (spec))
vec_safe_push (unparsed_noexcepts, decl);
+
+ /* Contracts are deferred. */
+ for (tree attr = DECL_ATTRIBUTES (decl); attr; attr = TREE_CHAIN (attr))
+ if (cxx_contract_attribute_p (attr))
+ {
+ vec_safe_push (unparsed_contracts, decl);
+ break;
+ }
}
/* DEFAULT_ARG contains the saved tokens for the initializer of DECL,
@@ -42478,15 +42999,21 @@ cp_convert_omp_range_for (tree &this_pre_body, vec<tree, va_gc> *for_block,
&& !BRACE_ENCLOSED_INITIALIZER_P (init))
{
tree d = decl;
+ tree decomp_first_name = NULL_TREE;
+ unsigned decomp_cnt = 0;
if (decl != error_mark_node && DECL_HAS_VALUE_EXPR_P (decl))
{
tree v = DECL_VALUE_EXPR (decl);
if (TREE_CODE (v) == ARRAY_REF
&& VAR_P (TREE_OPERAND (v, 0))
&& DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
- d = TREE_OPERAND (v, 0);
+ {
+ d = TREE_OPERAND (v, 0);
+ decomp_cnt = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
+ decomp_first_name = decl;
+ }
}
- do_range_for_auto_deduction (d, init);
+ do_range_for_auto_deduction (d, init, decomp_first_name, decomp_cnt);
}
cond = global_namespace;
incr = NULL_TREE;
@@ -42600,8 +43127,16 @@ cp_convert_omp_range_for (tree &this_pre_body, vec<tree, va_gc> *for_block,
tree t = build_x_indirect_ref (input_location, begin, RO_UNARY_STAR,
NULL_TREE, tf_none);
if (!error_operand_p (t))
- TREE_TYPE (orig_decl) = do_auto_deduction (TREE_TYPE (orig_decl),
- t, auto_node);
+ {
+ TREE_TYPE (orig_decl) = do_auto_deduction (TREE_TYPE (orig_decl),
+ t, auto_node);
+ if (decomp_first_name)
+ {
+ ++processing_template_decl;
+ cp_finish_decomp (orig_decl, decomp_first_name, decomp_cnt);
+ --processing_template_decl;
+ }
+ }
}
tree v = make_tree_vec (decomp_cnt + 3);
diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h
index 3e95bfc..5737146 100644
--- a/gcc/cp/parser.h
+++ b/gcc/cp/parser.h
@@ -178,6 +178,9 @@ struct GTY(()) cp_unparsed_functions_entry {
/* Functions with noexcept-specifiers that require post-processing. */
vec<tree, va_gc> *noexcepts;
+
+ /* Functions with contract attributes that require post-processing. */
+ vec<tree, va_gc> *contracts;
};
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index fc6279c..80110da 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -148,8 +148,6 @@ static void add_pending_template (tree);
static tree reopen_tinst_level (struct tinst_level *);
static tree tsubst_initializer_list (tree, tree);
static tree get_partial_spec_bindings (tree, tree, tree);
-static tree coerce_innermost_template_parms (tree, tree, tree, tsubst_flags_t,
- bool = true);
static void tsubst_enum (tree, tree, tree);
static bool check_instantiated_args (tree, tree, tsubst_flags_t);
static int check_non_deducible_conversion (tree, tree, unification_kind_t, int,
@@ -217,7 +215,6 @@ static tree get_underlying_template (tree);
static tree tsubst_attributes (tree, tree, tsubst_flags_t, tree);
static tree canonicalize_expr_argument (tree, tsubst_flags_t);
static tree make_argument_pack (tree);
-static void register_parameter_specializations (tree, tree);
static tree enclosing_instantiation_of (tree tctx);
static void instantiate_body (tree pattern, tree args, tree d, bool nested);
static tree maybe_dependent_member_ref (tree, tree, tsubst_flags_t, tree);
@@ -1968,6 +1965,16 @@ register_local_specialization (tree spec, tree tmpl)
local_specializations->put (tmpl, spec);
}
+/* Registers T as a specialization of itself. This is used to preserve
+ the references to already-parsed parameters when instantiating
+ postconditions. */
+
+void
+register_local_identity (tree t)
+{
+ local_specializations->put (t, t);
+}
+
/* TYPE is a class type. Returns true if TYPE is an explicitly
specialized class. */
@@ -2475,17 +2482,14 @@ determine_specialization (tree template_id,
}
/* It was a specialization of a template. */
- targs = DECL_TI_ARGS (DECL_TEMPLATE_RESULT (TREE_VALUE (templates)));
- if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (targs))
- {
- *targs_out = copy_node (targs);
- SET_TMPL_ARGS_LEVEL (*targs_out,
- TMPL_ARGS_DEPTH (*targs_out),
- TREE_PURPOSE (templates));
- }
- else
- *targs_out = TREE_PURPOSE (templates);
- return TREE_VALUE (templates);
+ tree tmpl = TREE_VALUE (templates);
+ *targs_out = add_outermost_template_args (tmpl, TREE_PURPOSE (templates));
+
+ /* Propagate the template's constraints to the declaration. */
+ if (tsk != tsk_template)
+ set_constraints (decl, get_constraints (tmpl));
+
+ return tmpl;
}
/* Returns a chain of parameter types, exactly like the SPEC_TYPES,
@@ -3161,8 +3165,10 @@ check_explicit_specialization (tree declarator,
parm = DECL_CHAIN (parm))
DECL_CONTEXT (parm) = result;
}
- return register_specialization (tmpl, gen_tmpl, targs,
+ decl = register_specialization (tmpl, gen_tmpl, targs,
is_friend, 0);
+ remove_contract_attributes (result);
+ return decl;
}
/* Set up the DECL_TEMPLATE_INFO for DECL. */
@@ -3262,6 +3268,10 @@ check_explicit_specialization (tree declarator,
is_friend, 0);
}
+ /* If this is a specialization, splice any contracts that may have
+ been inherited from the template, removing them. */
+ if (decl != error_mark_node && DECL_TEMPLATE_SPECIALIZATION (decl))
+ remove_contract_attributes (decl);
/* A 'structor should already have clones. */
gcc_assert (decl == error_mark_node
@@ -3772,8 +3782,7 @@ expand_integer_pack (tree call, tree args, tsubst_flags_t complain,
tree in_decl)
{
tree ohi = CALL_EXPR_ARG (call, 0);
- tree hi = tsubst_copy_and_build (ohi, args, complain, in_decl,
- false/*fn*/, true/*int_cst*/);
+ tree hi = tsubst_copy_and_build (ohi, args, complain, in_decl);
if (instantiation_dependent_expression_p (hi))
{
@@ -4483,18 +4492,23 @@ struct ctp_hasher : ggc_ptr_hash<tree_node>
{
static hashval_t hash (tree t)
{
+ ++comparing_specializations;
tree_code code = TREE_CODE (t);
hashval_t val = iterative_hash_object (code, 0);
val = iterative_hash_object (TEMPLATE_TYPE_LEVEL (t), val);
val = iterative_hash_object (TEMPLATE_TYPE_IDX (t), val);
if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
val = iterative_hash_template_arg (TYPE_TI_ARGS (t), val);
+ --comparing_specializations;
return val;
}
static bool equal (tree t, tree u)
{
- return comptypes (t, u, COMPARE_STRUCTURAL);
+ ++comparing_specializations;
+ bool eq = comptypes (t, u, COMPARE_STRUCTURAL);
+ --comparing_specializations;
+ return eq;
}
};
@@ -6360,9 +6374,7 @@ instantiate_non_dependent_expr_internal (tree expr, tsubst_flags_t complain)
return tsubst_copy_and_build (expr,
/*args=*/NULL_TREE,
complain,
- /*in_decl=*/NULL_TREE,
- /*function_p=*/false,
- /*integral_constant_expression_p=*/true);
+ /*in_decl=*/NULL_TREE);
}
/* Instantiate the non-dependent expression EXPR. */
@@ -8830,6 +8842,14 @@ pack_expansion_args_count (tree args)
arguments. If any error occurs, return error_mark_node. Error and
warning messages are issued under control of COMPLAIN.
+ If PARMS represents all template parameters levels, this function
+ returns a vector of vectors representing all the resulting argument
+ levels. Note that in this case, only the innermost arguments are
+ coerced because the outermost ones are supposed to have been coerced
+ already. Otherwise, if PARMS represents only (the innermost) vector
+ of parameters, this function returns a vector containing just the
+ innermost resulting arguments.
+
If REQUIRE_ALL_ARGS is false, argument deduction will be performed
for arguments not specified in ARGS. If REQUIRE_ALL_ARGS is true,
arguments not specified in ARGS must have default arguments which
@@ -8845,8 +8865,6 @@ coerce_template_parms (tree parms,
int nparms, nargs, parm_idx, arg_idx, lost = 0;
tree orig_inner_args;
tree inner_args;
- tree new_args;
- tree new_inner_args;
/* When used as a boolean value, indicates whether this is a
variadic template parameter list. Since it's an int, we can also
@@ -8867,6 +8885,17 @@ coerce_template_parms (tree parms,
if (args == error_mark_node)
return error_mark_node;
+ bool return_full_args = false;
+ if (TREE_CODE (parms) == TREE_LIST)
+ {
+ if (TMPL_PARMS_DEPTH (parms) > 1)
+ {
+ gcc_assert (TMPL_PARMS_DEPTH (parms) == TMPL_ARGS_DEPTH (args));
+ return_full_args = true;
+ }
+ parms = INNERMOST_TEMPLATE_PARMS (parms);
+ }
+
nparms = TREE_VEC_LENGTH (parms);
/* Determine if there are any parameter packs or default arguments. */
@@ -8964,8 +8993,8 @@ coerce_template_parms (tree parms,
template-id may be nested within a "sizeof". */
cp_evaluated ev;
- new_inner_args = make_tree_vec (nparms);
- new_args = add_outermost_template_args (args, new_inner_args);
+ tree new_args = add_outermost_template_args (args, make_tree_vec (nparms));
+ tree& new_inner_args = TMPL_ARGS_LEVEL (new_args, TMPL_ARGS_DEPTH (new_args));
int pack_adjust = 0;
for (parm_idx = 0, arg_idx = 0; parm_idx < nparms; parm_idx++, arg_idx++)
{
@@ -9167,59 +9196,7 @@ coerce_template_parms (tree parms,
SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args,
TREE_VEC_LENGTH (new_inner_args));
- return new_inner_args;
-}
-
-/* Like coerce_template_parms. If PARMS represents all template
- parameters levels, this function returns a vector of vectors
- representing all the resulting argument levels. Note that in this
- case, only the innermost arguments are coerced because the
- outermost ones are supposed to have been coerced already.
-
- Otherwise, if PARMS represents only (the innermost) vector of
- parameters, this function returns a vector containing just the
- innermost resulting arguments. */
-
-static tree
-coerce_innermost_template_parms (tree parms,
- tree args,
- tree in_decl,
- tsubst_flags_t complain,
- bool require_all_args /* = true */)
-{
- int parms_depth = TMPL_PARMS_DEPTH (parms);
- int args_depth = TMPL_ARGS_DEPTH (args);
- tree coerced_args;
-
- if (parms_depth > 1)
- {
- coerced_args = make_tree_vec (parms_depth);
- tree level;
- int cur_depth;
-
- for (level = parms, cur_depth = parms_depth;
- parms_depth > 0 && level != NULL_TREE;
- level = TREE_CHAIN (level), --cur_depth)
- {
- tree l;
- if (cur_depth == args_depth)
- l = coerce_template_parms (TREE_VALUE (level),
- args, in_decl, complain,
- require_all_args);
- else
- l = TMPL_ARGS_LEVEL (args, cur_depth);
-
- if (l == error_mark_node)
- return error_mark_node;
-
- SET_TMPL_ARGS_LEVEL (coerced_args, cur_depth, l);
- }
- }
- else
- coerced_args = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parms),
- args, in_decl, complain,
- require_all_args);
- return coerced_args;
+ return return_full_args ? new_args : new_inner_args;
}
/* Returns true if T is a wrapper to make a C++20 template parameter
@@ -9912,8 +9889,7 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context,
/* Calculate the BOUND_ARGS. These will be the args that are
actually tsubst'd into the definition to create the
instantiation. */
- arglist = coerce_innermost_template_parms (parmlist, arglist, gen_tmpl,
- complain);
+ arglist = coerce_template_parms (parmlist, arglist, gen_tmpl, complain);
if (arglist == error_mark_node)
/* We were unable to bind the arguments. */
@@ -10329,7 +10305,7 @@ finish_template_variable (tree var, tsubst_flags_t complain)
tree arglist = TREE_OPERAND (var, 1);
tree parms = DECL_TEMPLATE_PARMS (templ);
- arglist = coerce_innermost_template_parms (parms, arglist, templ, complain);
+ arglist = coerce_template_parms (parms, arglist, templ, complain);
if (arglist == error_mark_node)
return error_mark_node;
@@ -10597,21 +10573,6 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
return error_mark_node;
break;
- case REQUIRES_EXPR:
- {
- if (!fn)
- return error_mark_node;
-
- /* Recursively walk the type of each constraint variable. */
- tree p = TREE_OPERAND (t, 0);
- while (p)
- {
- WALK_SUBTREE (TREE_TYPE (p));
- p = TREE_CHAIN (p);
- }
- }
- break;
-
default:
break;
}
@@ -11196,8 +11157,7 @@ tsubst_friend_function (tree decl, tree args)
current class with same name. */
push_nested_namespace (ns);
fns = tsubst_expr (DECL_TI_TEMPLATE (decl), args,
- tf_warning_or_error, NULL_TREE,
- /*integral_constant_expression_p=*/false);
+ tf_warning_or_error, NULL_TREE);
pop_nested_namespace (ns);
arglist = tsubst (DECL_TI_ARGS (decl), args,
tf_warning_or_error, NULL_TREE);
@@ -11284,6 +11244,9 @@ tsubst_friend_function (tree decl, tree args)
not_tmpl = DECL_TEMPLATE_RESULT (new_friend);
new_friend_result_template_info = DECL_TEMPLATE_INFO (not_tmpl);
}
+ else if (!constraints_satisfied_p (new_friend))
+ /* Only define a constrained hidden friend when satisfied. */
+ return error_mark_node;
/* Inside pushdecl_namespace_level, we will push into the
current namespace. However, the friend function should go
@@ -11576,6 +11539,113 @@ can_complete_type_without_circularity (tree type)
static tree tsubst_omp_clauses (tree, enum c_omp_region_type, tree,
tsubst_flags_t, tree);
+/* Instantiate the contract statement. */
+
+static tree
+tsubst_contract (tree decl, tree t, tree args, tsubst_flags_t complain,
+ tree in_decl)
+{
+ tree type = decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE;
+ bool auto_p = type_uses_auto (type);
+
+ tree r = copy_node (t);
+
+ /* Rebuild the result variable. */
+ if (type && POSTCONDITION_P (t) && POSTCONDITION_IDENTIFIER (t))
+ {
+ tree oldvar = POSTCONDITION_IDENTIFIER (t);
+
+ tree newvar = copy_node (oldvar);
+ TREE_TYPE (newvar) = type;
+ DECL_CONTEXT (newvar) = decl;
+ POSTCONDITION_IDENTIFIER (r) = newvar;
+
+ /* Make sure the postcondition is valid. */
+ location_t loc = DECL_SOURCE_LOCATION (oldvar);
+ if (!auto_p)
+ if (!check_postcondition_result (decl, type, loc))
+ return invalidate_contract (r);
+
+ /* Make the variable available for lookup. */
+ register_local_specialization (newvar, oldvar);
+ }
+
+ /* Instantiate the condition. If the return type is undeduced, process
+ the expression as if inside a template to avoid spurious type errors. */
+ if (auto_p)
+ ++processing_template_decl;
+ ++processing_contract_condition;
+ CONTRACT_CONDITION (r)
+ = tsubst_expr (CONTRACT_CONDITION (t), args, complain, in_decl);
+ --processing_contract_condition;
+ if (auto_p)
+ --processing_template_decl;
+
+ /* And the comment. */
+ CONTRACT_COMMENT (r)
+ = tsubst_expr (CONTRACT_COMMENT (r), args, complain, in_decl);
+
+ return r;
+}
+
+/* Update T by instantiating its contract attribute. */
+
+static void
+tsubst_contract_attribute (tree decl, tree t, tree args,
+ tsubst_flags_t complain, tree in_decl)
+{
+ /* For non-specializations, adjust the current declaration to the most general
+ version of in_decl. Because we defer the instantiation of contracts as long
+ as possible, they are still written in terms of the parameters (and return
+ type) of the most general template. */
+ tree tmpl = DECL_TI_TEMPLATE (in_decl);
+ if (!DECL_TEMPLATE_SPECIALIZATION (tmpl))
+ in_decl = DECL_TEMPLATE_RESULT (most_general_template (in_decl));
+ local_specialization_stack specs (lss_copy);
+ register_parameter_specializations (in_decl, decl);
+
+ /* Get the contract to be instantiated. */
+ tree contract = CONTRACT_STATEMENT (t);
+
+ /* Use the complete set of template arguments for instantiation. The
+ contract may not have been instantiated and still refer to outer levels
+ of template parameters. */
+ args = DECL_TI_ARGS (decl);
+
+ /* For member functions, make this available for semantic analysis. */
+ tree save_ccp = current_class_ptr;
+ tree save_ccr = current_class_ref;
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ {
+ tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ tree this_type = TREE_TYPE (TREE_VALUE (arg_types));
+ inject_this_parameter (this_type, cp_type_quals (this_type));
+ }
+
+ contract = tsubst_contract (decl, contract, args, complain, in_decl);
+
+ current_class_ptr = save_ccp;
+ current_class_ref = save_ccr;
+
+ /* Rebuild the attribute. */
+ TREE_VALUE (t) = build_tree_list (NULL_TREE, contract);
+}
+
+/* Rebuild the attribute list for DECL, substituting into contracts
+ as needed. */
+
+void
+tsubst_contract_attributes (tree decl, tree args, tsubst_flags_t complain, tree in_decl)
+{
+ tree list = copy_list (DECL_ATTRIBUTES (decl));
+ for (tree attr = list; attr; attr = CONTRACT_CHAIN (attr))
+ {
+ if (cxx_contract_attribute_p (attr))
+ tsubst_contract_attribute (decl, attr, args, complain, in_decl);
+ }
+ DECL_ATTRIBUTES (decl) = list;
+}
+
/* Instantiate a single dependent attribute T (a TREE_LIST), and return either
T or a new TREE_LIST, possibly a chain in the case of a pack expansion. */
@@ -11585,6 +11655,10 @@ tsubst_attribute (tree t, tree *decl_p, tree args,
{
gcc_assert (ATTR_IS_DEPENDENT (t));
+ /* Note that contract attributes are never substituted from this function.
+ Their instantiation is triggered by regenerate_from_template_decl when
+ we instantiate the body of the function. */
+
tree val = TREE_VALUE (t);
if (val == NULL_TREE)
/* Nothing to do. */;
@@ -11610,9 +11684,7 @@ tsubst_attribute (tree t, tree *decl_p, tree args,
get_attribute_name (t)))
{
++cp_unevaluated_operand;
- tree varid
- = tsubst_expr (TREE_PURPOSE (val), args, complain,
- in_decl, /*integral_constant_expression_p=*/false);
+ tree varid = tsubst_expr (TREE_PURPOSE (val), args, complain, in_decl);
--cp_unevaluated_operand;
tree chain = TREE_CHAIN (val);
location_t match_loc = cp_expr_loc_or_input_loc (TREE_PURPOSE (chain));
@@ -11648,7 +11720,7 @@ tsubst_attribute (tree t, tree *decl_p, tree args,
tree v = TREE_VALUE (t3);
if (TREE_CODE (v) == STRING_CST && allow_string)
continue;
- v = tsubst_expr (v, args, complain, in_decl, true);
+ v = tsubst_expr (v, args, complain, in_decl);
v = fold_non_dependent_expr (v);
if (!INTEGRAL_TYPE_P (TREE_TYPE (v))
|| (TREE_PURPOSE (t3) == score
@@ -11694,8 +11766,7 @@ tsubst_attribute (tree t, tree *decl_p, tree args,
else if (attribute_takes_identifier_p (get_attribute_name (t)))
{
tree chain
- = tsubst_expr (TREE_CHAIN (val), args, complain, in_decl,
- /*integral_constant_expression_p=*/false);
+ = tsubst_expr (TREE_CHAIN (val), args, complain, in_decl);
if (chain != TREE_CHAIN (val))
val = tree_cons (NULL_TREE, TREE_VALUE (val), chain);
}
@@ -11718,8 +11789,7 @@ tsubst_attribute (tree t, tree *decl_p, tree args,
return list;
}
else
- val = tsubst_expr (val, args, complain, in_decl,
- /*integral_constant_expression_p=*/false);
+ val = tsubst_expr (val, args, complain, in_decl);
if (val == error_mark_node)
return error_mark_node;
@@ -12161,8 +12231,7 @@ instantiate_class_template (tree type)
{
/* Build new TYPE_FIELDS. */
if (TREE_CODE (t) == STATIC_ASSERT)
- tsubst_expr (t, args, tf_warning_or_error, NULL_TREE,
- /*integral_constant_expression_p=*/true);
+ tsubst_expr (t, args, tf_warning_or_error, NULL_TREE);
else if (TREE_CODE (t) != CONST_DECL)
{
tree r;
@@ -12419,8 +12488,7 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
if (!(complain & tf_warning))
++c_inhibit_evaluation_warnings;
- r = tsubst_expr (t, args, complain, in_decl,
- /*integral_constant_expression_p=*/true);
+ r = tsubst_expr (t, args, complain, in_decl);
if (!(complain & tf_warning))
--c_inhibit_evaluation_warnings;
}
@@ -12684,8 +12752,7 @@ gen_elem_of_pack_expansion_instantiation (tree pattern,
else if (pattern == error_mark_node)
t = error_mark_node;
else if (!TYPE_P (pattern))
- t = tsubst_expr (pattern, args, complain, in_decl,
- /*integral_constant_expression_p=*/false);
+ t = tsubst_expr (pattern, args, complain, in_decl);
else
{
t = tsubst (pattern, args, complain, in_decl);
@@ -12779,7 +12846,7 @@ tsubst_fold_expr_pack (tree t, tree args, tsubst_flags_t complain, tree in_decl)
static inline tree
tsubst_fold_expr_init (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
- return tsubst_expr (FOLD_EXPR_INIT (t), args, complain, in_decl, false);
+ return tsubst_expr (FOLD_EXPR_INIT (t), args, complain, in_decl);
}
/* Expand a PACK of arguments into a grouped as left fold.
@@ -13148,12 +13215,12 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
if (BASES_DIRECT (parm_pack))
return calculate_direct_bases (tsubst_expr (BASES_TYPE (parm_pack),
args, complain,
- in_decl, false),
+ in_decl),
complain);
else
return calculate_bases (tsubst_expr (BASES_TYPE (parm_pack),
- args, complain, in_decl,
- false), complain);
+ args, complain, in_decl),
+ complain);
}
else if (builtin_pack_call_p (parm_pack))
{
@@ -13327,8 +13394,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
pattern and return a PACK_EXPANSION_*. The caller will need to
deal with that. */
if (TREE_CODE (t) == EXPR_PACK_EXPANSION)
- result = tsubst_expr (pattern, args, complain, in_decl,
- /*integral_constant_expression_p=*/false);
+ result = tsubst_expr (pattern, args, complain, in_decl);
else
result = tsubst (pattern, args, complain, in_decl);
result = make_pack_expansion (result, complain);
@@ -13902,9 +13968,7 @@ tsubst_default_argument (tree fn, int parmnum, tree type, tree arg,
the body of function so as to avoid collecting live data on the
stack. */
++function_depth;
- arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
- complain, NULL_TREE,
- /*integral_constant_expression_p=*/false);
+ arg = tsubst_expr (arg, DECL_TI_ARGS (fn), complain, NULL_TREE);
--function_depth;
finish_lambda_scope ();
@@ -14209,9 +14273,7 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain,
if (DECL_HAS_DEPENDENT_EXPLICIT_SPEC_P (t))
{
tree spec = lookup_explicit_specifier (t);
- spec = tsubst_copy_and_build (spec, args, complain, in_decl,
- /*function_p=*/false,
- /*i_c_e_p=*/true);
+ spec = tsubst_copy_and_build (spec, args, complain, in_decl);
spec = build_explicit_specifier (spec, complain);
if (spec == error_mark_node)
return error_mark_node;
@@ -14823,8 +14885,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
number of bits. */
DECL_BIT_FIELD_REPRESENTATIVE (r)
= tsubst_expr (DECL_BIT_FIELD_REPRESENTATIVE (t), args,
- complain, in_decl,
- /*integral_constant_expression_p=*/true);
+ complain, in_decl);
if (DECL_INITIAL (t))
{
/* Set up DECL_TEMPLATE_INFO so that we can get at the
@@ -14976,7 +15037,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
/* We're fully specializing a template declaration, so
we need to coerce the innermost arguments corresponding to
the template. */
- argvec = (coerce_innermost_template_parms
+ argvec = (coerce_template_parms
(DECL_TEMPLATE_PARMS (gen_tmpl),
argvec, t, complain));
if (argvec == error_mark_node)
@@ -15076,8 +15137,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
bool nop = (TREE_CODE (ve) == NOP_EXPR);
if (nop)
ve = TREE_OPERAND (ve, 0);
- ve = tsubst_expr (ve, args, complain, in_decl,
- /*constant_expression_p=*/false);
+ ve = tsubst_expr (ve, args, complain, in_decl);
if (REFERENCE_REF_P (ve))
{
gcc_assert (TYPE_REF_P (type));
@@ -15275,8 +15335,7 @@ tsubst_arg_types (tree arg_types,
if (lambda_fn_in_template_p (in_decl)
|| (in_decl && TREE_CODE (in_decl) == FUNCTION_DECL
&& DECL_LOCAL_DECL_P (in_decl)))
- default_arg = tsubst_copy_and_build (default_arg, args, complain, in_decl,
- false/*fn*/, false/*constexpr*/);
+ default_arg = tsubst_copy_and_build (default_arg, args, complain, in_decl);
tree remaining_arg_types = tsubst_arg_types (TREE_CHAIN (arg_types),
args, end, complain, in_decl);
@@ -15457,9 +15516,7 @@ tsubst_exception_specification (tree fntype,
args);
expr = DEFERRED_NOEXCEPT_PATTERN (expr);
}
- new_specs = tsubst_copy_and_build
- (expr, args, complain, in_decl, /*function_p=*/false,
- /*integral_constant_expression_p=*/true);
+ new_specs = tsubst_copy_and_build (expr, args, complain, in_decl);
}
new_specs = build_noexcept_spec (new_specs, complain);
/* We've instantiated a template before a noexcept-specifier
@@ -15766,8 +15823,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
- max = tsubst_expr (omax, args, complain, in_decl,
- /*integral_constant_expression_p=*/false);
+ max = tsubst_expr (omax, args, complain, in_decl);
/* Fix up type of the magic NOP_EXPR with TREE_SIDE_EFFECTS if
needed. */
@@ -16360,9 +16416,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
++cp_unevaluated_operand;
++c_inhibit_evaluation_warnings;
- type = tsubst_expr (TYPEOF_TYPE_EXPR (t), args,
- complain, in_decl,
- /*integral_constant_expression_p=*/false);
+ type = tsubst_expr (TYPEOF_TYPE_EXPR (t), args, complain, in_decl);
--cp_unevaluated_operand;
--c_inhibit_evaluation_warnings;
@@ -16382,9 +16436,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
++c_inhibit_evaluation_warnings;
type = tsubst_copy_and_build (DECLTYPE_TYPE_EXPR (t), args,
- complain|tf_decltype, in_decl,
- /*function_p*/false,
- /*integral_constant_expression*/false);
+ complain|tf_decltype, in_decl);
--cp_unevaluated_operand;
--c_inhibit_evaluation_warnings;
@@ -16843,7 +16895,7 @@ tsubst_init (tree init, tree decl, tree args,
if (!init)
return NULL_TREE;
- init = tsubst_expr (init, args, complain, in_decl, false);
+ init = tsubst_expr (init, args, complain, in_decl);
tree type = TREE_TYPE (decl);
@@ -16999,13 +17051,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (DECL_TEMPLATE_PARM_P (t))
return tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
- /* There is no need to substitute into namespace-scope
- enumerators. */
- if (DECL_NAMESPACE_SCOPE_P (t))
+ if (!uses_template_parms (DECL_CONTEXT (t)))
return t;
- /* If ARGS is NULL, then T is known to be non-dependent. */
- if (args == NULL_TREE)
- return scalar_constant_value (t);
/* Unfortunately, we cannot just call lookup_name here.
Consider:
@@ -17131,7 +17178,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
= do_auto_deduction (TREE_TYPE (r), init, auto_node,
complain, adc_variable_type);
}
- gcc_assert (cp_unevaluated_operand || TREE_STATIC (r)
+ gcc_assert (cp_unevaluated_operand
+ || processing_contract_condition
+ || TREE_STATIC (r)
|| decl_constant_var_p (r)
|| seen_error ());
if (!processing_template_decl
@@ -17680,9 +17729,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
return t;
case CO_AWAIT_EXPR:
- return tsubst_expr (t, args, complain, in_decl,
- /*integral_constant_expression_p=*/false);
- break;
+ return tsubst_expr (t, args, complain, in_decl);
default:
/* We shouldn't get here, but keep going if !flag_checking. */
@@ -17722,14 +17769,11 @@ tsubst_omp_clause_decl (tree decl, tree args, tsubst_flags_t complain,
DECL_CONTEXT (TREE_VEC_ELT (*tp, 0)) = current_function_decl;
pushdecl (TREE_VEC_ELT (*tp, 0));
TREE_VEC_ELT (*tp, 1)
- = tsubst_expr (TREE_VEC_ELT (it, 1), args, complain, in_decl,
- /*integral_constant_expression_p=*/false);
+ = tsubst_expr (TREE_VEC_ELT (it, 1), args, complain, in_decl);
TREE_VEC_ELT (*tp, 2)
- = tsubst_expr (TREE_VEC_ELT (it, 2), args, complain, in_decl,
- /*integral_constant_expression_p=*/false);
+ = tsubst_expr (TREE_VEC_ELT (it, 2), args, complain, in_decl);
TREE_VEC_ELT (*tp, 3)
- = tsubst_expr (TREE_VEC_ELT (it, 3), args, complain, in_decl,
- /*integral_constant_expression_p=*/false);
+ = tsubst_expr (TREE_VEC_ELT (it, 3), args, complain, in_decl);
TREE_CHAIN (*tp) = NULL_TREE;
tp = &TREE_CHAIN (*tp);
}
@@ -17751,10 +17795,8 @@ tsubst_omp_clause_decl (tree decl, tree args, tsubst_flags_t complain,
if (TREE_CODE (decl) == TREE_LIST)
{
tree low_bound
- = tsubst_expr (TREE_PURPOSE (decl), args, complain, in_decl,
- /*integral_constant_expression_p=*/false);
- tree length = tsubst_expr (TREE_VALUE (decl), args, complain, in_decl,
- /*integral_constant_expression_p=*/false);
+ = tsubst_expr (TREE_PURPOSE (decl), args, complain, in_decl);
+ tree length = tsubst_expr (TREE_VALUE (decl), args, complain, in_decl);
tree chain = tsubst_omp_clause_decl (TREE_CHAIN (decl), args, complain,
in_decl, NULL);
if (TREE_PURPOSE (decl) == low_bound
@@ -17766,8 +17808,7 @@ tsubst_omp_clause_decl (tree decl, tree args, tsubst_flags_t complain,
= OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (decl);
return ret;
}
- tree ret = tsubst_expr (decl, args, complain, in_decl,
- /*integral_constant_expression_p=*/false);
+ tree ret = tsubst_expr (decl, args, complain, in_decl);
/* Undo convert_from_reference tsubst_expr could have called. */
if (decl
&& REFERENCE_REF_P (ret)
@@ -17798,8 +17839,8 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
if (OMP_CLAUSE_LASTPRIVATE_STMT (oc))
{
OMP_CLAUSE_LASTPRIVATE_STMT (nc) = push_stmt_list ();
- tsubst_expr (OMP_CLAUSE_LASTPRIVATE_STMT (oc), args, complain,
- in_decl, /*integral_constant_expression_p=*/false);
+ tsubst_expr (OMP_CLAUSE_LASTPRIVATE_STMT (oc), args,
+ complain, in_decl);
OMP_CLAUSE_LASTPRIVATE_STMT (nc)
= pop_stmt_list (OMP_CLAUSE_LASTPRIVATE_STMT (nc));
}
@@ -17832,8 +17873,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (oc))
OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (nc)
= tsubst_expr (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (oc), args,
- complain, in_decl,
- /*integral_constant_expression_p=*/false);
+ complain, in_decl);
/* FALLTHRU */
case OMP_CLAUSE_TILE:
case OMP_CLAUSE_IF:
@@ -17861,8 +17901,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
case OMP_CLAUSE_WAIT:
case OMP_CLAUSE_DETACH:
OMP_CLAUSE_OPERAND (nc, 0)
- = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain,
- in_decl, /*integral_constant_expression_p=*/false);
+ = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain, in_decl);
break;
case OMP_CLAUSE_REDUCTION:
case OMP_CLAUSE_IN_REDUCTION:
@@ -17892,19 +17931,16 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
= tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
in_decl, NULL);
OMP_CLAUSE_OPERAND (nc, 1)
- = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 1), args, complain,
- in_decl, /*integral_constant_expression_p=*/false);
+ = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 1), args, complain, in_decl);
break;
case OMP_CLAUSE_ALLOCATE:
OMP_CLAUSE_DECL (nc)
= tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
in_decl, NULL);
OMP_CLAUSE_OPERAND (nc, 1)
- = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 1), args, complain,
- in_decl, /*integral_constant_expression_p=*/false);
+ = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 1), args, complain, in_decl);
OMP_CLAUSE_OPERAND (nc, 2)
- = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 2), args, complain,
- in_decl, /*integral_constant_expression_p=*/false);
+ = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 2), args, complain, in_decl);
break;
case OMP_CLAUSE_LINEAR:
OMP_CLAUSE_DECL (nc)
@@ -17921,9 +17957,8 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
complain, in_decl, NULL);
else
OMP_CLAUSE_LINEAR_STEP (nc)
- = tsubst_expr (OMP_CLAUSE_LINEAR_STEP (oc), args, complain,
- in_decl,
- /*integral_constant_expression_p=*/false);
+ = tsubst_expr (OMP_CLAUSE_LINEAR_STEP (oc), args,
+ complain, in_decl);
break;
case OMP_CLAUSE_NOWAIT:
case OMP_CLAUSE_DEFAULT:
@@ -18048,9 +18083,7 @@ tsubst_copy_asm_operands (tree t, tree args, tsubst_flags_t complain,
return t;
if (TREE_CODE (t) != TREE_LIST)
- return tsubst_copy_and_build (t, args, complain, in_decl,
- /*function_p=*/false,
- /*integral_constant_expression_p=*/false);
+ return tsubst_copy_and_build (t, args, complain, in_decl);
if (t == void_list_node)
return t;
@@ -18091,12 +18124,10 @@ static tree tsubst_decomp_names (tree, tree, tree, tsubst_flags_t, tree,
static bool
tsubst_omp_for_iterator (tree t, int i, tree declv, tree &orig_declv,
tree initv, tree condv, tree incrv, tree *clauses,
- tree args, tsubst_flags_t complain, tree in_decl,
- bool integral_constant_expression_p)
+ tree args, tsubst_flags_t complain, tree in_decl)
{
#define RECUR(NODE) \
- tsubst_expr ((NODE), args, complain, in_decl, \
- integral_constant_expression_p)
+ tsubst_expr ((NODE), args, complain, in_decl)
tree decl, init, cond = NULL_TREE, incr = NULL_TREE;
bool ret = false;
@@ -18584,13 +18615,11 @@ dependent_operand_p (tree t)
processing. */
tree
-tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
- bool integral_constant_expression_p)
+tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
#define RETURN(EXP) do { r = (EXP); goto out; } while(0)
#define RECUR(NODE) \
- tsubst_expr ((NODE), args, complain, in_decl, \
- integral_constant_expression_p)
+ tsubst_expr ((NODE), args, complain, in_decl)
tree stmt, tmp;
tree r;
@@ -18649,6 +18678,19 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
finish_using_directive (USING_STMT_NAMESPACE (t), /*attribs=*/NULL_TREE);
break;
+ case PRECONDITION_STMT:
+ case POSTCONDITION_STMT:
+ gcc_unreachable ();
+
+ case ASSERTION_STMT:
+ {
+ r = tsubst_contract (NULL_TREE, t, args, complain, in_decl);
+ if (r != error_mark_node)
+ add_stmt (r);
+ RETURN (r);
+ }
+ break;
+
case DECL_EXPR:
{
tree decl, pattern_decl;
@@ -19136,11 +19178,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
tree condition;
++c_inhibit_evaluation_warnings;
- condition =
- tsubst_expr (STATIC_ASSERT_CONDITION (t),
- args,
- complain, in_decl,
- /*integral_constant_expression_p=*/true);
+ condition = tsubst_expr (STATIC_ASSERT_CONDITION (t), args,
+ complain, in_decl);
--c_inhibit_evaluation_warnings;
finish_static_assert (condition,
@@ -19236,8 +19275,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
any_range_for
|= tsubst_omp_for_iterator (t, i, declv, orig_declv, initv,
condv, incrv, &clauses, args,
- complain, in_decl,
- integral_constant_expression_p);
+ complain, in_decl);
omp_parallel_combined_clauses = NULL;
if (any_range_for)
@@ -19635,9 +19673,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
default:
gcc_assert (!STATEMENT_CODE_P (TREE_CODE (t)));
- RETURN (tsubst_copy_and_build (t, args, complain, in_decl,
- /*function_p=*/false,
- integral_constant_expression_p));
+ RETURN (tsubst_copy_and_build (t, args, complain, in_decl));
}
RETURN (NULL_TREE);
@@ -19684,7 +19720,7 @@ tsubst_omp_udr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
DECL_CONTEXT (omp_in) = current_function_decl;
keep_next_level (true);
tree block = begin_omp_structured_block ();
- tsubst_expr (stmts[2], args, complain, in_decl, false);
+ tsubst_expr (stmts[2], args, complain, in_decl);
block = finish_omp_structured_block (block);
block = maybe_cleanup_point_expr_void (block);
add_decl_expr (omp_out);
@@ -19704,7 +19740,7 @@ tsubst_omp_udr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
DECL_CONTEXT (omp_orig) = current_function_decl;
keep_next_level (true);
tree block = begin_omp_structured_block ();
- tsubst_expr (stmts[5], args, complain, in_decl, false);
+ tsubst_expr (stmts[5], args, complain, in_decl);
block = finish_omp_structured_block (block);
block = maybe_cleanup_point_expr_void (block);
cp_walk_tree (&block, cp_remove_omp_priv_cleanup_stmt, omp_priv, NULL);
@@ -19728,9 +19764,7 @@ tsubst_non_call_postfix_expression (tree t, tree args,
t = tsubst_qualified_id (t, args, complain, in_decl,
/*done=*/false, /*address_p=*/false);
else
- t = tsubst_copy_and_build (t, args, complain, in_decl,
- /*function_p=*/false,
- /*integral_constant_expression_p=*/false);
+ t = tsubst_copy_and_build (t, args, complain, in_decl);
return t;
}
@@ -19801,8 +19835,7 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (PACK_EXPANSION_P (init))
init = tsubst_pack_expansion (init, args, complain, in_decl);
else
- init = tsubst_copy_and_build (init, args, complain, in_decl,
- /*fn*/false, /*constexpr*/false);
+ init = tsubst_copy_and_build (init, args, complain, in_decl);
if (init == error_mark_node)
return error_mark_node;
@@ -19912,6 +19945,7 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
goto out;
}
finish_member_declaration (inst);
+ record_lambda_scope_sig_discriminator (r, inst);
tree fn = oldtmpl ? DECL_TEMPLATE_RESULT (inst) : inst;
@@ -19967,7 +20001,7 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
need another to confuse NRV (91217). */
saved = BIND_EXPR_BODY (saved);
- tsubst_expr (saved, args, complain, r, /*constexpr*/false);
+ tsubst_expr (saved, args, complain, r);
finish_lambda_function (body);
@@ -20057,9 +20091,7 @@ maybe_fold_fn_template_args (tree fn, tsubst_flags_t complain)
static void
tsubst_copy_and_build_call_args (tree t, tree args, tsubst_flags_t complain,
- tree in_decl,
- bool integral_constant_expression_p,
- releasing_vec &call_args)
+ tree in_decl, releasing_vec &call_args)
{
unsigned int nargs = call_expr_nargs (t);
for (unsigned int i = 0; i < nargs; ++i)
@@ -20068,9 +20100,7 @@ tsubst_copy_and_build_call_args (tree t, tree args, tsubst_flags_t complain,
if (!PACK_EXPANSION_P (arg))
vec_safe_push (call_args,
- tsubst_copy_and_build (arg, args, complain, in_decl,
- /*function_p=*/false,
- integral_constant_expression_p));
+ tsubst_copy_and_build (arg, args, complain, in_decl));
else
{
/* Expand the pack expansion and push each entry onto CALL_ARGS. */
@@ -20096,22 +20126,17 @@ tsubst_copy_and_build_call_args (tree t, tree args, tsubst_flags_t complain,
}
/* Like tsubst but deals with expressions and performs semantic
- analysis. FUNCTION_P is true if T is the "F" in "F (ARGS)" or
- "F<TARGS> (ARGS)". */
+ analysis. */
tree
tsubst_copy_and_build (tree t,
tree args,
tsubst_flags_t complain,
- tree in_decl,
- bool function_p,
- bool integral_constant_expression_p)
+ tree in_decl)
{
#define RETURN(EXP) do { retval = (EXP); goto out; } while(0)
#define RECUR(NODE) \
- tsubst_copy_and_build (NODE, args, complain, in_decl, \
- /*function_p=*/false, \
- integral_constant_expression_p)
+ tsubst_copy_and_build (NODE, args, complain, in_decl)
tree retval, op1;
location_t save_loc;
@@ -20137,7 +20162,6 @@ tsubst_copy_and_build (tree t,
{
tree decl;
cp_id_kind idk;
- bool non_integral_constant_expression_p;
const char *error_msg;
if (IDENTIFIER_CONV_OP_P (t))
@@ -20156,9 +20180,9 @@ tsubst_copy_and_build (tree t,
decl = finish_id_expression (t, decl, NULL_TREE,
&idk,
- integral_constant_expression_p,
- /*allow_non_integral_constant_expression_p=*/(cxx_dialect >= cxx11),
- &non_integral_constant_expression_p,
+ /*i_c_e_p=*/false,
+ /*allow_i_c_e_p=*/true,
+ /*non_i_c_e_p=*/nullptr,
/*template_p=*/false,
/*done=*/true,
/*address_p=*/false,
@@ -20167,7 +20191,7 @@ tsubst_copy_and_build (tree t,
input_location);
if (error_msg)
error (error_msg);
- if (!function_p && identifier_p (decl))
+ if (identifier_p (decl))
{
if (complain & tf_error)
unqualified_name_lookup_error (decl);
@@ -20180,9 +20204,7 @@ tsubst_copy_and_build (tree t,
{
tree object;
tree templ = tsubst_copy_and_build (TREE_OPERAND (t, 0), args,
- complain, in_decl,
- function_p,
- integral_constant_expression_p);
+ complain, in_decl);
tree targs = TREE_OPERAND (t, 1);
if (targs)
@@ -20322,14 +20344,6 @@ tsubst_copy_and_build (tree t,
if (TREE_CODE (t) == CAST_EXPR)
tcomplain |= tf_tst_ok;
type = tsubst (TREE_TYPE (t), args, tcomplain, in_decl);
- if (integral_constant_expression_p
- && !cast_valid_in_integral_constant_expression_p (type))
- {
- if (complain & tf_error)
- error ("a cast to a type other than an integral or "
- "enumeration type cannot appear in a constant-expression");
- RETURN (error_mark_node);
- }
op = RECUR (TREE_OPERAND (t, 0));
@@ -20514,7 +20528,6 @@ tsubst_copy_and_build (tree t,
tree c = TREE_OPERAND (t, 1);
releasing_vec index_exp_list;
tsubst_copy_and_build_call_args (c, args, complain, in_decl,
- integral_constant_expression_p,
index_exp_list);
tree r;
@@ -20563,10 +20576,7 @@ tsubst_copy_and_build (tree t,
if (TYPE_P (op1))
op1 = tsubst (op1, args, complain, in_decl);
else
- op1 = tsubst_copy_and_build (op1, args, complain, in_decl,
- /*function_p=*/false,
- /*integral_constant_expression_p=*/
- false);
+ op1 = tsubst_copy_and_build (op1, args, complain, in_decl);
--cp_unevaluated_operand;
--c_inhibit_evaluation_warnings;
}
@@ -20603,9 +20613,7 @@ tsubst_copy_and_build (tree t,
op1 = TREE_OPERAND (t, 0);
++cp_unevaluated_operand;
++c_inhibit_evaluation_warnings;
- op1 = tsubst_copy_and_build (op1, args, complain, in_decl,
- /*function_p=*/false,
- /*integral_constant_expression_p=*/false);
+ op1 = tsubst_copy_and_build (op1, args, complain, in_decl);
--cp_unevaluated_operand;
--c_inhibit_evaluation_warnings;
RETURN (objc_build_encode_expr (op1));
@@ -20616,9 +20624,7 @@ tsubst_copy_and_build (tree t,
++cp_unevaluated_operand;
++c_inhibit_evaluation_warnings;
++cp_noexcept_operand;
- op1 = tsubst_copy_and_build (op1, args, complain, in_decl,
- /*function_p=*/false,
- /*integral_constant_expression_p=*/false);
+ op1 = tsubst_copy_and_build (op1, args, complain, in_decl);
--cp_unevaluated_operand;
--c_inhibit_evaluation_warnings;
--cp_noexcept_operand;
@@ -20727,9 +20733,7 @@ tsubst_copy_and_build (tree t,
case COMPOUND_EXPR:
{
tree op0 = tsubst_copy_and_build (TREE_OPERAND (t, 0), args,
- complain & ~tf_decltype, in_decl,
- /*function_p=*/false,
- integral_constant_expression_p);
+ complain & ~tf_decltype, in_decl);
RETURN (build_x_compound_expr (EXPR_LOCATION (t),
op0,
RECUR (TREE_OPERAND (t, 1)),
@@ -20774,12 +20778,10 @@ tsubst_copy_and_build (tree t,
would incorrectly perform unqualified lookup again.
Note that we can also have an IDENTIFIER_NODE if the earlier
- unqualified lookup found a member function; in that case
- koenig_p will be false and we do want to do the lookup
- again to find the instantiated member function.
-
- FIXME but doing that causes c++/15272, so we need to stop
- using IDENTIFIER_NODE in that situation. */
+ unqualified lookup found a dependent local extern declaration
+ (as per finish_call_expr); in that case koenig_p will be false
+ and we do want to do the lookup again to find the substituted
+ declaration. */
qualified_p = false;
if (TREE_CODE (function) == TEMPLATE_ID_EXPR)
@@ -20812,10 +20814,7 @@ tsubst_copy_and_build (tree t,
augmenting the overload set via ADL, so during this initial
substitution we disable mark_used by setting tf_conv (68942). */
subcomplain |= tf_conv;
- function = tsubst_copy_and_build (function, args, subcomplain,
- in_decl,
- !qualified_p,
- integral_constant_expression_p);
+ function = tsubst_copy_and_build (function, args, subcomplain, in_decl);
if (BASELINK_P (function))
qualified_p = true;
@@ -20824,7 +20823,6 @@ tsubst_copy_and_build (tree t,
nargs = call_expr_nargs (t);
releasing_vec call_args;
tsubst_copy_and_build_call_args (t, args, complain, in_decl,
- integral_constant_expression_p,
call_args);
/* Stripped-down processing for a call in a thunk. Specifically, in
@@ -20917,9 +20915,8 @@ tsubst_copy_and_build (tree t,
/* For backwards compatibility and good diagnostics, try
the unqualified lookup again if we aren't in SFINAE
context. */
- tree unq = (tsubst_copy_and_build
- (function, args, complain, in_decl, true,
- integral_constant_expression_p));
+ tree unq = tsubst_copy_and_build (function, args,
+ complain, in_decl);
if (unq == error_mark_node)
RETURN (error_mark_node);
@@ -20936,8 +20933,9 @@ tsubst_copy_and_build (tree t,
/* In a lambda fn, we have to be careful to not
introduce new this captures. Legacy code can't
be using lambdas anyway, so it's ok to be
- stricter. Be strict with C++20 template-id ADL too. */
- bool strict = in_lambda || template_id_p;
+ stricter. Be strict with C++20 template-id ADL too.
+ And be strict if we're already failing anyway. */
+ bool strict = in_lambda || template_id_p || seen_error();
bool diag = true;
if (strict)
error_at (cp_expr_loc_or_input_loc (t),
@@ -21467,9 +21465,8 @@ tsubst_copy_and_build (tree t,
case OFFSETOF_EXPR:
{
tree object_ptr
- = tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain,
- in_decl, /*function_p=*/false,
- /*integral_constant_expression_p=*/false);
+ = tsubst_copy_and_build (TREE_OPERAND (t, 1), args,
+ complain, in_decl);
RETURN (finish_offsetof (object_ptr,
RECUR (TREE_OPERAND (t, 0)),
EXPR_LOCATION (t)));
@@ -21495,8 +21492,7 @@ tsubst_copy_and_build (tree t,
tree stmt_expr = begin_stmt_expr ();
cur_stmt_expr = stmt_expr;
- tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl,
- integral_constant_expression_p);
+ tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl);
stmt_expr = finish_stmt_expr (stmt_expr, false);
cur_stmt_expr = old_stmt_expr;
@@ -21523,8 +21519,7 @@ tsubst_copy_and_build (tree t,
}
case TRANSACTION_EXPR:
- RETURN (tsubst_expr(t, args, complain, in_decl,
- integral_constant_expression_p));
+ RETURN (tsubst_expr (t, args, complain, in_decl));
case PAREN_EXPR:
if (REF_PARENTHESIZED_P (t))
@@ -21570,8 +21565,7 @@ tsubst_copy_and_build (tree t,
/* Handle Objective-C++ constructs, if appropriate. */
{
tree subst
- = objcp_tsubst_copy_and_build (t, args, complain,
- in_decl, /*function_p=*/false);
+ = objcp_tsubst_copy_and_build (t, args, complain, in_decl);
if (subst)
RETURN (subst);
}
@@ -21891,8 +21885,8 @@ instantiate_alias_template (tree tmpl, tree args, tsubst_flags_t complain)
if (tmpl == error_mark_node || args == error_mark_node)
return error_mark_node;
- args = coerce_innermost_template_parms (DECL_TEMPLATE_PARMS (tmpl),
- args, tmpl, complain);
+ args = coerce_template_parms (DECL_TEMPLATE_PARMS (tmpl),
+ args, tmpl, complain);
/* FIXME check for satisfaction in check_instantiated_args. */
if (flag_concepts
@@ -26179,6 +26173,21 @@ regenerate_decl_from_template (tree decl, tree tmpl, tree args)
DECL_CONTEXT (t) = decl;
}
+ if (DECL_CONTRACTS (decl))
+ {
+ /* If we're regenerating a specialization, the contracts will have
+ been copied from the most general template. Replace those with
+ the ones from the actual specialization. */
+ tree tmpl = DECL_TI_TEMPLATE (decl);
+ if (DECL_TEMPLATE_SPECIALIZATION (tmpl))
+ {
+ remove_contract_attributes (decl);
+ copy_contract_attributes (decl, code_pattern);
+ }
+
+ tsubst_contract_attributes (decl, args, tf_warning_or_error, code_pattern);
+ }
+
/* Merge additional specifiers from the CODE_PATTERN. */
if (DECL_DECLARED_INLINE_P (code_pattern)
&& !DECL_DECLARED_INLINE_P (decl))
@@ -26387,9 +26396,7 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
/* Do deferred instantiation of the noexcept-specifier. */
noex = tsubst_copy_and_build (DEFERRED_NOEXCEPT_PATTERN (noex),
DEFERRED_NOEXCEPT_ARGS (noex),
- tf_warning_or_error, fn,
- /*function_p=*/false,
- /*i_c_e_p=*/true);
+ tf_warning_or_error, fn);
/* Build up the noexcept-specification. */
spec = build_noexcept_spec (noex, tf_warning_or_error);
@@ -26426,7 +26433,7 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
/* We're starting to process the function INST, an instantiation of PATTERN;
add their parameters to local_specializations. */
-static void
+void
register_parameter_specializations (tree pattern, tree inst)
{
tree tmpl_parm = DECL_ARGUMENTS (pattern);
@@ -26575,8 +26582,7 @@ instantiate_body (tree pattern, tree args, tree d, bool nested_p)
else
{
tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
- tf_warning_or_error, DECL_TI_TEMPLATE (d),
- /*integral_constant_expression_p=*/false);
+ tf_warning_or_error, DECL_TI_TEMPLATE (d));
/* Set the current input_location to the end of the function
so that finish_function knows where we are. */
@@ -26817,8 +26823,7 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p)
push_nested_class (DECL_CONTEXT (d));
init = tsubst_expr (DECL_INITIAL (code_pattern),
args,
- tf_warning_or_error, NULL_TREE,
- /*integral_constant_expression_p=*/false);
+ tf_warning_or_error, NULL_TREE);
/* If instantiating the initializer involved instantiating this
again, don't call cp_finish_decl twice. */
if (!DECL_INITIAL (d))
@@ -27106,8 +27111,7 @@ tsubst_initializer_list (tree t, tree argvec)
tmp = init;
if (init != void_type_node)
init = tsubst_expr (init, argvec,
- tf_warning_or_error, NULL_TREE,
- /*integral_constant_expression_p=*/false);
+ tf_warning_or_error, NULL_TREE);
if (init == NULL_TREE && tmp != NULL_TREE)
/* If we had an initializer but it instantiated to nothing,
value-initialize the object. This will only occur when
@@ -27173,8 +27177,7 @@ tsubst_enum (tree tag, tree newtag, tree args)
/* Note that in a template enum, the TREE_VALUE is the
CONST_DECL, not the corresponding INTEGER_CST. */
value = tsubst_expr (DECL_INITIAL (decl),
- args, tf_warning_or_error, NULL_TREE,
- /*integral_constant_expression_p=*/true);
+ args, tf_warning_or_error, NULL_TREE);
/* Give this enumeration constant the correct access. */
set_current_access_from_decl (decl);
@@ -29025,7 +29028,7 @@ placeholder_type_constraint_dependent_p (tree t)
the TEMPLATE_DECL. */
tree
-finish_concept_definition (cp_expr id, tree init)
+finish_concept_definition (cp_expr id, tree init, tree attrs)
{
gcc_assert (identifier_p (id));
gcc_assert (processing_template_decl);
@@ -29059,6 +29062,9 @@ finish_concept_definition (cp_expr id, tree init)
DECL_CONTEXT (decl) = current_scope ();
DECL_INITIAL (decl) = init;
+ if (attrs)
+ cplus_decl_attributes (&decl, attrs, 0);
+
set_originating_module (decl, false);
/* Push the enclosing template. */
diff --git a/gcc/cp/search.cc b/gcc/cp/search.cc
index 10863a4..0dbb3be 100644
--- a/gcc/cp/search.cc
+++ b/gcc/cp/search.cc
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "spellcheck-tree.h"
#include "stringpool.h"
#include "attribs.h"
+#include "tree-inline.h"
static int is_subobject_of_p (tree, tree);
static tree dfs_lookup_base (tree, void *);
@@ -2082,6 +2083,33 @@ check_final_overrider (tree overrider, tree basefn)
}
return 0;
}
+
+ if (!DECL_HAS_CONTRACTS_P (basefn) && DECL_HAS_CONTRACTS_P (overrider))
+ {
+ auto_diagnostic_group d;
+ error ("function with contracts %q+D overriding contractless function",
+ overrider);
+ inform (DECL_SOURCE_LOCATION (basefn),
+ "overridden function is %qD", basefn);
+ return 0;
+ }
+ else if (DECL_HAS_CONTRACTS_P (basefn) && !DECL_HAS_CONTRACTS_P (overrider))
+ {
+ /* We're inheriting basefn's contracts; create a copy of them but
+ replace references to their parms to our parms. */
+ inherit_base_contracts (overrider, basefn);
+ }
+ else if (DECL_HAS_CONTRACTS_P (basefn) && DECL_HAS_CONTRACTS_P (overrider))
+ {
+ /* We're in the process of completing the overrider's class, which means
+ our conditions definitely are not parsed so simply chain on the
+ basefn for later checking.
+
+ Note that OVERRIDER's contracts will have been fully parsed at the
+ point the deferred match is run. */
+ defer_guarded_contract_match (overrider, basefn, DECL_CONTRACTS (basefn));
+ }
+
if (DECL_FINAL_P (basefn))
{
auto_diagnostic_group d;
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 7c5f90b..ab52e56 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -610,7 +610,8 @@ set_cleanup_locs (tree stmts, location_t loc)
if (TREE_CODE (stmts) == CLEANUP_STMT)
{
tree t = CLEANUP_EXPR (stmts);
- protected_set_expr_location (t, loc);
+ if (t && TREE_CODE (t) != POSTCONDITION_STMT)
+ protected_set_expr_location (t, loc);
/* Avoid locus differences for C++ cdtor calls depending on whether
cdtor_returns_this: a conversion to void is added to discard the return
value, and this conversion ends up carrying the location, and when it
@@ -2169,7 +2170,8 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope,
/* DR 613/850: Can use non-static data members without an associated
object in sizeof/decltype/alignof. */
- if (is_dummy_object (object) && cp_unevaluated_operand == 0
+ if (is_dummy_object (object)
+ && !cp_unevaluated_operand
&& (!processing_template_decl || !current_class_ref))
{
if (complain & tf_error)
@@ -2177,6 +2179,14 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope,
if (current_function_decl
&& DECL_STATIC_FUNCTION_P (current_function_decl))
error ("invalid use of member %qD in static member function", decl);
+ else if (current_function_decl
+ && processing_contract_condition
+ && DECL_CONSTRUCTOR_P (current_function_decl))
+ error ("invalid use of member %qD in constructor %<pre%> contract", decl);
+ else if (current_function_decl
+ && processing_contract_condition
+ && DECL_DESTRUCTOR_P (current_function_decl))
+ error ("invalid use of member %qD in destructor %<post%> contract", decl);
else
error ("invalid use of non-static data member %qD", decl);
inform (DECL_SOURCE_LOCATION (decl), "declared here");
@@ -2737,6 +2747,10 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
result = build_min_nt_call_vec (orig_fn, *args);
SET_EXPR_LOCATION (result, cp_expr_loc_or_input_loc (fn));
KOENIG_LOOKUP_P (result) = koenig_p;
+ /* Disable the std::move warnings since this call was dependent
+ (c++/89780, c++/107363). This also suppresses the
+ -Wredundant-move warning. */
+ suppress_warning (result, OPT_Wpessimizing_move);
if (is_overloaded_fn (fn))
fn = get_fns (fn);
@@ -3010,6 +3024,10 @@ finish_this_expr (void)
tree fn = current_nonlambda_function ();
if (fn && DECL_STATIC_FUNCTION_P (fn))
error ("%<this%> is unavailable for static member functions");
+ else if (fn && processing_contract_condition && DECL_CONSTRUCTOR_P (fn))
+ error ("invalid use of %<this%> before it is valid");
+ else if (fn && processing_contract_condition && DECL_DESTRUCTOR_P (fn))
+ error ("invalid use of %<this%> after it is valid");
else if (fn)
error ("invalid use of %<this%> in non-member function");
else
@@ -3983,6 +4001,9 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use)
}
return error_mark_node;
}
+ else if (processing_contract_condition && (TREE_CODE (decl) == PARM_DECL))
+ /* Use of a parameter in a contract condition is fine. */
+ return decl;
else
{
if (complain & tf_error)
@@ -4115,7 +4136,8 @@ finish_id_expression_1 (tree id_expression,
body, except inside an unevaluated context (i.e. decltype). */
if (TREE_CODE (decl) == PARM_DECL
&& DECL_CONTEXT (decl) == NULL_TREE
- && !cp_unevaluated_operand)
+ && !cp_unevaluated_operand
+ && !processing_contract_condition)
{
*error_msg = G_("use of parameter outside function body");
return error_mark_node;
@@ -11661,7 +11683,7 @@ is_corresponding_member_aggr (location_t loc, tree basetype1, tree membertype1,
tree ret = boolean_false_node;
while (1)
{
- bool r = next_common_initial_seqence (field1, field2);
+ bool r = next_common_initial_sequence (field1, field2);
if (field1 == NULL_TREE || field2 == NULL_TREE)
break;
if (r
@@ -12286,6 +12308,10 @@ apply_deduced_return_type (tree fco, tree return_type)
TREE_TYPE (fco) = change_return_type (return_type, TREE_TYPE (fco));
+ maybe_update_postconditions (fco);
+
+ /* Apply the type to the result object. */
+
result = DECL_RESULT (fco);
if (result == NULL_TREE)
return;
@@ -12299,24 +12325,23 @@ apply_deduced_return_type (tree fco, tree return_type)
/* We already have a DECL_RESULT from start_preparsed_function.
Now we need to redo the work it and allocate_struct_function
did to reflect the new type. */
- gcc_assert (current_function_decl == fco);
- result = build_decl (input_location, RESULT_DECL, NULL_TREE,
+ result = build_decl (DECL_SOURCE_LOCATION (result), RESULT_DECL, NULL_TREE,
TYPE_MAIN_VARIANT (return_type));
DECL_ARTIFICIAL (result) = 1;
DECL_IGNORED_P (result) = 1;
cp_apply_type_quals_to_decl (cp_type_quals (return_type),
result);
-
DECL_RESULT (fco) = result;
if (!processing_template_decl)
- {
- bool aggr = aggregate_value_p (result, fco);
+ if (function *fun = DECL_STRUCT_FUNCTION (fco))
+ {
+ bool aggr = aggregate_value_p (result, fco);
#ifdef PCC_STATIC_STRUCT_RETURN
- cfun->returns_pcc_struct = aggr;
+ fun->returns_pcc_struct = aggr;
#endif
- cfun->returns_struct = aggr;
- }
+ fun->returns_struct = aggr;
+ }
}
/* DECL is a local variable or parameter from the surrounding scope of a
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 45348c5..33bde16 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -46,6 +46,7 @@ static tree verify_stmt_tree_r (tree *, int *, void *);
static tree handle_init_priority_attribute (tree *, tree, tree, int, bool *);
static tree handle_abi_tag_attribute (tree *, tree, tree, int, bool *);
+static tree handle_contract_attribute (tree *, tree, tree, int, bool *);
/* If REF is an lvalue, returns the kind of lvalue that REF is.
Otherwise, returns clk_none. */
@@ -3885,6 +3886,50 @@ called_fns_equal (tree t1, tree t2)
return cp_tree_equal (t1, t2);
}
+bool comparing_override_contracts;
+
+/* In a component reference, return the innermost object of
+ the postfix-expression. */
+
+static tree
+get_innermost_component (tree t)
+{
+ gcc_assert (TREE_CODE (t) == COMPONENT_REF);
+ while (TREE_CODE (t) == COMPONENT_REF)
+ t = TREE_OPERAND (t, 0);
+ return t;
+}
+
+/* Returns true if T is a possibly converted 'this' or '*this' expression. */
+
+static bool
+is_this_expression (tree t)
+{
+ t = get_innermost_component (t);
+ /* See through deferences and no-op conversions. */
+ if (TREE_CODE (t) == INDIRECT_REF)
+ t = TREE_OPERAND (t, 0);
+ if (TREE_CODE (t) == NOP_EXPR)
+ t = TREE_OPERAND (t, 0);
+ return is_this_parameter (t);
+}
+
+static bool
+comparing_this_references (tree t1, tree t2)
+{
+ return is_this_expression (t1) && is_this_expression (t2);
+}
+
+static bool
+equivalent_member_references (tree t1, tree t2)
+{
+ if (!comparing_this_references (t1, t2))
+ return false;
+ t1 = TREE_OPERAND (t1, 1);
+ t2 = TREE_OPERAND (t2, 1);
+ return t1 == t2;
+}
+
/* Return truthvalue of whether T1 is the same tree structure as T2.
Return 1 if they are the same. Return 0 if they are different. */
@@ -4219,6 +4264,13 @@ cp_tree_equal (tree t1, tree t2)
return false;
return true;
+ case COMPONENT_REF:
+ /* If we're comparing contract conditions of overrides, member references
+ compare equal if they designate the same member. */
+ if (comparing_override_contracts)
+ return equivalent_member_references (t1, t2);
+ break;
+
default:
break;
}
@@ -4923,6 +4975,32 @@ structural_type_p (tree t, bool explain)
return true;
}
+/* Partially handle the C++11 [[carries_dependency]] attribute.
+ Just emit a different diagnostics when it is used on something the
+ spec doesn't allow vs. where it allows and we just choose to ignore
+ it. */
+
+static tree
+handle_carries_dependency_attribute (tree *node, tree name,
+ tree ARG_UNUSED (args),
+ int ARG_UNUSED (flags),
+ bool *no_add_attrs)
+{
+ if (TREE_CODE (*node) != FUNCTION_DECL
+ && TREE_CODE (*node) != PARM_DECL)
+ {
+ warning (OPT_Wattributes, "%qE attribute can only be applied to "
+ "functions or parameters", name);
+ *no_add_attrs = true;
+ }
+ else
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+ return NULL_TREE;
+}
+
/* Handle the C++17 [[nodiscard]] attribute, which is similar to the GNU
warn_unused_result attribute. */
@@ -5034,6 +5112,12 @@ const struct attribute_spec std_attribute_table[] =
handle_likeliness_attribute, attr_cold_hot_exclusions },
{ "noreturn", 0, 0, true, false, false, false,
handle_noreturn_attribute, attr_noreturn_exclusions },
+ { "carries_dependency", 0, 0, true, false, false, false,
+ handle_carries_dependency_attribute, NULL },
+ { "pre", 0, -1, false, false, false, false,
+ handle_contract_attribute, NULL },
+ { "post", 0, -1, false, false, false, false,
+ handle_contract_attribute, NULL },
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
};
@@ -5046,6 +5130,11 @@ handle_init_priority_attribute (tree* node,
int /*flags*/,
bool* no_add_attrs)
{
+ if (!SUPPORTS_INIT_PRIORITY)
+ /* Treat init_priority as an unrecognized attribute (mirroring
+ __has_attribute) if the target doesn't support init priorities. */
+ return error_mark_node;
+
tree initp_expr = TREE_VALUE (args);
tree decl = *node;
tree type = TREE_TYPE (decl);
@@ -5103,18 +5192,9 @@ handle_init_priority_attribute (tree* node,
pri);
}
- if (SUPPORTS_INIT_PRIORITY)
- {
- SET_DECL_INIT_PRIORITY (decl, pri);
- DECL_HAS_INIT_PRIORITY_P (decl) = 1;
- return NULL_TREE;
- }
- else
- {
- error ("%qE attribute is not supported on this platform", name);
- *no_add_attrs = true;
- return NULL_TREE;
- }
+ SET_DECL_INIT_PRIORITY (decl, pri);
+ DECL_HAS_INIT_PRIORITY_P (decl) = 1;
+ return NULL_TREE;
}
/* DECL is being redeclared; the old declaration had the abi tags in OLD,
@@ -5282,6 +5362,17 @@ handle_abi_tag_attribute (tree* node, tree name, tree args,
return NULL_TREE;
}
+/* Perform checking for contract attributes. */
+
+tree
+handle_contract_attribute (tree *ARG_UNUSED (node), tree ARG_UNUSED (name),
+ tree ARG_UNUSED (args), int ARG_UNUSED (flags),
+ bool *ARG_UNUSED (no_add_attrs))
+{
+ /* TODO: Is there any checking we could do here? */
+ return NULL_TREE;
+}
+
/* Return a new PTRMEM_CST of the indicated TYPE. The MEMBER is the
thing pointed to by the constant. */
@@ -5512,15 +5603,18 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
break;
case REQUIRES_EXPR:
- // Only recurse through the nested expression. Do not
- // walk the parameter list. Doing so causes false
- // positives in the pack expansion checker since the
- // requires parameters are introduced as pack expansions.
- ++cp_unevaluated_operand;
- result = cp_walk_tree (&REQUIRES_EXPR_REQS (*tp), func, data, pset);
- --cp_unevaluated_operand;
- *walk_subtrees_p = 0;
- break;
+ {
+ cp_unevaluated u;
+ for (tree parm = REQUIRES_EXPR_PARMS (*tp); parm; parm = DECL_CHAIN (parm))
+ /* Walk the types of each parameter, but not the parameter itself,
+ since doing so would cause false positives in the unexpanded pack
+ checker if the requires-expr introduces a function parameter pack,
+ e.g. requires (Ts... ts) { }. */
+ WALK_SUBTREE (TREE_TYPE (parm));
+ WALK_SUBTREE (REQUIRES_EXPR_REQS (*tp));
+ *walk_subtrees_p = 0;
+ break;
+ }
case DECL_EXPR:
/* User variables should be mentioned in BIND_EXPR_VARS
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 2e0fd8f..7dfe5ac 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -1779,7 +1779,7 @@ similar_type_p (tree type1, tree type2)
the common initial sequence. */
bool
-next_common_initial_seqence (tree &memb1, tree &memb2)
+next_common_initial_sequence (tree &memb1, tree &memb2)
{
while (memb1)
{
@@ -1833,6 +1833,8 @@ next_common_initial_seqence (tree &memb1, tree &memb2)
if ((!lookup_attribute ("no_unique_address", DECL_ATTRIBUTES (memb1)))
!= !lookup_attribute ("no_unique_address", DECL_ATTRIBUTES (memb2)))
return false;
+ if (DECL_ALIGN (memb1) != DECL_ALIGN (memb2))
+ return false;
if (!tree_int_cst_equal (bit_position (memb1), bit_position (memb2)))
return false;
return true;
@@ -1854,15 +1856,13 @@ layout_compatible_type_p (tree type1, tree type2)
type2 = cp_build_qualified_type (type2, TYPE_UNQUALIFIED);
if (TREE_CODE (type1) == ENUMERAL_TYPE)
- return (TYPE_ALIGN (type1) == TYPE_ALIGN (type2)
- && tree_int_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
+ return (tree_int_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
&& same_type_p (finish_underlying_type (type1),
finish_underlying_type (type2)));
if (CLASS_TYPE_P (type1)
&& std_layout_type_p (type1)
&& std_layout_type_p (type2)
- && TYPE_ALIGN (type1) == TYPE_ALIGN (type2)
&& tree_int_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2)))
{
tree field1 = TYPE_FIELDS (type1);
@@ -1871,7 +1871,7 @@ layout_compatible_type_p (tree type1, tree type2)
{
while (1)
{
- if (!next_common_initial_seqence (field1, field2))
+ if (!next_common_initial_sequence (field1, field2))
return false;
if (field1 == NULL_TREE)
return true;
@@ -6215,8 +6215,9 @@ cp_build_binary_op (const op_location_t &location,
tree_code orig_code0 = TREE_CODE (orig_type0);
tree orig_type1 = TREE_TYPE (orig_op1);
tree_code orig_code1 = TREE_CODE (orig_type1);
- if (!result_type)
- /* Nope. */;
+ if (!result_type || result_type == error_mark_node)
+ /* Nope. */
+ result_type = NULL_TREE;
else if ((orig_code0 == BOOLEAN_TYPE) != (orig_code1 == BOOLEAN_TYPE))
/* "If one of the operands is of type bool and the other is not, the
program is ill-formed." */
@@ -9513,19 +9514,6 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
&& MAYBE_CLASS_TYPE_P (TREE_TYPE (lhstype)))
|| MAYBE_CLASS_TYPE_P (lhstype)));
- /* An expression of the form E1 op= E2. [expr.ass] says:
- "Such expressions are deprecated if E1 has volatile-qualified
- type and op is not one of the bitwise operators |, &, ^."
- We warn here rather than in cp_genericize_r because
- for compound assignments we are supposed to warn even if the
- assignment is a discarded-value expression. */
- if (modifycode != BIT_AND_EXPR
- && modifycode != BIT_IOR_EXPR
- && modifycode != BIT_XOR_EXPR
- && (TREE_THIS_VOLATILE (lhs) || CP_TYPE_VOLATILE_P (lhstype)))
- warning_at (loc, OPT_Wvolatile,
- "compound assignment with %<volatile%>-qualified left "
- "operand is deprecated");
/* Preevaluate the RHS to make sure its evaluation is complete
before the lvalue-to-rvalue conversion of the LHS:
@@ -10885,7 +10873,9 @@ maybe_warn_pessimizing_move (tree expr, tree type, bool return_p)
and where the std::move does nothing if T does not have a T(const T&&)
constructor, because the argument is const. It will not use T(T&&)
because that would mean losing the const. */
- else if (TYPE_REF_P (TREE_TYPE (arg))
+ else if (warn_redundant_move
+ && !warning_suppressed_p (expr, OPT_Wredundant_move)
+ && TYPE_REF_P (TREE_TYPE (arg))
&& CP_TYPE_CONST_P (TREE_TYPE (TREE_TYPE (arg))))
{
tree rtype = TREE_TYPE (TREE_TYPE (arg));
@@ -10901,8 +10891,11 @@ maybe_warn_pessimizing_move (tree expr, tree type, bool return_p)
return;
}
auto_diagnostic_group d;
- if (warning_at (loc, OPT_Wredundant_move,
- "redundant move in return statement"))
+ if (return_p
+ ? warning_at (loc, OPT_Wredundant_move,
+ "redundant move in return statement")
+ : warning_at (loc, OPT_Wredundant_move,
+ "redundant move in initialization"))
inform (loc, "remove %<std::move%> call");
}
}
@@ -11126,11 +11119,6 @@ check_return_expr (tree retval, bool *no_warning)
/* We don't know if this is an lvalue or rvalue use, but
either way we can mark it as read. */
mark_exp_read (retval);
- /* Disable our std::move warnings when we're returning
- a dependent expression (c++/89780). */
- if (retval && TREE_CODE (retval) == CALL_EXPR)
- /* This also suppresses -Wredundant-move. */
- suppress_warning (retval, OPT_Wpessimizing_move);
return retval;
}
@@ -11260,11 +11248,22 @@ check_return_expr (tree retval, bool *no_warning)
/* Actually copy the value returned into the appropriate location. */
if (retval && retval != result)
- retval = cp_build_init_expr (result, retval);
+ {
+ /* If there's a postcondition for a scalar return value, wrap
+ retval in a call to the postcondition function. */
+ if (tree post = apply_postcondition_to_return (retval))
+ retval = post;
+ retval = cp_build_init_expr (result, retval);
+ }
if (tree set = maybe_set_retval_sentinel ())
retval = build2 (COMPOUND_EXPR, void_type_node, retval, set);
+ /* If there's a postcondition for an aggregate return value, call the
+ postcondition function after the return object is initialized. */
+ if (tree post = apply_postcondition_to_return (result))
+ retval = build2 (COMPOUND_EXPR, void_type_node, retval, post);
+
return retval;
}
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index 888d82b..7630f24 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,255 @@
+2022-12-12 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/108055
+ * decl.cc (function_defined_in_root_p): Check all enclosing template
+ instances for definition in a root module.
+ (function_needs_inline_definition_p): Replace call to
+ function_defined_in_root_p with test for outer module `isRoot'.
+
+2022-12-11 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/108050
+ * decl.cc (DeclVisitor::visit (Import *)): Handle build_import_decl
+ returning a TREE_LIST.
+ * imports.cc (ImportVisitor::visit (OverloadSet *)): New override.
+
+2022-12-11 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * dmd/MERGE: Merge upstream dmd c8ae4adb2e.
+ * typeinfo.cc (check_typeinfo_type): Update for new front-end
+ interface.
+ (TypeInfoVisitor::visit (TypeInfoStructDeclaration *)): Remove warning
+ that toHash() must be declared 'nothrow @safe`.
+
+2022-12-11 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * intrinsics.cc (expand_intrinsic_bsf): Fix comment.
+ (expand_intrinsic_bsr): Use BIT_XOR_EXPR instead of MINUS_EXPR.
+
+2022-11-30 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * Make-lang.in (D_TEXI_FILES): Add d/implement-d.texi.
+ * gdc.texi: Adjust introduction, include implement-d.texi.
+ * implement-d.texi: New file.
+
+2022-11-30 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * Make-lang.in: Only include doc/include when building documentation.
+ (d.html): Rename html directory to $(build_htmldir)/gdc.
+
+2022-11-30 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * gdc.texi: Separate indices into options and keywords.
+
+2022-11-30 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * gdc.texi: Update gdc option documentation.
+ * lang.opt (frevert=intpromote): Correct documentation.
+
+2022-11-30 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/107592
+ * toir.cc (IRVisitor::push_unrolled_continue_label): New method.
+ (IRVisitor::pop_unrolled_continue_label): New method.
+ (IRVisitor::visit (UnrolledLoopStatement *)): Use them instead of
+ push_continue_label and pop_continue_label.
+
+2022-11-23 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Use it as $DO_LINK_MUTEX.
+
+2022-11-23 Marek Polacek <polacek@redhat.com>
+
+ Revert:
+ 2022-11-23 Marek Polacek <polacek@redhat.com>
+
+ * Make-lang.in: Remove NO_PIE_CFLAGS.
+
+2022-11-23 Marek Polacek <polacek@redhat.com>
+
+ * Make-lang.in: Remove NO_PIE_CFLAGS.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/conf.py: New file.
+ * doc/copyright.rst: New file.
+ * doc/general-public-license-3.rst: New file.
+ * doc/gnu-free-documentation-license.rst: New file.
+ * doc/index.rst: New file.
+ * doc/indices-and-tables.rst: New file.
+ * doc/invoking-gdc.rst: New file.
+ * doc/invoking-gdc/code-generation.rst: New file.
+ * doc/invoking-gdc/developer-options.rst: New file.
+ * doc/invoking-gdc/input-and-output-files.rst: New file.
+ * doc/invoking-gdc/options-for-directory-search.rst: New file.
+ * doc/invoking-gdc/options-for-linking.rst: New file.
+ * doc/invoking-gdc/runtime-options.rst: New file.
+ * doc/invoking-gdc/warnings.rst: New file.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * d-target.def: Port to RST.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support Sphinx based documentation.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * gdc.texi: Removed.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support --with-sphinx-build.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in:
+ Support installation if sphinx-build is missing.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/copyright.rst:
+ Add trailing newline.
+ * doc/general-public-license-3.rst:
+ Add trailing newline.
+ * doc/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/index.rst:
+ Add trailing newline.
+ * doc/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/invoking-gdc.rst:
+ Add trailing newline.
+ * doc/invoking-gdc/code-generation.rst:
+ Add trailing newline.
+ * doc/invoking-gdc/developer-options.rst:
+ Add trailing newline.
+ * doc/invoking-gdc/input-and-output-files.rst:
+ Add trailing newline.
+ * doc/invoking-gdc/options-for-directory-search.rst:
+ Add trailing newline.
+ * doc/invoking-gdc/options-for-linking.rst:
+ Add trailing newline.
+ * doc/invoking-gdc/runtime-options.rst:
+ Add trailing newline.
+ * doc/invoking-gdc/warnings.rst:
+ Add trailing newline.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-10 Martin Liska <mliska@suse.cz>
+
+ * doc/conf.py: Add newline at last line.
+
+2022-11-10 Martin Liska <mliska@suse.cz>
+
+ * doc/conf.py: Add newline at last line.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/copyright.rst:
+ Add trailing newline.
+ * doc/general-public-license-3.rst:
+ Add trailing newline.
+ * doc/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/index.rst:
+ Add trailing newline.
+ * doc/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/invoking-gdc.rst:
+ Add trailing newline.
+ * doc/invoking-gdc/code-generation.rst:
+ Add trailing newline.
+ * doc/invoking-gdc/developer-options.rst:
+ Add trailing newline.
+ * doc/invoking-gdc/input-and-output-files.rst:
+ Add trailing newline.
+ * doc/invoking-gdc/options-for-directory-search.rst:
+ Add trailing newline.
+ * doc/invoking-gdc/options-for-linking.rst:
+ Add trailing newline.
+ * doc/invoking-gdc/runtime-options.rst:
+ Add trailing newline.
+ * doc/invoking-gdc/warnings.rst:
+ Add trailing newline.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in:
+ Support installation if sphinx-build is missing.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support --with-sphinx-build.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * gdc.texi: Removed.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support Sphinx based documentation.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * d-target.def: Port to RST.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/conf.py: New file.
+ * doc/copyright.rst: New file.
+ * doc/general-public-license-3.rst: New file.
+ * doc/gnu-free-documentation-license.rst: New file.
+ * doc/index.rst: New file.
+ * doc/indices-and-tables.rst: New file.
+ * doc/invoking-gdc.rst: New file.
+ * doc/invoking-gdc/code-generation.rst: New file.
+ * doc/invoking-gdc/developer-options.rst: New file.
+ * doc/invoking-gdc/input-and-output-files.rst: New file.
+ * doc/invoking-gdc/options-for-directory-search.rst: New file.
+ * doc/invoking-gdc/options-for-linking.rst: New file.
+ * doc/invoking-gdc/runtime-options.rst: New file.
+ * doc/invoking-gdc/warnings.rst: New file.
+
+2022-11-05 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * d-target.cc (Target::isVectorOpSupported): Remove cases for
+ comparison operators.
+ * intrinsics.cc (maybe_set_intrinsic): Remove cases for vector
+ comparison intrinsics.
+ (maybe_warn_intrinsic_mismatch): Likewise.
+ (expand_intrinsic_vec_cond): Remove.
+ (maybe_expand_intrinsic): Remove cases for vector comparison
+ intrinsics.
+ * intrinsics.def (INTRINSIC_EQUALMASK): Remove.
+ (INTRINSIC_NOTEQUALMASK): Remove.
+ (INTRINSIC_GREATERMASK): Remove.
+ (INTRINSIC_GREATEREQUALMASK): Remove.
+
2022-10-29 Iain Buclaw <ibuclaw@gdcproject.org>
* d-attribs.cc (apply_user_attributes): Update for new front-end
diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in
index 6f9b2e5..b526461 100644
--- a/gcc/d/Make-lang.in
+++ b/gcc/d/Make-lang.in
@@ -70,7 +70,7 @@ DPOSTCOMPILE = @mv $(@D)/$(DEPDIR)/$(*F).TPo $(@D)/$(DEPDIR)/$(*F).Po
DLINKER = $(GDC) $(NO_PIE_FLAG) -lstdc++
# Like LINKER, but use a mutex for serializing front end links.
-ifeq (@DO_LINK_MUTEX@,true)
+ifeq ($(DO_LINK_MUTEX),true)
DLLINKER = $(SHELL) $(srcdir)/lock-and-run.sh linkfe.lck $(DLINKER)
else
DLLINKER = $(DLINKER)
@@ -239,6 +239,7 @@ d21$(exeext): $(D_ALL_OBJS) attribs.o $(BACKEND) $(LIBDEPS) $(d.prev)
D_TEXI_FILES = \
d/gdc.texi \
+ d/implement-d.texi \
$(gcc_docdir)/include/fdl.texi \
$(gcc_docdir)/include/gpl_v3.texi \
$(gcc_docdir)/include/gcc-common.texi \
@@ -252,16 +253,15 @@ doc/gdc.info: $(D_TEXI_FILES)
else true; fi
doc/gdc.dvi: $(D_TEXI_FILES)
- $(TEXI2DVI) -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $<
+ $(TEXI2DVI) -I $(abs_docdir)/include -o $@ $<
doc/gdc.pdf: $(D_TEXI_FILES)
- $(TEXI2PDF) -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $<
+ $(TEXI2PDF) -I $(abs_docdir)/include -o $@ $<
-$(build_htmldir)/d/index.html: $(D_TEXI_FILES)
+$(build_htmldir)/gdc/index.html: $(D_TEXI_FILES)
$(mkinstalldirs) $(@D)
rm -f $(@D)/*
- $(TEXI2HTML) -I $(gcc_docdir) -I $(gcc_docdir)/include \
- -I $(srcdir)/d -o $(@D) $<
+ $(TEXI2HTML) -I $(gcc_docdir)/include -I $(srcdir)/d -o $(@D) $<
.INTERMEDIATE: gdc.pod
@@ -276,7 +276,7 @@ d.rest.encap:
d.info: doc/gdc.info
d.dvi: doc/gdc.dvi
d.pdf: doc/gdc.pdf
-d.html: $(build_htmldir)/d/index.html
+d.html: $(build_htmldir)/gdc/index.html
d.srcinfo: doc/gdc.info
-cp -p $^ $(srcdir)/doc
d.srcextra:
@@ -340,10 +340,10 @@ d.install-dvi: doc/gdc.dvi
$(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(dvidir)/gcc/$$f"; \
done
-d.install-html: $(build_htmldir)/d
+d.install-html: $(build_htmldir)/gdc
@$(NORMAL_INSTALL)
test -z "$(htmldir)" || $(mkinstalldirs) "$(DESTDIR)$(htmldir)"
- @for p in $(build_htmldir)/d; do \
+ @for p in $(build_htmldir)/gdc; do \
if test -f "$$p" || test -d "$$p"; then d=""; else d="$(srcdir)/"; fi; \
f=$(html__strip_dir) \
if test -d "$$d$$p"; then \
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index d4350e5..d3244673 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -323,12 +323,6 @@ Target::isVectorOpSupported (Type *type, EXP op, Type *)
/* Logical operators must have a result type of bool. */
return false;
- case EXP::lessOrEqual:
- case EXP::lessThan:
- case EXP::greaterOrEqual:
- case EXP::greaterThan:
- case EXP::equal:
- case EXP::notEqual:
case EXP::identity:
case EXP::notIdentity:
/* Comparison operators must have a result type of bool. */
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index dcfca64..3508108 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -198,8 +198,16 @@ public:
tree name = (alias != NULL)
? get_identifier (alias->toChars ()) : NULL_TREE;
- debug_hooks->imported_module_or_decl (decl, name, context,
- false, false);
+ if (TREE_CODE (decl) != TREE_LIST)
+ debug_hooks->imported_module_or_decl (decl, name, context,
+ false, false);
+ else
+ {
+ /* Overload sets return a list of imported decls. */
+ for (; decl != NULL_TREE; decl = TREE_CHAIN (decl))
+ debug_hooks->imported_module_or_decl (TREE_VALUE (decl), name,
+ context, false, false);
+ }
}
}
else
@@ -1020,7 +1028,8 @@ build_decl_tree (Dsymbol *d)
input_location = saved_location;
}
-/* Returns true if function FD is defined or instantiated in a root module. */
+/* Returns true if function FD, or any lexically enclosing scope function of FD
+ is defined or instantiated in a root module. */
static bool
function_defined_in_root_p (FuncDeclaration *fd)
@@ -1029,9 +1038,11 @@ function_defined_in_root_p (FuncDeclaration *fd)
if (md && md->isRoot ())
return true;
- TemplateInstance *ti = fd->isInstantiated ();
- if (ti && ti->minst && ti->minst->isRoot ())
- return true;
+ for (TemplateInstance *ti = fd->isInstantiated (); ti != NULL; ti = ti->tinst)
+ {
+ if (ti->minst && ti->minst->isRoot ())
+ return true;
+ }
return false;
}
@@ -1059,7 +1070,8 @@ function_needs_inline_definition_p (FuncDeclaration *fd)
/* Check whether function will be regularly defined later in the current
translation unit. */
- if (function_defined_in_root_p (fd))
+ Module *md = fd->getModule ();
+ if (md && md->isRoot ())
return false;
/* Non-inlineable functions are always external. */
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 2398875..5ee6f62 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-e4f89195913be1dc638707b1abb24c4f3ae7e0bf
+c8ae4adb2eda515b09b326948e3a4aa9f489af45
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d
index e9e8bbe..50fdc3b 100644
--- a/gcc/d/dmd/aggregate.d
+++ b/gcc/d/dmd/aggregate.d
@@ -193,7 +193,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
*/
final size_t nonHiddenFields()
{
- return fields.dim - isNested() - (vthis2 !is null);
+ return fields.length - isNested() - (vthis2 !is null);
}
/***************************************
@@ -274,7 +274,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
{
//printf("AggregateDeclaration::checkOverlappedFields() %s\n", toChars());
assert(sizeok == Sizeok.done);
- size_t nfields = fields.dim;
+ size_t nfields = fields.length;
if (isNested())
{
auto cd = isClassDeclaration();
@@ -362,7 +362,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
const nfields = nonHiddenFields();
bool errors = false;
- size_t dim = elements.dim;
+ size_t dim = elements.length;
elements.setDim(nfields);
foreach (size_t i; dim .. nfields)
elements[i] = null;
@@ -774,7 +774,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
}
}
- for (size_t i = 0; i < members.dim; i++)
+ for (size_t i = 0; i < members.length; i++)
{
auto sm = (*members)[i];
sm.apply(&SearchCtor.fp, null);
diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d
index 3f27cb9..55d69b5 100644
--- a/gcc/d/dmd/attrib.d
+++ b/gcc/d/dmd/attrib.d
@@ -781,7 +781,7 @@ extern (C++) final class AnonDeclaration : AttribDeclaration
* so in order to place that member we need to compute the member's
* size and alignment.
*/
- size_t fieldstart = ad.fields.dim;
+ size_t fieldstart = ad.fields.length;
/* Hackishly hijack ad's structsize and alignsize fields
* for use in our fake anon aggregate member.
@@ -804,7 +804,7 @@ extern (C++) final class AnonDeclaration : AttribDeclaration
* added in ad.fields, just update *poffset for the subsequent
* field offset calculation.
*/
- if (fieldstart == ad.fields.dim)
+ if (fieldstart == ad.fields.length)
{
ad.structsize = savestructsize;
ad.alignsize = savealignsize;
@@ -838,7 +838,7 @@ extern (C++) final class AnonDeclaration : AttribDeclaration
// Add to the anon fields the base offset of this anonymous aggregate
//printf("anon fields, anonoffset = %d\n", anonoffset);
- foreach (const i; fieldstart .. ad.fields.dim)
+ foreach (const i; fieldstart .. ad.fields.length)
{
VarDeclaration v = ad.fields[i];
//printf("\t[%d] %s %d\n", i, v.toChars(), v.offset);
@@ -1349,7 +1349,7 @@ extern (C++) final class UserAttributeDeclaration : AttribDeclaration
override Scope* newScope(Scope* sc)
{
Scope* sc2 = sc;
- if (atts && atts.dim)
+ if (atts && atts.length)
{
// create new one for changes
sc2 = sc.copy();
@@ -1369,9 +1369,9 @@ extern (C++) final class UserAttributeDeclaration : AttribDeclaration
extern (D) static Expressions* concat(Expressions* udas1, Expressions* udas2)
{
Expressions* udas;
- if (!udas1 || udas1.dim == 0)
+ if (!udas1 || udas1.length == 0)
udas = udas2;
- else if (!udas2 || udas2.dim == 0)
+ else if (!udas2 || udas2.length == 0)
udas = udas1;
else
{
@@ -1395,7 +1395,7 @@ extern (C++) final class UserAttributeDeclaration : AttribDeclaration
auto exps = new Expressions();
if (userAttribDecl && userAttribDecl !is this)
exps.push(new TupleExp(Loc.initial, userAttribDecl.getAttributes()));
- if (atts && atts.dim)
+ if (atts && atts.length)
exps.push(new TupleExp(Loc.initial, atts));
return exps;
}
diff --git a/gcc/d/dmd/blockexit.d b/gcc/d/dmd/blockexit.d
index 22c9dde..6456876 100644
--- a/gcc/d/dmd/blockexit.d
+++ b/gcc/d/dmd/blockexit.d
@@ -122,7 +122,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
override void visit(CompoundStatement cs)
{
- //printf("CompoundStatement.blockExit(%p) %d result = x%X\n", cs, cs.statements.dim, result);
+ //printf("CompoundStatement.blockExit(%p) %d result = x%X\n", cs, cs.statements.length, result);
result = BE.fallthru;
Statement slast = null;
foreach (s; *cs.statements)
@@ -547,7 +547,7 @@ BE checkThrow(ref const Loc loc, Expression exp, const bool mustNotThrow)
ClassDeclaration cd = t.isClassHandle();
assert(cd);
- if (cd == ClassDeclaration.errorException || ClassDeclaration.errorException.isBaseOf(cd, null))
+ if (cd.isErrorException())
{
return BE.errthrow;
}
diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d
index 09e3833..cb9289f 100644
--- a/gcc/d/dmd/canthrow.d
+++ b/gcc/d/dmd/canthrow.d
@@ -102,7 +102,7 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN
if (global.errors && !ce.e1.type)
return; // error recovery
- if (ce.f && ce.arguments.dim > 0)
+ if (ce.f && ce.arguments.length > 0)
{
Type tb = (*ce.arguments)[0].type.toBasetype();
auto tbNext = tb.nextOf();
diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d
index c999048..c030d35 100644
--- a/gcc/d/dmd/clone.d
+++ b/gcc/d/dmd/clone.d
@@ -870,17 +870,17 @@ void buildDtors(AggregateDeclaration ad, Scope* sc)
return; // unions don't have destructors
StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;
- Loc declLoc = ad.userDtors.dim ? ad.userDtors[0].loc : ad.loc;
+ Loc declLoc = ad.userDtors.length ? ad.userDtors[0].loc : ad.loc;
Loc loc; // internal code should have no loc to prevent coverage
FuncDeclaration xdtor_fwd = null;
// Build the field destructor (`ad.fieldDtor`), if needed.
// If the user dtor is an extern(C++) prototype, then we expect it performs a full-destruction and skip building.
- const bool dtorIsCppPrototype = ad.userDtors.dim && ad.userDtors[0]._linkage == LINK.cpp && !ad.userDtors[0].fbody;
+ const bool dtorIsCppPrototype = ad.userDtors.length && ad.userDtors[0]._linkage == LINK.cpp && !ad.userDtors[0].fbody;
if (!dtorIsCppPrototype)
{
Expression e = null;
- for (size_t i = 0; i < ad.fields.dim; i++)
+ for (size_t i = 0; i < ad.fields.length; i++)
{
auto v = ad.fields[i];
if (v.storage_class & STC.ref_)
@@ -985,7 +985,7 @@ void buildDtors(AggregateDeclaration ad, Scope* sc)
}
// Set/build `ad.aggrDtor`
- switch (dtors.dim)
+ switch (dtors.length)
{
case 0:
break;
@@ -1168,7 +1168,7 @@ private DtorDeclaration buildExternDDtor(AggregateDeclaration ad, Scope* sc)
*/
FuncDeclaration buildInv(AggregateDeclaration ad, Scope* sc)
{
- switch (ad.invs.dim)
+ switch (ad.invs.length)
{
case 0:
return null;
@@ -1225,11 +1225,11 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc)
if (sd.isUnionDeclaration())
return null;
- const hasUserDefinedPosblit = sd.postblits.dim && !sd.postblits[0].isDisabled ? true : false;
+ const hasUserDefinedPosblit = sd.postblits.length && !sd.postblits[0].isDisabled ? true : false;
// by default, the storage class of the created postblit
StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;
- Loc declLoc = sd.postblits.dim ? sd.postblits[0].loc : sd.loc;
+ Loc declLoc = sd.postblits.length ? sd.postblits[0].loc : sd.loc;
Loc loc; // internal code should have no loc to prevent coverage
// if any of the postblits are disabled, then the generated postblit
@@ -1240,7 +1240,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc)
VarDeclaration[] fieldsToDestroy;
auto postblitCalls = new Statements();
// iterate through all the struct fields that are not disabled
- for (size_t i = 0; i < sd.fields.dim && !(stc & STC.disable); i++)
+ for (size_t i = 0; i < sd.fields.length && !(stc & STC.disable); i++)
{
auto structField = sd.fields[i];
if (structField.storage_class & STC.ref_)
@@ -1411,7 +1411,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc)
}
// Build our own "postblit" which executes a, but only if needed.
- if (postblitCalls.dim || (stc & STC.disable))
+ if (postblitCalls.length || (stc & STC.disable))
{
//printf("Building __fieldPostBlit()\n");
checkShared();
@@ -1426,7 +1426,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc)
// create __xpostblit, which is the generated postblit
FuncDeclaration xpostblit = null;
- switch (sd.postblits.dim)
+ switch (sd.postblits.length)
{
case 0:
break;
diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d
index 65085f5..c1e1e4d 100644
--- a/gcc/d/dmd/cond.d
+++ b/gcc/d/dmd/cond.d
@@ -222,7 +222,7 @@ extern (C++) final class StaticForeach : RootObject
}
else
{
- assert(rangefe && parameters.dim == 1);
+ assert(rangefe && parameters.length == 1);
return new ForeachRangeStatement(loc, rangefe.op, (*parameters)[0], rangefe.lwr.syntaxCopy(), rangefe.upr.syntaxCopy(), s, loc);
}
}
@@ -306,7 +306,7 @@ extern (C++) final class StaticForeach : RootObject
private void lowerNonArrayAggregate(Scope* sc)
{
- auto nvars = aggrfe ? aggrfe.parameters.dim : 1;
+ auto nvars = aggrfe ? aggrfe.parameters.length : 1;
auto aloc = aggrfe ? aggrfe.aggr.loc : rangefe.lwr.loc;
// We need three sets of foreach loop variables because the
// lowering contains three foreach loops.
@@ -332,7 +332,7 @@ extern (C++) final class StaticForeach : RootObject
{
foreach (i; 0 .. 2)
{
- auto e = new Expressions(pparams[0].dim);
+ auto e = new Expressions(pparams[0].length);
foreach (j, ref elem; *e)
{
auto p = (*pparams[i])[j];
diff --git a/gcc/d/dmd/constfold.d b/gcc/d/dmd/constfold.d
index f4e44e8..ef684ba 100644
--- a/gcc/d/dmd/constfold.d
+++ b/gcc/d/dmd/constfold.d
@@ -644,7 +644,7 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e
}
else if (ArrayLiteralExp es2 = e2.isArrayLiteralExp())
{
- cmp = !es2.elements || (0 == es2.elements.dim);
+ cmp = !es2.elements || (0 == es2.elements.length);
}
else
{
@@ -660,7 +660,7 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e
}
else if (ArrayLiteralExp es1 = e1.isArrayLiteralExp())
{
- cmp = !es1.elements || (0 == es1.elements.dim);
+ cmp = !es1.elements || (0 == es1.elements.length);
}
else
{
@@ -689,15 +689,15 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e
{
ArrayLiteralExp es1 = e1.isArrayLiteralExp();
ArrayLiteralExp es2 = e2.isArrayLiteralExp();
- if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim))
+ if ((!es1.elements || !es1.elements.length) && (!es2.elements || !es2.elements.length))
cmp = 1; // both arrays are empty
else if (!es1.elements || !es2.elements)
cmp = 0;
- else if (es1.elements.dim != es2.elements.dim)
+ else if (es1.elements.length != es2.elements.length)
cmp = 0;
else
{
- for (size_t i = 0; i < es1.elements.dim; i++)
+ for (size_t i = 0; i < es1.elements.length; i++)
{
auto ee1 = es1[i];
auto ee2 = es2[i];
@@ -724,7 +724,7 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e
StringExp es1 = e1.isStringExp();
ArrayLiteralExp es2 = e2.isArrayLiteralExp();
size_t dim1 = es1.len;
- size_t dim2 = es2.elements ? es2.elements.dim : 0;
+ size_t dim2 = es2.elements ? es2.elements.length : 0;
if (dim1 != dim2)
cmp = 0;
else
@@ -751,16 +751,16 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e
StructLiteralExp es2 = e2.isStructLiteralExp();
if (es1.sd != es2.sd)
cmp = 0;
- else if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim))
+ else if ((!es1.elements || !es1.elements.length) && (!es2.elements || !es2.elements.length))
cmp = 1; // both arrays are empty
else if (!es1.elements || !es2.elements)
cmp = 0;
- else if (es1.elements.dim != es2.elements.dim)
+ else if (es1.elements.length != es2.elements.length)
cmp = 0;
else
{
cmp = 1;
- for (size_t i = 0; i < es1.elements.dim; i++)
+ for (size_t i = 0; i < es1.elements.length; i++)
{
Expression ee1 = (*es1.elements)[i];
Expression ee2 = (*es2.elements)[i];
@@ -1074,7 +1074,7 @@ UnionExp Cast(const ref Loc loc, Type type, Type to, Expression e1)
StructDeclaration sd = tb.toDsymbol(null).isStructDeclaration();
assert(sd);
auto elements = new Expressions();
- for (size_t i = 0; i < sd.fields.dim; i++)
+ for (size_t i = 0; i < sd.fields.length; i++)
{
VarDeclaration v = sd.fields[i];
UnionExp zero;
@@ -1110,12 +1110,12 @@ UnionExp ArrayLength(Type type, Expression e1)
}
else if (ArrayLiteralExp ale = e1.isArrayLiteralExp())
{
- size_t dim = ale.elements ? ale.elements.dim : 0;
+ size_t dim = ale.elements ? ale.elements.length : 0;
emplaceExp!(IntegerExp)(&ue, loc, dim, type);
}
else if (AssocArrayLiteralExp ale = e1.isAssocArrayLiteralExp)
{
- size_t dim = ale.keys.dim;
+ size_t dim = ale.keys.length;
emplaceExp!(IntegerExp)(&ue, loc, dim, type);
}
else if (e1.type.toBasetype().ty == Tsarray)
@@ -1183,9 +1183,9 @@ UnionExp Index(Type type, Expression e1, Expression e2, bool indexIsInBounds)
uinteger_t i = e2.toInteger();
if (ArrayLiteralExp ale = e1.isArrayLiteralExp())
{
- if (i >= ale.elements.dim)
+ if (i >= ale.elements.length)
{
- e1.error("array index %llu is out of bounds `%s[0 .. %llu]`", i, e1.toChars(), cast(ulong) ale.elements.dim);
+ e1.error("array index %llu is out of bounds `%s[0 .. %llu]`", i, e1.toChars(), cast(ulong) ale.elements.length);
emplaceExp!(ErrorExp)(&ue);
}
else
@@ -1206,7 +1206,7 @@ UnionExp Index(Type type, Expression e1, Expression e2, bool indexIsInBounds)
{
/* Search the keys backwards, in case there are duplicate keys
*/
- for (size_t i = ae.keys.dim; i;)
+ for (size_t i = ae.keys.length; i;)
{
i--;
Expression ekey = (*ae.keys)[i];
@@ -1274,7 +1274,7 @@ UnionExp Slice(Type type, Expression e1, Expression lwr, Expression upr)
ArrayLiteralExp es1 = e1.isArrayLiteralExp();
const uinteger_t ilwr = lwr.toInteger();
const uinteger_t iupr = upr.toInteger();
- if (sliceBoundsCheck(0, es1.elements.dim, ilwr, iupr))
+ if (sliceBoundsCheck(0, es1.elements.length, ilwr, iupr))
cantExp(ue);
else
{
@@ -1318,7 +1318,7 @@ void sliceAssignArrayLiteralFromString(ArrayLiteralExp existingAE, const StringE
void sliceAssignStringFromArrayLiteral(StringExp existingSE, ArrayLiteralExp newae, size_t firstIndex)
{
assert(existingSE.ownedByCtfe != OwnedBy.code);
- foreach (j; 0 .. newae.elements.dim)
+ foreach (j; 0 .. newae.elements.length)
{
existingSE.setCodeUnit(firstIndex + j, cast(dchar)newae[j].toInteger());
}
@@ -1383,9 +1383,9 @@ private Expressions* copyElements(Expression e1, Expression e2 = null)
{
if (!ale.elements)
return;
- auto d = elems.dim;
+ auto d = elems.length;
elems.append(ale.elements);
- foreach (ref el; (*elems)[d .. elems.dim])
+ foreach (ref el; (*elems)[d .. elems.length])
{
if (!el)
el = ale.basis;
@@ -1524,15 +1524,15 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2)
// [chars] ~ string --> [chars]
StringExp es = e2.isStringExp();
ArrayLiteralExp ea = e1.isArrayLiteralExp();
- size_t len = es.len + ea.elements.dim;
+ size_t len = es.len + ea.elements.length;
auto elems = new Expressions(len);
- for (size_t i = 0; i < ea.elements.dim; ++i)
+ for (size_t i = 0; i < ea.elements.length; ++i)
{
(*elems)[i] = ea[i];
}
emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, type, elems);
ArrayLiteralExp dest = ue.exp().isArrayLiteralExp();
- sliceAssignArrayLiteralFromString(dest, es, ea.elements.dim);
+ sliceAssignArrayLiteralFromString(dest, es, ea.elements.length);
assert(ue.exp().type);
return ue;
}
@@ -1541,9 +1541,9 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2)
// string ~ [chars] --> [chars]
StringExp es = e1.isStringExp();
ArrayLiteralExp ea = e2.isArrayLiteralExp();
- size_t len = es.len + ea.elements.dim;
+ size_t len = es.len + ea.elements.length;
auto elems = new Expressions(len);
- for (size_t i = 0; i < ea.elements.dim; ++i)
+ for (size_t i = 0; i < ea.elements.length; ++i)
{
(*elems)[es.len + i] = ea[i];
}
@@ -1609,7 +1609,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2)
e = ue.exp();
if (type.toBasetype().ty == Tsarray)
{
- e.type = t1.nextOf().sarrayOf(elems.dim);
+ e.type = t1.nextOf().sarrayOf(elems.length);
}
else
e.type = type;
@@ -1633,7 +1633,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2)
e = ue.exp();
if (type.toBasetype().ty == Tsarray)
{
- e.type = t1.nextOf().sarrayOf(elems.dim);
+ e.type = t1.nextOf().sarrayOf(elems.length);
}
else
e.type = type;
@@ -1651,7 +1651,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2)
e = ue.exp();
if (type.toBasetype().ty == Tsarray)
{
- e.type = e2.type.sarrayOf(elems.dim);
+ e.type = e2.type.sarrayOf(elems.length);
}
else
e.type = type;
@@ -1667,7 +1667,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2)
e = ue.exp();
if (type.toBasetype().ty == Tsarray)
{
- e.type = e1.type.sarrayOf(elems.dim);
+ e.type = e1.type.sarrayOf(elems.length);
}
else
e.type = type;
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index ad1ad67..d4416ab 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -4816,7 +4816,13 @@ final class CParser(AST) : Parser!AST
else if (auto tt = t.isTypeTag())
tt.mod |= MODFlags.const_;
else
- t = t.addSTC(STC.const_);
+ {
+ /* Ignore const if the result would be const pointer to mutable
+ */
+ auto tn = t.nextOf();
+ if (!tn || tn.isConst())
+ t = t.addSTC(STC.const_);
+ }
return t;
}
diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d
index 7c130e9..fbe9f01 100644
--- a/gcc/d/dmd/cppmangle.d
+++ b/gcc/d/dmd/cppmangle.d
@@ -534,10 +534,10 @@ private final class CppMangleVisitor : Visitor
{
/* <template-args> ::= I <template-arg>+ E
*/
- if (!ti || ti.tiargs.dim <= firstArg) // could happen if std::basic_string is not a template
+ if (!ti || ti.tiargs.length <= firstArg) // could happen if std::basic_string is not a template
return false;
buf.writeByte('I');
- foreach (i; firstArg .. ti.tiargs.dim)
+ foreach (i; firstArg .. ti.tiargs.length)
{
TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration();
assert(td);
@@ -556,7 +556,7 @@ private final class CppMangleVisitor : Visitor
buf.writeByte('J'); // argument pack
// mangle the rest of the arguments as types
- foreach (j; i .. (*ti.tiargs).dim)
+ foreach (j; i .. (*ti.tiargs).length)
{
Type t = isType((*ti.tiargs)[j]);
assert(t);
@@ -760,7 +760,7 @@ private final class CppMangleVisitor : Visitor
return false;
Dsymbol q = getQualifier(ti);
const bool inStd = isStd(q) || isStd(this.getTiNamespace(ti));
- return inStd && ti.tiargs.dim == 1 && isChar((*ti.tiargs)[0]);
+ return inStd && ti.tiargs.length == 1 && isChar((*ti.tiargs)[0]);
}
/***
@@ -771,7 +771,7 @@ private final class CppMangleVisitor : Visitor
*/
bool char_std_char_traits_char(TemplateInstance ti, string st)
{
- if (ti.tiargs.dim == 2 &&
+ if (ti.tiargs.length == 2 &&
isChar((*ti.tiargs)[0]) &&
isChar_traits_char((*ti.tiargs)[1]))
{
@@ -851,7 +851,7 @@ private final class CppMangleVisitor : Visitor
if (ti.name == Id.basic_string)
{
// ::std::basic_string<char, ::std::char_traits<char>, ::std::allocator<char>>
- if (ti.tiargs.dim == 3 &&
+ if (ti.tiargs.length == 3 &&
isChar((*ti.tiargs)[0]) &&
isChar_traits_char((*ti.tiargs)[1]) &&
isAllocator_char((*ti.tiargs)[2]))
@@ -933,7 +933,7 @@ private final class CppMangleVisitor : Visitor
else if (s.ident == Id.basic_string)
{
// ::std::basic_string<char, ::std::char_traits<char>, ::std::allocator<char>>
- if (ti.tiargs.dim == 3 &&
+ if (ti.tiargs.length == 3 &&
isChar((*ti.tiargs)[0]) &&
isChar_traits_char((*ti.tiargs)[1]) &&
isAllocator_char((*ti.tiargs)[2]))
@@ -1224,7 +1224,7 @@ private final class CppMangleVisitor : Visitor
case CppOperator.OpAssign:
TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration();
assert(td);
- assert(ti.tiargs.dim >= 1);
+ assert(ti.tiargs.length >= 1);
TemplateParameter tp = (*td.parameters)[0];
TemplateValueParameter tv = tp.isTemplateValueParameter();
if (!tv || !tv.valType.isString())
@@ -2005,14 +2005,14 @@ extern(C++):
this.context.res = (*analyzed_ti.tiargs)[idx];
o.visitObject(this);
}
- if (analyzed_ti.tiargs.dim > t.tiargs.dim)
+ if (analyzed_ti.tiargs.length > t.tiargs.length)
{
// If the resolved AST has more args than the parse one,
// we have default arguments
auto oparams = (cast(TemplateDeclaration)analyzed_ti.tempdecl).origParameters;
- foreach (idx, arg; (*oparams)[t.tiargs.dim .. $])
+ foreach (idx, arg; (*oparams)[t.tiargs.length .. $])
{
- this.context.res = (*analyzed_ti.tiargs)[idx + t.tiargs.dim];
+ this.context.res = (*analyzed_ti.tiargs)[idx + t.tiargs.length];
if (auto ttp = arg.isTemplateTypeParameter())
ttp.defaultType.accept(this);
diff --git a/gcc/d/dmd/ctfeexpr.d b/gcc/d/dmd/ctfeexpr.d
index 6243e74..1dc1f7d 100644
--- a/gcc/d/dmd/ctfeexpr.d
+++ b/gcc/d/dmd/ctfeexpr.d
@@ -62,17 +62,17 @@ extern (C++) final class ClassReferenceExp : Expression
{
ClassDeclaration cd = originalClass();
uint fieldsSoFar = 0;
- for (size_t j = 0; j < value.elements.dim; j++)
+ for (size_t j = 0; j < value.elements.length; j++)
{
- while (j - fieldsSoFar >= cd.fields.dim)
+ while (j - fieldsSoFar >= cd.fields.length)
{
- fieldsSoFar += cd.fields.dim;
+ fieldsSoFar += cd.fields.length;
cd = cd.baseClass;
}
VarDeclaration v2 = cd.fields[j - fieldsSoFar];
if (fieldoffset == v2.offset && fieldtype.size() == v2.type.size())
{
- return cast(int)(value.elements.dim - fieldsSoFar - cd.fields.dim + (j - fieldsSoFar));
+ return cast(int)(value.elements.length - fieldsSoFar - cd.fields.length + (j - fieldsSoFar));
}
}
return -1;
@@ -84,17 +84,17 @@ extern (C++) final class ClassReferenceExp : Expression
{
ClassDeclaration cd = originalClass();
size_t fieldsSoFar = 0;
- for (size_t j = 0; j < value.elements.dim; j++)
+ for (size_t j = 0; j < value.elements.length; j++)
{
- while (j - fieldsSoFar >= cd.fields.dim)
+ while (j - fieldsSoFar >= cd.fields.length)
{
- fieldsSoFar += cd.fields.dim;
+ fieldsSoFar += cd.fields.length;
cd = cd.baseClass;
}
VarDeclaration v2 = cd.fields[j - fieldsSoFar];
if (v == v2)
{
- return cast(int)(value.elements.dim - fieldsSoFar - cd.fields.dim + (j - fieldsSoFar));
+ return cast(int)(value.elements.length - fieldsSoFar - cd.fields.length + (j - fieldsSoFar));
}
}
return -1;
@@ -267,7 +267,7 @@ private Expressions* copyLiteralArray(Expressions* oldelems, Expression basis =
if (!oldelems)
return oldelems;
incArrayAllocs();
- auto newelems = new Expressions(oldelems.dim);
+ auto newelems = new Expressions(oldelems.length);
foreach (i, el; *oldelems)
{
(*newelems)[i] = copyLiteral(el ? el : basis).copy();
@@ -318,7 +318,7 @@ UnionExp copyLiteral(Expression e)
* an int[4] array can be initialized with a single int.
*/
auto oldelems = sle.elements;
- auto newelems = new Expressions(oldelems.dim);
+ auto newelems = new Expressions(oldelems.length);
foreach (i, ref el; *newelems)
{
// We need the struct definition to detect block assignment
@@ -566,12 +566,12 @@ uinteger_t resolveArrayLength(Expression e)
case EXP.arrayLiteral:
{
const ale = e.isArrayLiteralExp();
- return ale.elements ? ale.elements.dim : 0;
+ return ale.elements ? ale.elements.length : 0;
}
case EXP.assocArrayLiteral:
{
- return e.isAssocArrayLiteralExp().keys.dim;
+ return e.isAssocArrayLiteralExp().keys.length;
}
default:
@@ -1312,15 +1312,15 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide
// For structs, we only need to return 0 or 1 (< and > aren't legal).
if (es1.sd != es2.sd)
return 1;
- else if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim))
+ else if ((!es1.elements || !es1.elements.length) && (!es2.elements || !es2.elements.length))
return 0; // both arrays are empty
else if (!es1.elements || !es2.elements)
return 1;
- else if (es1.elements.dim != es2.elements.dim)
+ else if (es1.elements.length != es2.elements.length)
return 1;
else
{
- foreach (size_t i; 0 .. es1.elements.dim)
+ foreach (size_t i; 0 .. es1.elements.length)
{
Expression ee1 = (*es1.elements)[i];
Expression ee2 = (*es2.elements)[i];
@@ -1344,8 +1344,8 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide
{
AssocArrayLiteralExp es1 = e1.isAssocArrayLiteralExp();
AssocArrayLiteralExp es2 = e2.isAssocArrayLiteralExp();
- size_t dim = es1.keys.dim;
- if (es2.keys.dim != dim)
+ size_t dim = es1.keys.length;
+ if (es2.keys.length != dim)
return 1;
bool* used = cast(bool*)mem.xmalloc(bool.sizeof * dim);
memset(used, 0, bool.sizeof * dim);
@@ -1376,11 +1376,11 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide
}
else if (e1.op == EXP.assocArrayLiteral && e2.op == EXP.null_)
{
- return e1.isAssocArrayLiteralExp.keys.dim != 0;
+ return e1.isAssocArrayLiteralExp.keys.length != 0;
}
else if (e1.op == EXP.null_ && e2.op == EXP.assocArrayLiteral)
{
- return e2.isAssocArrayLiteralExp.keys.dim != 0;
+ return e2.isAssocArrayLiteralExp.keys.length != 0;
}
error(loc, "CTFE internal error: bad compare of `%s` and `%s`", e1.toChars(), e2.toChars());
@@ -1461,12 +1461,12 @@ UnionExp ctfeCat(const ref Loc loc, Type type, Expression e1, Expression e2)
// [chars] ~ string => string (only valid for CTFE)
StringExp es1 = e2.isStringExp();
ArrayLiteralExp es2 = e1.isArrayLiteralExp();
- const len = es1.len + es2.elements.dim;
+ const len = es1.len + es2.elements.length;
const sz = es1.sz;
void* s = mem.xmalloc((len + 1) * sz);
const data1 = es1.peekData();
- memcpy(cast(char*)s + sz * es2.elements.dim, data1.ptr, data1.length);
- foreach (size_t i; 0 .. es2.elements.dim)
+ memcpy(cast(char*)s + sz * es2.elements.length, data1.ptr, data1.length);
+ foreach (size_t i; 0 .. es2.elements.length)
{
Expression es2e = (*es2.elements)[i];
if (es2e.op != EXP.int64)
@@ -1491,12 +1491,12 @@ UnionExp ctfeCat(const ref Loc loc, Type type, Expression e1, Expression e2)
// Concatenate the strings
StringExp es1 = e1.isStringExp();
ArrayLiteralExp es2 = e2.isArrayLiteralExp();
- const len = es1.len + es2.elements.dim;
+ const len = es1.len + es2.elements.length;
const sz = es1.sz;
void* s = mem.xmalloc((len + 1) * sz);
auto slice = es1.peekData();
memcpy(s, slice.ptr, slice.length);
- foreach (size_t i; 0 .. es2.elements.dim)
+ foreach (size_t i; 0 .. es2.elements.length)
{
Expression es2e = (*es2.elements)[i];
if (es2e.op != EXP.int64)
@@ -1523,7 +1523,7 @@ UnionExp ctfeCat(const ref Loc loc, Type type, Expression e1, Expression e2)
ArrayLiteralExp es2 = e2.isArrayLiteralExp();
emplaceExp!(ArrayLiteralExp)(&ue, es1.loc, type, copyLiteralArray(es1.elements));
es1 = ue.exp().isArrayLiteralExp();
- es1.elements.insert(es1.elements.dim, copyLiteralArray(es2.elements));
+ es1.elements.insert(es1.elements.length, copyLiteralArray(es2.elements));
return ue;
}
if (e1.op == EXP.arrayLiteral && e2.op == EXP.null_ && t1.nextOf().equals(t2.nextOf()))
@@ -1549,7 +1549,7 @@ Expression findKeyInAA(const ref Loc loc, AssocArrayLiteralExp ae, Expression e2
{
/* Search the keys backwards, in case there are duplicate keys
*/
- for (size_t i = ae.keys.dim; i;)
+ for (size_t i = ae.keys.length; i;)
{
--i;
Expression ekey = (*ae.keys)[i];
@@ -1583,9 +1583,9 @@ Expression ctfeIndex(UnionExp* pue, const ref Loc loc, Type type, Expression e1,
if (auto ale = e1.isArrayLiteralExp())
{
- if (indx >= ale.elements.dim)
+ if (indx >= ale.elements.length)
{
- error(loc, "array index %llu is out of bounds `%s[0 .. %llu]`", indx, e1.toChars(), cast(ulong)ale.elements.dim);
+ error(loc, "array index %llu is out of bounds `%s[0 .. %llu]`", indx, e1.toChars(), cast(ulong)ale.elements.length);
return CTFEExp.cantexp;
}
Expression e = (*ale.elements)[cast(size_t)indx];
@@ -1685,9 +1685,9 @@ void assignInPlace(Expression dest, Expression src)
newelems = src.isStructLiteralExp().elements;
auto sd = dest.isStructLiteralExp().sd;
const nfields = sd.nonHiddenFields();
- const nvthis = sd.fields.dim - nfields;
- if (nvthis && oldelems.dim >= nfields && oldelems.dim < newelems.dim)
- foreach (_; 0 .. newelems.dim - oldelems.dim)
+ const nvthis = sd.fields.length - nfields;
+ if (nvthis && oldelems.length >= nfields && oldelems.length < newelems.length)
+ foreach (_; 0 .. newelems.length - oldelems.length)
oldelems.push(null);
}
else if (dest.op == EXP.arrayLiteral && src.op == EXP.arrayLiteral)
@@ -1715,8 +1715,8 @@ void assignInPlace(Expression dest, Expression src)
printf("invalid op %d %d\n", src.op, dest.op);
assert(0);
}
- assert(oldelems.dim == newelems.dim);
- foreach (size_t i; 0 .. oldelems.dim)
+ assert(oldelems.length == newelems.length);
+ foreach (size_t i; 0 .. oldelems.length)
{
Expression e = (*newelems)[i];
Expression o = (*oldelems)[i];
@@ -1744,7 +1744,7 @@ Expression assignAssocArrayElement(const ref Loc loc, AssocArrayLiteralExp aae,
Expressions* keysx = aae.keys;
Expressions* valuesx = aae.values;
int updated = 0;
- for (size_t j = valuesx.dim; j;)
+ for (size_t j = valuesx.length; j;)
{
j--;
Expression ekey = (*aae.keys)[j];
@@ -2029,13 +2029,13 @@ void showCtfeExpr(Expression e, int level = 0)
if (elements)
{
size_t fieldsSoFar = 0;
- for (size_t i = 0; i < elements.dim; i++)
+ for (size_t i = 0; i < elements.length; i++)
{
Expression z = null;
VarDeclaration v = null;
if (i > 15)
{
- printf("...(total %d elements)\n", cast(int)elements.dim);
+ printf("...(total %d elements)\n", cast(int)elements.length);
return;
}
if (sd)
@@ -2045,18 +2045,18 @@ void showCtfeExpr(Expression e, int level = 0)
}
else if (cd)
{
- while (i - fieldsSoFar >= cd.fields.dim)
+ while (i - fieldsSoFar >= cd.fields.length)
{
- fieldsSoFar += cd.fields.dim;
+ fieldsSoFar += cd.fields.length;
cd = cd.baseClass;
for (int j = level; j > 0; --j)
printf(" ");
printf(" BASE CLASS: %s\n", cd.toChars());
}
v = cd.fields[i - fieldsSoFar];
- assert((elements.dim + i) >= (fieldsSoFar + cd.fields.dim));
- size_t indx = (elements.dim - fieldsSoFar) - cd.fields.dim + i;
- assert(indx < elements.dim);
+ assert((elements.length + i) >= (fieldsSoFar + cd.fields.length));
+ size_t indx = (elements.length - fieldsSoFar) - cd.fields.length + i;
+ assert(indx < elements.length);
z = (*elements)[indx];
}
if (!z)
@@ -2108,8 +2108,8 @@ UnionExp voidInitLiteral(Type t, VarDeclaration var)
else if (t.ty == Tstruct)
{
TypeStruct ts = cast(TypeStruct)t;
- auto exps = new Expressions(ts.sym.fields.dim);
- foreach (size_t i; 0 .. ts.sym.fields.dim)
+ auto exps = new Expressions(ts.sym.fields.length);
+ foreach (size_t i; 0 .. ts.sym.fields.length)
{
(*exps)[i] = voidInitLiteral(ts.sym.fields[i].type, ts.sym.fields[i]).copy();
}
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index ba3afb7..02bf6cf 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -192,7 +192,7 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
{
Type tb = t.toBasetype();
Type tx = (tb.ty == Tsarray)
- ? tb.nextOf().sarrayOf(ale.elements ? ale.elements.dim : 0)
+ ? tb.nextOf().sarrayOf(ale.elements ? ale.elements.length : 0)
: tb.nextOf().arrayOf();
se.e1 = ale.implicitCastTo(sc, tx);
}
@@ -333,7 +333,7 @@ MATCH implicitConvTo(Expression e, Type t)
{
const size_t nparams = tf.parameterList.length;
const size_t j = tf.isDstyleVariadic(); // if TypeInfoArray was prepended
- foreach (const i; j .. args.dim)
+ foreach (const i; j .. args.length)
{
Expression earg = (*args)[i];
Type targ = earg.type.toBasetype();
@@ -749,12 +749,12 @@ MATCH implicitConvTo(Expression e, Type t)
if (auto tsa = tb.isTypeSArray())
{
- if (e.elements.dim != tsa.dim.toInteger())
+ if (e.elements.length != tsa.dim.toInteger())
result = MATCH.nomatch;
}
Type telement = tb.nextOf();
- if (!e.elements.dim)
+ if (!e.elements.length)
{
if (typen.ty != Tvoid)
result = typen.implicitConvTo(telement);
@@ -767,7 +767,7 @@ MATCH implicitConvTo(Expression e, Type t)
if (m < result)
result = m;
}
- for (size_t i = 0; i < e.elements.dim; i++)
+ for (size_t i = 0; i < e.elements.length; i++)
{
Expression el = (*e.elements)[i];
if (result == MATCH.nomatch)
@@ -792,7 +792,7 @@ MATCH implicitConvTo(Expression e, Type t)
TypeVector tv = tb.isTypeVector();
TypeSArray tbase = tv.basetype.isTypeSArray();
assert(tbase);
- const edim = e.elements.dim;
+ const edim = e.elements.length;
const tbasedim = tbase.dim.toInteger();
if (edim > tbasedim)
{
@@ -1233,7 +1233,7 @@ MATCH implicitConvTo(Expression e, Type t)
*/
if (!e.member && e.arguments)
{
- for (size_t i = 0; i < e.arguments.dim; ++i)
+ for (size_t i = 0; i < e.arguments.length; ++i)
{
Expression earg = (*e.arguments)[i];
if (!earg) // https://issues.dlang.org/show_bug.cgi?id=14853
@@ -1284,7 +1284,7 @@ MATCH implicitConvTo(Expression e, Type t)
{
extern (C++) static bool convertible(Expression e, ClassDeclaration cd, MOD mod)
{
- for (size_t i = 0; i < cd.fields.dim; i++)
+ for (size_t i = 0; i < cd.fields.length; i++)
{
VarDeclaration v = cd.fields[i];
Initializer _init = v._init;
@@ -2101,7 +2101,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
{
OverExp eo = e.e1.isOverExp();
FuncDeclaration f = null;
- for (size_t i = 0; i < eo.vars.a.dim; i++)
+ for (size_t i = 0; i < eo.vars.a.length; i++)
{
auto s = eo.vars.a[i];
auto f2 = s.isFuncDeclaration();
@@ -2177,7 +2177,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
TupleExp te = e.copy().isTupleExp();
te.e0 = e.e0 ? e.e0.copy() : null;
te.exps = e.exps.copy();
- for (size_t i = 0; i < te.exps.dim; i++)
+ for (size_t i = 0; i < te.exps.length; i++)
{
Expression ex = (*te.exps)[i];
ex = ex.castTo(sc, totuple ? (*totuple.arguments)[i].type : t);
@@ -2239,7 +2239,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
{
if (auto tsa = tb.isTypeSArray())
{
- if (e.elements.dim != tsa.dim.toInteger())
+ if (e.elements.length != tsa.dim.toInteger())
goto L1;
}
@@ -2247,7 +2247,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
if (e.basis)
ae.basis = e.basis.castTo(sc, tb.nextOf());
ae.elements = e.elements.copy();
- for (size_t i = 0; i < e.elements.dim; i++)
+ for (size_t i = 0; i < e.elements.length; i++)
{
Expression ex = (*e.elements)[i];
if (!ex)
@@ -2274,7 +2274,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
TypeVector tv = tb.isTypeVector();
TypeSArray tbase = tv.basetype.isTypeSArray();
assert(tbase.ty == Tsarray);
- const edim = e.elements.dim;
+ const edim = e.elements.length;
const tbasedim = tbase.dim.toInteger();
if (edim > tbasedim)
goto L1;
@@ -2322,8 +2322,8 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
AssocArrayLiteralExp ae = e.copy().isAssocArrayLiteralExp();
ae.keys = e.keys.copy();
ae.values = e.values.copy();
- assert(e.keys.dim == e.values.dim);
- for (size_t i = 0; i < e.keys.dim; i++)
+ assert(e.keys.length == e.values.length);
+ for (size_t i = 0; i < e.keys.length; i++)
{
Expression ex = (*e.values)[i];
ex = ex.castTo(sc, tb.nextOf());
@@ -2637,7 +2637,7 @@ Expression inferType(Expression e, Type t, int flag = 0)
Type tn = tb.nextOf();
if (ale.basis)
ale.basis = inferType(ale.basis, tn, flag);
- for (size_t i = 0; i < ale.elements.dim; i++)
+ for (size_t i = 0; i < ale.elements.length; i++)
{
if (Expression e = (*ale.elements)[i])
{
@@ -2656,7 +2656,7 @@ Expression inferType(Expression e, Type t, int flag = 0)
{
Type ti = taa.index;
Type tv = taa.nextOf();
- for (size_t i = 0; i < aale.keys.dim; i++)
+ for (size_t i = 0; i < aale.keys.length; i++)
{
if (Expression e = (*aale.keys)[i])
{
@@ -2664,7 +2664,7 @@ Expression inferType(Expression e, Type t, int flag = 0)
(*aale.keys)[i] = e;
}
}
- for (size_t i = 0; i < aale.values.dim; i++)
+ for (size_t i = 0; i < aale.values.length; i++)
{
if (Expression e = (*aale.values)[i])
{
@@ -2772,7 +2772,7 @@ Expression scaleFactor(BinExp be, Scope* sc)
*/
private bool isVoidArrayLiteral(Expression e, Type other)
{
- while (e.op == EXP.arrayLiteral && e.type.ty == Tarray && (e.isArrayLiteralExp().elements.dim == 1))
+ while (e.op == EXP.arrayLiteral && e.type.ty == Tarray && (e.isArrayLiteralExp().elements.length == 1))
{
auto ale = e.isArrayLiteralExp();
e = ale[0];
@@ -2784,7 +2784,7 @@ private bool isVoidArrayLiteral(Expression e, Type other)
if (other.ty != Tsarray && other.ty != Tarray)
return false;
Type t = e.type;
- return (e.op == EXP.arrayLiteral && t.ty == Tarray && t.nextOf().ty == Tvoid && e.isArrayLiteralExp().elements.dim == 0);
+ return (e.op == EXP.arrayLiteral && t.ty == Tarray && t.nextOf().ty == Tvoid && e.isArrayLiteralExp().elements.length == 0);
}
/**
diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d
index a4a2abf..fc49b21 100644
--- a/gcc/d/dmd/dclass.d
+++ b/gcc/d/dmd/dclass.d
@@ -74,10 +74,10 @@ extern (C++) struct BaseClass
//printf("BaseClass.fillVtbl(this='%s', cd='%s')\n", sym.toChars(), cd.toChars());
if (vtbl)
- vtbl.setDim(sym.vtbl.dim);
+ vtbl.setDim(sym.vtbl.length);
// first entry is ClassInfo reference
- for (size_t j = sym.vtblOffset(); j < sym.vtbl.dim; j++)
+ for (size_t j = sym.vtblOffset(); j < sym.vtbl.length; j++)
{
FuncDeclaration ifd = sym.vtbl[j].isFuncDeclaration();
@@ -113,7 +113,7 @@ extern (C++) struct BaseClass
BaseClass* b = &baseInterfaces[i];
BaseClass* b2 = sym.interfaces[i];
- assert(b2.vtbl.dim == 0); // should not be filled yet
+ assert(b2.vtbl.length == 0); // should not be filled yet
memcpy(b, b2, BaseClass.sizeof);
if (i) // single inheritance is i==0
@@ -217,7 +217,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
this.members = members;
- //printf("ClassDeclaration(%s), dim = %d\n", ident.toChars(), this.baseclasses.dim);
+ //printf("ClassDeclaration(%s), dim = %d\n", ident.toChars(), this.baseclasses.length);
// For forward references
type = new TypeClass(this);
@@ -390,8 +390,8 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
cd.storage_class |= storage_class;
- cd.baseclasses.setDim(this.baseclasses.dim);
- for (size_t i = 0; i < cd.baseclasses.dim; i++)
+ cd.baseclasses.setDim(this.baseclasses.length);
+ for (size_t i = 0; i < cd.baseclasses.length; i++)
{
BaseClass* b = (*this.baseclasses)[i];
auto b2 = new BaseClass(b.type.syntaxCopy());
@@ -424,7 +424,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
if (!cd)
return false;
//printf("ClassDeclaration.isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars());
- for (size_t i = 0; i < cd.baseclasses.dim; i++)
+ for (size_t i = 0; i < cd.baseclasses.length; i++)
{
BaseClass* b = (*cd.baseclasses)[i];
if (b.sym == this || isBaseOf2(b.sym))
@@ -610,7 +610,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
if (!b.sym.alignsize)
b.sym.alignsize = target.ptrsize;
alignmember(structalign_t(cast(ushort)b.sym.alignsize), b.sym.alignsize, &offset);
- assert(bi < vtblInterfaces.dim);
+ assert(bi < vtblInterfaces.length);
BaseClass* bv = (*vtblInterfaces)[bi];
if (b.sym.interfaces.length == 0)
@@ -879,7 +879,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
return 0;
}
- for (size_t i = 0; i < members.dim; i++)
+ for (size_t i = 0; i < members.length; i++)
{
auto s = (*members)[i];
if (s.apply(&func))
@@ -917,7 +917,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
return 0;
}
- for (size_t i = 0; i < members.dim; i++)
+ for (size_t i = 0; i < members.length; i++)
{
auto s = (*members)[i];
s.apply(&virtualSemantic);
@@ -926,7 +926,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
/* Finally, check the vtbl[]
*/
- foreach (i; 1 .. vtbl.dim)
+ foreach (i; 1 .. vtbl.length)
{
auto fd = vtbl[i].isFuncDeclaration();
//if (fd) printf("\tvtbl[%d] = [%s] %s\n", i, fd.loc.toChars(), fd.toPrettyChars());
@@ -980,7 +980,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
{
if (!vtblsym)
{
- auto vtype = Type.tvoidptr.immutableOf().sarrayOf(vtbl.dim);
+ auto vtype = Type.tvoidptr.immutableOf().sarrayOf(vtbl.length);
auto var = new VarDeclaration(loc, vtype, Identifier.idPool("__vtbl"), null, STC.immutable_ | STC.static_);
var.addMember(null, this);
var.isdataseg = 1;
@@ -991,6 +991,11 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
return vtblsym;
}
+ extern (D) final bool isErrorException()
+ {
+ return errorException && (this == errorException || errorException.isBaseOf(this, null));
+ }
+
override final inout(ClassDeclaration) isClassDeclaration() inout @nogc nothrow pure @safe
{
return this;
diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d
index 07d58f0..3d0752c 100644
--- a/gcc/d/dmd/declaration.d
+++ b/gcc/d/dmd/declaration.d
@@ -66,7 +66,7 @@ bool checkFrameAccess(Loc loc, Scope* sc, AggregateDeclaration ad, size_t iStart
}
bool result = false;
- for (size_t i = iStart; i < ad.fields.dim; i++)
+ for (size_t i = iStart; i < ad.fields.length; i++)
{
VarDeclaration vd = ad.fields[i];
Type tb = vd.type.baseElemOf();
@@ -297,7 +297,7 @@ extern (C++) abstract class Declaration : Dsymbol
{
auto sd = p.isStructDeclaration();
assert(sd);
- for (size_t i = 0; i < sd.fields.dim; i++)
+ for (size_t i = 0; i < sd.fields.length; i++)
{
auto structField = sd.fields[i];
if (structField.overlapped)
@@ -606,7 +606,7 @@ extern (C++) final class TupleDeclaration : Declaration
{
/* It's only a type tuple if all the Object's are types
*/
- for (size_t i = 0; i < objects.dim; i++)
+ for (size_t i = 0; i < objects.length; i++)
{
RootObject o = (*objects)[i];
if (o.dyncast() != DYNCAST.type)
@@ -619,10 +619,10 @@ extern (C++) final class TupleDeclaration : Declaration
/* We know it's a type tuple, so build the TypeTuple
*/
Types* types = cast(Types*)objects;
- auto args = new Parameters(objects.dim);
+ auto args = new Parameters(objects.length);
OutBuffer buf;
int hasdeco = 1;
- for (size_t i = 0; i < types.dim; i++)
+ for (size_t i = 0; i < types.length; i++)
{
Type t = (*types)[i];
//printf("type = %s\n", t.toChars());
@@ -653,7 +653,7 @@ extern (C++) final class TupleDeclaration : Declaration
override Dsymbol toAlias2()
{
//printf("TupleDeclaration::toAlias2() '%s' objects = %s\n", toChars(), objects.toChars());
- for (size_t i = 0; i < objects.dim; i++)
+ for (size_t i = 0; i < objects.length; i++)
{
RootObject o = (*objects)[i];
if (Dsymbol s = isDsymbol(o))
@@ -1219,7 +1219,7 @@ extern (C++) class VarDeclaration : Declaration
fieldState.offset = ad.structsize; // https://issues.dlang.org/show_bug.cgi?id=13613
return;
}
- for (size_t i = 0; i < ad.fields.dim; i++)
+ for (size_t i = 0; i < ad.fields.length; i++)
{
if (ad.fields[i] == this)
{
diff --git a/gcc/d/dmd/delegatize.d b/gcc/d/dmd/delegatize.d
index 77e09bc..461f441 100644
--- a/gcc/d/dmd/delegatize.d
+++ b/gcc/d/dmd/delegatize.d
@@ -96,7 +96,7 @@ private void lambdaSetParent(Expression e, FuncDeclaration fd)
if (!vd || !pfd)
return;
// move to fd's closure when applicable
- foreach (i; 0 .. pfd.closureVars.dim)
+ foreach (i; 0 .. pfd.closureVars.length)
{
if (vd == pfd.closureVars[i])
{
diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d
index ef322f1..926186b 100644
--- a/gcc/d/dmd/denum.d
+++ b/gcc/d/dmd/denum.d
@@ -88,7 +88,7 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
version (none)
{
printf("EnumDeclaration::addMember() %s\n", toChars());
- for (size_t i = 0; i < members.dim; i++)
+ for (size_t i = 0; i < members.length; i++)
{
EnumMember em = (*members)[i].isEnumMember();
printf(" member %s\n", em.toChars());
@@ -191,7 +191,7 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
return handleErrors();
}
- foreach (const i; 0 .. members.dim)
+ foreach (const i; 0 .. members.length)
{
EnumMember em = (*members)[i].isEnumMember();
if (em)
diff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d
index 705acd1..1104005 100644
--- a/gcc/d/dmd/dimport.d
+++ b/gcc/d/dmd/dimport.d
@@ -114,7 +114,7 @@ extern (C++) final class Import : Dsymbol
assert(!s);
auto si = new Import(loc, packages, id, aliasId, isstatic);
si.comment = comment;
- for (size_t i = 0; i < names.dim; i++)
+ for (size_t i = 0; i < names.length; i++)
{
si.addAlias(names[i], aliases[i]);
}
@@ -241,11 +241,11 @@ extern (C++) final class Import : Dsymbol
mod.checkImportDeprecation(loc, sc);
if (sc.explicitVisibility)
visibility = sc.visibility;
- if (!isstatic && !aliasId && !names.dim)
+ if (!isstatic && !aliasId && !names.length)
sc.scopesym.importScope(mod, visibility);
// Enable access to pkgs/mod as soon as posible, because compiler
// can traverse them before the import gets semantic (Issue: 21501)
- if (!aliasId && !names.dim)
+ if (!aliasId && !names.length)
addPackageAccess(sc.scopesym);
}
@@ -296,14 +296,14 @@ extern (C++) final class Import : Dsymbol
override void addMember(Scope* sc, ScopeDsymbol sd)
{
//printf("Import.addMember(this=%s, sd=%s, sc=%p)\n", toChars(), sd.toChars(), sc);
- if (names.dim == 0)
+ if (names.length == 0)
return Dsymbol.addMember(sc, sd);
if (aliasId)
Dsymbol.addMember(sc, sd);
/* Instead of adding the import to sd's symbol table,
* add each of the alias=name pairs
*/
- for (size_t i = 0; i < names.dim; i++)
+ for (size_t i = 0; i < names.length; i++)
{
Identifier name = names[i];
Identifier _alias = aliases[i];
@@ -320,7 +320,7 @@ extern (C++) final class Import : Dsymbol
override void setScope(Scope* sc)
{
Dsymbol.setScope(sc);
- if (aliasdecls.dim)
+ if (aliasdecls.length)
{
if (!mod)
importAll(sc);
diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d
index 63b70009..e504cb4 100644
--- a/gcc/d/dmd/dinterpret.d
+++ b/gcc/d/dmd/dinterpret.d
@@ -282,7 +282,7 @@ private:
public:
extern (C++) size_t stackPointer()
{
- return values.dim;
+ return values.length;
}
// The current value of 'this', or NULL if none
@@ -308,12 +308,12 @@ public:
extern (C++) void endFrame()
{
- size_t oldframe = cast(size_t)frames[frames.dim - 1];
- localThis = savedThis[savedThis.dim - 1];
+ size_t oldframe = cast(size_t)frames[frames.length - 1];
+ localThis = savedThis[savedThis.length - 1];
popAll(framepointer);
framepointer = oldframe;
- frames.setDim(frames.dim - 1);
- savedThis.setDim(savedThis.dim - 1);
+ frames.setDim(frames.length - 1);
+ savedThis.setDim(savedThis.length - 1);
}
extern (C++) bool isInCurrentFrame(VarDeclaration v)
@@ -328,7 +328,7 @@ public:
//printf("getValue() %s\n", v.toChars());
if ((v.isDataseg() || v.storage_class & STC.manifest) && !v.isCTFE())
{
- assert(v.ctfeAdrOnStack < globalValues.dim);
+ assert(v.ctfeAdrOnStack < globalValues.length);
return globalValues[v.ctfeAdrOnStack];
}
assert(v.ctfeAdrOnStack < stackPointer());
@@ -354,7 +354,7 @@ public:
return;
}
savedId.push(cast(void*)cast(size_t)v.ctfeAdrOnStack);
- v.ctfeAdrOnStack = cast(uint)values.dim;
+ v.ctfeAdrOnStack = cast(uint)values.length;
vars.push(v);
values.push(null);
}
@@ -365,7 +365,7 @@ public:
assert(!v.isReference());
const oldid = v.ctfeAdrOnStack;
v.ctfeAdrOnStack = cast(uint)cast(size_t)savedId[oldid];
- if (v.ctfeAdrOnStack == values.dim - 1)
+ if (v.ctfeAdrOnStack == values.length - 1)
{
values.pop();
vars.pop();
@@ -377,8 +377,8 @@ public:
{
if (stackPointer() > maxStackPointer)
maxStackPointer = stackPointer();
- assert(values.dim >= stackpointer);
- for (size_t i = stackpointer; i < values.dim; ++i)
+ assert(values.length >= stackpointer);
+ for (size_t i = stackpointer; i < values.length; ++i)
{
VarDeclaration v = vars[i];
v.ctfeAdrOnStack = cast(uint)cast(size_t)savedId[i];
@@ -391,7 +391,7 @@ public:
extern (C++) void saveGlobalConstant(VarDeclaration v, Expression e)
{
assert(v._init && (v.isConst() || v.isImmutable() || v.storage_class & STC.manifest) && !v.isCTFE());
- v.ctfeAdrOnStack = cast(uint)globalValues.dim;
+ v.ctfeAdrOnStack = cast(uint)globalValues.length;
globalValues.push(copyRegionExp(e));
}
}
@@ -444,7 +444,7 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta
auto tf = fd.type.toBasetype().isTypeFunction();
if (tf.parameterList.varargs != VarArg.none && arguments &&
- ((fd.parameters && arguments.dim != fd.parameters.dim) || (!fd.parameters && arguments.dim)))
+ ((fd.parameters && arguments.length != fd.parameters.length) || (!fd.parameters && arguments.length)))
{
fd.error("C-style variadic functions are not yet implemented in CTFE");
return CTFEExp.cantexp;
@@ -467,8 +467,8 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta
// Place to hold all the arguments to the function while
// we are evaluating them.
- size_t dim = arguments ? arguments.dim : 0;
- assert((fd.parameters ? fd.parameters.dim : 0) == dim);
+ size_t dim = arguments ? arguments.length : 0;
+ assert((fd.parameters ? fd.parameters.length : 0) == dim);
/* Evaluate all the arguments to the function,
* store the results in eargs[]
@@ -827,7 +827,7 @@ public:
if (istate.start == s)
istate.start = null;
- const dim = s.statements ? s.statements.dim : 0;
+ const dim = s.statements ? s.statements.length : 0;
foreach (i; 0 .. dim)
{
Statement sx = (*s.statements)[i];
@@ -850,7 +850,7 @@ public:
if (istate.start == s)
istate.start = null;
- const dim = s.statements ? s.statements.dim : 0;
+ const dim = s.statements ? s.statements.length : 0;
foreach (i; 0 .. dim)
{
Statement sx = (*s.statements)[i];
@@ -1034,7 +1034,7 @@ public:
result = interpret(pue, s.exp, istate, CTFEGoal.LValue);
return;
}
- if (tf.next && tf.next.ty == Tdelegate && istate.fd.closureVars.dim > 0)
+ if (tf.next && tf.next.ty == Tdelegate && istate.fd.closureVars.length > 0)
{
// To support this, we need to copy all the closure vars
// into the delegate literal.
@@ -1521,11 +1521,6 @@ public:
result = e;
}
- static bool isAnErrorException(ClassDeclaration cd)
- {
- return cd == ClassDeclaration.errorException || ClassDeclaration.errorException.isBaseOf(cd, null);
- }
-
static ThrownExceptionExp chainExceptions(ThrownExceptionExp oldest, ThrownExceptionExp newest)
{
debug (LOG)
@@ -1537,7 +1532,7 @@ public:
const next = 4; // index of Throwable.next
assert((*boss.value.elements)[next].type.ty == Tclass); // Throwable.next
ClassReferenceExp collateral = newest.thrown;
- if (isAnErrorException(collateral.originalClass()) && !isAnErrorException(boss.originalClass()))
+ if (collateral.originalClass().isErrorException() && !boss.originalClass().isErrorException())
{
/* Find the index of the Error.bypassException field
*/
@@ -1647,8 +1642,15 @@ public:
if (exceptionOrCant(e))
return;
- assert(e.op == EXP.classReference);
- result = ctfeEmplaceExp!ThrownExceptionExp(loc, e.isClassReferenceExp());
+ if (e.op == EXP.classReference)
+ {
+ result = ctfeEmplaceExp!ThrownExceptionExp(loc, e.isClassReferenceExp());
+ }
+ else
+ {
+ exp.error("to be thrown `%s` must be non-null", exp.toChars());
+ result = ErrorExp.get();
+ }
}
override void visit(ScopeGuardStatement s)
@@ -2296,7 +2298,7 @@ public:
while (s.isAttribDeclaration())
{
auto ad = cast(AttribDeclaration)s;
- assert(ad.decl && ad.decl.dim == 1); // Currently, only one allowed when parsing
+ assert(ad.decl && ad.decl.length == 1); // Currently, only one allowed when parsing
s = (*ad.decl)[0];
}
if (VarDeclaration v = s.isVarDeclaration())
@@ -2505,7 +2507,7 @@ public:
return;
auto expsx = e.elements;
- size_t dim = expsx ? expsx.dim : 0;
+ size_t dim = expsx ? expsx.length : 0;
for (size_t i = 0; i < dim; i++)
{
Expression exp = (*expsx)[i];
@@ -2544,7 +2546,7 @@ public:
{
// todo: all tuple expansions should go in semantic phase.
expandTuples(expsx);
- if (expsx.dim != dim)
+ if (expsx.length != dim)
{
e.error("CTFE internal error: invalid array literal");
result = CTFEExp.cantexp;
@@ -2607,7 +2609,7 @@ public:
expandTuples(keysx);
if (valuesx !is e.values)
expandTuples(valuesx);
- if (keysx.dim != valuesx.dim)
+ if (keysx.length != valuesx.length)
{
e.error("CTFE internal error: invalid AA");
result = CTFEExp.cantexp;
@@ -2616,10 +2618,10 @@ public:
/* Remove duplicate keys
*/
- for (size_t i = 1; i < keysx.dim; i++)
+ for (size_t i = 1; i < keysx.length; i++)
{
auto ekey = (*keysx)[i - 1];
- for (size_t j = i; j < keysx.dim; j++)
+ for (size_t j = i; j < keysx.length; j++)
{
auto ekey2 = (*keysx)[j];
if (!ctfeEqual(e.loc, EXP.equal, ekey, ekey2))
@@ -2665,14 +2667,14 @@ public:
return;
}
- size_t dim = e.elements ? e.elements.dim : 0;
+ size_t dim = e.elements ? e.elements.length : 0;
auto expsx = e.elements;
- if (dim != e.sd.fields.dim)
+ if (dim != e.sd.fields.length)
{
// guaranteed by AggregateDeclaration.fill and TypeStruct.defaultInitLiteral
- const nvthis = e.sd.fields.dim - e.sd.nonHiddenFields();
- assert(e.sd.fields.dim - dim == nvthis);
+ const nvthis = e.sd.fields.length - e.sd.nonHiddenFields();
+ assert(e.sd.fields.length - dim == nvthis);
/* If a nested struct has no initialized hidden pointer,
* set it to null to match the runtime behaviour.
@@ -2688,7 +2690,7 @@ public:
++dim;
}
}
- assert(dim == e.sd.fields.dim);
+ assert(dim == e.sd.fields.length);
foreach (i; 0 .. dim)
{
@@ -2728,7 +2730,7 @@ public:
if (expsx !is e.elements)
{
expandTuples(expsx);
- if (expsx.dim != e.sd.fields.dim)
+ if (expsx.length != e.sd.fields.length)
{
e.error("CTFE internal error: invalid struct literal");
result = CTFEExp.cantexp;
@@ -2757,7 +2759,7 @@ public:
return lenExpr;
size_t len = cast(size_t)lenExpr.toInteger();
Type elemType = (cast(TypeArray)newtype).next;
- if (elemType.ty == Tarray && argnum < arguments.dim - 1)
+ if (elemType.ty == Tarray && argnum < arguments.length - 1)
{
Expression elem = recursivelyCreateArrayLiteral(pue, loc, elemType, istate, arguments, argnum + 1);
if (exceptionOrCantInterpret(elem))
@@ -2771,7 +2773,7 @@ public:
ae.ownedByCtfe = OwnedBy.ctfe;
return ae;
}
- assert(argnum == arguments.dim - 1);
+ assert(argnum == arguments.length - 1);
if (elemType.ty.isSomeChar)
{
const ch = cast(dchar)elemType.defaultInitLiteral(loc).toInteger();
@@ -2818,10 +2820,10 @@ public:
{
StructDeclaration sd = ts.sym;
auto exps = new Expressions();
- exps.reserve(sd.fields.dim);
+ exps.reserve(sd.fields.length);
if (e.arguments)
{
- exps.setDim(e.arguments.dim);
+ exps.setDim(e.arguments.length);
foreach (i, ex; *e.arguments)
{
ex = interpretRegion(ex, istate);
@@ -2850,12 +2852,12 @@ public:
ClassDeclaration cd = tc.sym;
size_t totalFieldCount = 0;
for (ClassDeclaration c = cd; c; c = c.baseClass)
- totalFieldCount += c.fields.dim;
+ totalFieldCount += c.fields.length;
auto elems = new Expressions(totalFieldCount);
size_t fieldsSoFar = totalFieldCount;
for (ClassDeclaration c = cd; c; c = c.baseClass)
{
- fieldsSoFar -= c.fields.dim;
+ fieldsSoFar -= c.fields.length;
foreach (i, v; c.fields)
{
if (v.inuse)
@@ -2927,7 +2929,7 @@ public:
if (e.newtype.toBasetype().isscalar())
{
Expression newval;
- if (e.arguments && e.arguments.dim)
+ if (e.arguments && e.arguments.length)
newval = (*e.arguments)[0];
else
newval = e.newtype.defaultInitLiteral(e.loc);
@@ -3850,7 +3852,7 @@ public:
e.error("CTFE internal error: cannot find field `%s` in `%s`", v.toChars(), ex.toChars());
return CTFEExp.cantexp;
}
- assert(0 <= fieldi && fieldi < sle.elements.dim);
+ assert(0 <= fieldi && fieldi < sle.elements.length);
// If it's a union, set all other members of this union to void
stompOverlappedFields(sle, v);
@@ -3958,7 +3960,7 @@ public:
Expressions* oldelems = oldval.isArrayLiteralExp().elements;
Expressions* newelems = newval.isArrayLiteralExp().elements;
- assert(oldelems.dim == newelems.dim);
+ assert(oldelems.length == newelems.length);
Type elemtype = oldval.type.nextOf();
foreach (i, ref oldelem; *oldelems)
@@ -4049,7 +4051,7 @@ public:
if (auto ale = e1.isArrayLiteralExp())
{
lowerbound = 0;
- upperbound = ale.elements.dim;
+ upperbound = ale.elements.length;
}
else if (auto se = e1.isStringExp())
{
@@ -4287,7 +4289,7 @@ public:
extern (C++) Expression assignTo(ArrayLiteralExp ae)
{
- return assignTo(ae, 0, ae.elements.dim);
+ return assignTo(ae, 0, ae.elements.length);
}
extern (C++) Expression assignTo(ArrayLiteralExp ae, size_t lwr, size_t upr)
@@ -4786,7 +4788,7 @@ public:
if (fd.ident == Id.__ArrayPostblit || fd.ident == Id.__ArrayDtor)
{
- assert(e.arguments.dim == 1);
+ assert(e.arguments.length == 1);
Expression ea = (*e.arguments)[0];
// printf("1 ea = %s %s\n", ea.type.toChars(), ea.toChars());
if (auto se = ea.isSliceExp())
@@ -4822,7 +4824,7 @@ public:
{
// In expressionsem.d `ea.length = eb;` got lowered to `_d_arraysetlengthT(ea, eb);`.
// The following code will rewrite it back to `ea.length = eb` and then interpret that expression.
- assert(e.arguments.dim == 2);
+ assert(e.arguments.length == 2);
Expression ea = (*e.arguments)[0];
Expression eb = (*e.arguments)[1];
@@ -4846,9 +4848,9 @@ public:
// then interpret that expression.
if (fd.ident == Id._d_arrayctor)
- assert(e.arguments.dim == 3);
+ assert(e.arguments.length == 3);
else
- assert(e.arguments.dim == 2);
+ assert(e.arguments.length == 2);
Expression ea = (*e.arguments)[0];
if (ea.isCastExp)
@@ -4877,13 +4879,13 @@ public:
if (fd.ident == Id._d_arrayappendT)
{
- assert(e.arguments.dim == 2);
+ assert(e.arguments.length == 2);
lhs = (*e.arguments)[0];
rhs = (*e.arguments)[1];
}
else
{
- assert(e.arguments.dim == 5);
+ assert(e.arguments.length == 5);
lhs = (*e.arguments)[3];
rhs = (*e.arguments)[4];
}
@@ -5044,7 +5046,7 @@ public:
// `_d_arrayappendcTX(arr, elem), arr[arr.length - 1] = elem, elem;`.
// The following code will rewrite it back to `arr ~= elem`
// and then interpret that expression.
- assert(ce.arguments.dim == 2);
+ assert(ce.arguments.length == 2);
auto arr = (*ce.arguments)[0];
auto elem = e.e2.isConstructExp().e2;
@@ -5999,7 +6001,7 @@ public:
{
ArrayLiteralExp ale = ie.e1.isArrayLiteralExp();
const indx = cast(size_t)ie.e2.toInteger();
- if (indx < ale.elements.dim)
+ if (indx < ale.elements.length)
{
if (Expression xx = (*ale.elements)[indx])
{
@@ -6463,8 +6465,8 @@ public:
(*valuesx)[j - removed] = evalue;
}
}
- valuesx.dim = valuesx.dim - removed;
- keysx.dim = keysx.dim - removed;
+ valuesx.length = valuesx.length - removed;
+ keysx.length = keysx.length - removed;
result = IntegerExp.createBool(removed != 0);
}
@@ -6978,7 +6980,7 @@ private Expression interpret_length(UnionExp* pue, InterState* istate, Expressio
return earg;
dinteger_t len = 0;
if (auto aae = earg.isAssocArrayLiteralExp())
- len = aae.keys.dim;
+ len = aae.keys.length;
else
assert(earg.op == EXP.null_);
emplaceExp!(IntegerExp)(pue, earg.loc, len, Type.tsize_t);
@@ -7049,7 +7051,7 @@ private Expression interpret_dup(UnionExp* pue, InterState* istate, Expression e
if (earg.op != EXP.assocArrayLiteral && earg.type.toBasetype().ty != Taarray)
return null;
auto aae = copyLiteral(earg).copy().isAssocArrayLiteralExp();
- for (size_t i = 0; i < aae.keys.dim; i++)
+ for (size_t i = 0; i < aae.keys.length; i++)
{
if (Expression e = evaluatePostblit(istate, (*aae.keys)[i]))
return e;
@@ -7085,7 +7087,7 @@ private Expression interpret_aaApply(UnionExp* pue, InterState* istate, Expressi
assert(fd && fd.fbody);
assert(fd.parameters);
- size_t numParams = fd.parameters.dim;
+ size_t numParams = fd.parameters.length;
assert(numParams == 1 || numParams == 2);
Parameter fparam = fd.type.isTypeFunction().parameterList[numParams - 1];
@@ -7094,11 +7096,11 @@ private Expression interpret_aaApply(UnionExp* pue, InterState* istate, Expressi
Expressions args = Expressions(numParams);
AssocArrayLiteralExp ae = aa.isAssocArrayLiteralExp();
- if (!ae.keys || ae.keys.dim == 0)
+ if (!ae.keys || ae.keys.length == 0)
return ctfeEmplaceExp!IntegerExp(deleg.loc, 0, Type.tsize_t);
Expression eresult;
- for (size_t i = 0; i < ae.keys.dim; ++i)
+ for (size_t i = 0; i < ae.keys.length; ++i)
{
Expression ekey = (*ae.keys)[i];
Expression evalue = (*ae.values)[i];
@@ -7146,7 +7148,7 @@ private Expression foreachApplyUtf(UnionExp* pue, InterState* istate, Expression
assert(fd && fd.fbody);
assert(fd.parameters);
- size_t numParams = fd.parameters.dim;
+ size_t numParams = fd.parameters.length;
assert(numParams == 1 || numParams == 2);
Type charType = (*fd.parameters)[numParams - 1].type;
Type indexType = numParams == 2 ? (*fd.parameters)[0].type : Type.tsize_t;
@@ -7389,7 +7391,7 @@ private Expression foreachApplyUtf(UnionExp* pue, InterState* istate, Expression
private Expression evaluateIfBuiltin(UnionExp* pue, InterState* istate, const ref Loc loc, FuncDeclaration fd, Expressions* arguments, Expression pthis)
{
Expression e = null;
- size_t nargs = arguments ? arguments.dim : 0;
+ size_t nargs = arguments ? arguments.length : 0;
if (!pthis)
{
if (isBuiltin(fd) != BUILTIN.unimp)
@@ -7453,7 +7455,7 @@ private Expression evaluateIfBuiltin(UnionExp* pue, InterState* istate, const re
// At present, the constructors just copy their arguments into the struct.
// But we might need some magic if stack tracing gets added to druntime.
StructLiteralExp se = pthis.isClassReferenceExp().value;
- assert(arguments.dim <= se.elements.dim);
+ assert(arguments.length <= se.elements.length);
foreach (i, arg; *arguments)
{
auto elem = interpret(arg, istate);
@@ -7615,7 +7617,7 @@ private void removeHookTraceImpl(ref CallExp ce, ref FuncDeclaration fd)
// Remove the first three trace parameters
auto arguments = new Expressions();
- arguments.reserve(ce.arguments.dim - 3);
+ arguments.reserve(ce.arguments.length - 3);
arguments.pushSlice((*ce.arguments)[3 .. $]);
ce = ctfeEmplaceExp!CallExp(ce.loc, ctfeEmplaceExp!VarExp(ce.loc, fd, false), arguments);
diff --git a/gcc/d/dmd/dmangle.d b/gcc/d/dmd/dmangle.d
index be0cbcc..6ecaa52 100644
--- a/gcc/d/dmd/dmangle.d
+++ b/gcc/d/dmd/dmangle.d
@@ -721,8 +721,8 @@ public:
mangleIdentifier(tempdecl.ident, tempdecl);
auto args = ti.tiargs;
- size_t nparams = tempdecl.parameters.dim - (tempdecl.isVariadic() ? 1 : 0);
- for (size_t i = 0; i < args.dim; i++)
+ size_t nparams = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0);
+ for (size_t i = 0; i < args.length; i++)
{
auto o = (*args)[i];
Type ta = isType(o);
@@ -814,7 +814,7 @@ public:
}
else if (va)
{
- assert(i + 1 == args.dim); // must be last one
+ assert(i + 1 == args.length); // must be last one
args = &va.objects;
i = -cast(size_t)1;
}
@@ -960,7 +960,7 @@ public:
override void visit(ArrayLiteralExp e)
{
- const dim = e.elements ? e.elements.dim : 0;
+ const dim = e.elements ? e.elements.length : 0;
buf.writeByte('A');
buf.print(dim);
foreach (i; 0 .. dim)
@@ -971,7 +971,7 @@ public:
override void visit(AssocArrayLiteralExp e)
{
- const dim = e.keys.dim;
+ const dim = e.keys.length;
buf.writeByte('A');
buf.print(dim);
foreach (i; 0 .. dim)
@@ -983,7 +983,7 @@ public:
override void visit(StructLiteralExp e)
{
- const dim = e.elements ? e.elements.dim : 0;
+ const dim = e.elements ? e.elements.length : 0;
buf.writeByte('S');
buf.print(dim);
foreach (i; 0 .. dim)
diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d
index b2908ce..6160805 100644
--- a/gcc/d/dmd/dmodule.d
+++ b/gcc/d/dmd/dmodule.d
@@ -62,7 +62,7 @@ void semantic3OnDependencies(Module m)
m.semantic3(null);
- foreach (i; 1 .. m.aimports.dim)
+ foreach (i; 1 .. m.aimports.length)
semantic3OnDependencies(m.aimports[i]);
}
@@ -132,7 +132,7 @@ private const(char)[] getFilename(Identifier[] packages, Identifier ident) nothr
{
const p = pid.toString();
buf.writestring(p);
- if (modAliases.dim)
+ if (modAliases.length)
checkModFileAlias(p);
version (Windows)
enum FileSeparator = '\\';
@@ -141,7 +141,7 @@ private const(char)[] getFilename(Identifier[] packages, Identifier ident) nothr
buf.writeByte(FileSeparator);
}
buf.writestring(filename);
- if (modAliases.dim)
+ if (modAliases.length)
checkModFileAlias(filename);
buf.writeByte(0);
filename = buf.extractSlice()[0 .. $ - 1];
@@ -499,7 +499,7 @@ extern (C++) final class Module : Package
extern (D) static const(char)[] find(const(char)[] filename)
{
- return FileManager.lookForSourceFile(filename, global.path ? (*global.path)[] : null);
+ return global.fileManager.lookForSourceFile(filename, global.path ? (*global.path)[] : null);
}
extern (C++) static Module load(const ref Loc loc, Identifiers* packages, Identifier ident)
@@ -942,7 +942,7 @@ extern (C++) final class Module : Package
// classinst == classinst -> .object.opEquals(classinst, classinst)
// would fail inside object.d.
if (filetype != FileType.c &&
- (members.dim == 0 ||
+ (members.length == 0 ||
(*members)[0].ident != Id.object ||
(*members)[0].isImport() is null))
{
@@ -953,7 +953,7 @@ extern (C++) final class Module : Package
{
// Add all symbols into module's symbol table
symtab = new DsymbolTable();
- for (size_t i = 0; i < members.dim; i++)
+ for (size_t i = 0; i < members.length; i++)
{
Dsymbol s = (*members)[i];
s.addMember(sc, sc.scopesym);
@@ -966,12 +966,12 @@ extern (C++) final class Module : Package
* before any semantic() on any of them.
*/
setScope(sc); // remember module scope for semantic
- for (size_t i = 0; i < members.dim; i++)
+ for (size_t i = 0; i < members.length; i++)
{
Dsymbol s = (*members)[i];
s.setScope(sc);
}
- for (size_t i = 0; i < members.dim; i++)
+ for (size_t i = 0; i < members.length; i++)
{
Dsymbol s = (*members)[i];
s.importAll(sc);
@@ -1115,13 +1115,13 @@ extern (C++) final class Module : Package
__gshared int nested;
if (nested)
return;
- //if (deferred.dim) printf("+Module::runDeferredSemantic(), len = %ld\n", deferred.dim);
+ //if (deferred.length) printf("+Module::runDeferredSemantic(), len = %ld\n", deferred.length);
nested++;
size_t len;
do
{
- len = deferred.dim;
+ len = deferred.length;
if (!len)
break;
@@ -1146,13 +1146,13 @@ extern (C++) final class Module : Package
s.dsymbolSemantic(null);
//printf("deferred: %s, parent = %s\n", s.toChars(), s.parent.toChars());
}
- //printf("\tdeferred.dim = %ld, len = %ld\n", deferred.dim, len);
+ //printf("\tdeferred.length = %ld, len = %ld\n", deferred.length, len);
if (todoalloc)
free(todoalloc);
}
- while (deferred.dim != len); // while making progress
+ while (deferred.length != len); // while making progress
nested--;
- //printf("-Module::runDeferredSemantic(), len = %ld\n", deferred.dim);
+ //printf("-Module::runDeferredSemantic(), len = %ld\n", deferred.length);
}
static void runDeferredSemantic2()
@@ -1160,7 +1160,7 @@ extern (C++) final class Module : Package
Module.runDeferredSemantic();
Dsymbols* a = &Module.deferred2;
- for (size_t i = 0; i < a.dim; i++)
+ for (size_t i = 0; i < a.length; i++)
{
Dsymbol s = (*a)[i];
//printf("[%d] %s semantic2a\n", i, s.toPrettyChars());
@@ -1177,7 +1177,7 @@ extern (C++) final class Module : Package
Module.runDeferredSemantic2();
Dsymbols* a = &Module.deferred3;
- for (size_t i = 0; i < a.dim; i++)
+ for (size_t i = 0; i < a.length; i++)
{
Dsymbol s = (*a)[i];
//printf("[%d] %s semantic3a\n", i, s.toPrettyChars());
diff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d
index e1d5897..c04409c4 100644
--- a/gcc/d/dmd/doc.d
+++ b/gcc/d/dmd/doc.d
@@ -106,7 +106,7 @@ private class Section
void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, OutBuffer* buf)
{
- assert(a.dim);
+ assert(a.length);
if (name.length)
{
static immutable table =
@@ -161,7 +161,7 @@ private final class ParamSection : Section
{
override void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, OutBuffer* buf)
{
- assert(a.dim);
+ assert(a.length);
Dsymbol s = (*a)[0]; // test
const(char)* p = body_.ptr;
size_t len = body_.length;
@@ -295,10 +295,10 @@ private final class ParamSection : Section
goto L1;
// write out last one
buf.writestring(")");
- TypeFunction tf = a.dim == 1 ? isTypeFunction(s) : null;
+ TypeFunction tf = a.length == 1 ? isTypeFunction(s) : null;
if (tf)
{
- size_t pcount = (tf.parameterList.parameters ? tf.parameterList.parameters.dim : 0) +
+ size_t pcount = (tf.parameterList.parameters ? tf.parameterList.parameters.length : 0) +
cast(int)(tf.parameterList.varargs == VarArg.variadic);
if (pcount != paramcount)
{
@@ -386,7 +386,7 @@ extern(C++) void gendocfile(Module m)
if (p)
global.params.ddoc.files.shift(p);
// Override with the ddoc macro files from the command line
- for (size_t i = 0; i < global.params.ddoc.files.dim; i++)
+ for (size_t i = 0; i < global.params.ddoc.files.length; i++)
{
auto buffer = readFile(m.loc, global.params.ddoc.files[i]);
// BUG: convert file contents to UTF-8 before use
@@ -757,9 +757,9 @@ private void emitAnchor(ref OutBuffer buf, Dsymbol s, Scope* sc, bool forHeader
if (auto imp = s.isImport())
{
// For example: `public import core.stdc.string : memcpy, memcmp;`
- if (imp.aliases.dim > 0)
+ if (imp.aliases.length > 0)
{
- for(int i = 0; i < imp.aliases.dim; i++)
+ for(int i = 0; i < imp.aliases.length; i++)
{
// Need to distinguish between
// `public import core.stdc.string : memcpy, memcmp;` and
@@ -866,7 +866,7 @@ private void expandTemplateMixinComments(TemplateMixin tm, ref OutBuffer buf, Sc
TemplateDeclaration td = (tm && tm.tempdecl) ? tm.tempdecl.isTemplateDeclaration() : null;
if (td && td.members)
{
- for (size_t i = 0; i < td.members.dim; i++)
+ for (size_t i = 0; i < td.members.length; i++)
{
Dsymbol sm = (*td.members)[i];
TemplateMixin tmc = sm.isTemplateMixin();
@@ -898,7 +898,7 @@ private void emitMemberComments(ScopeDsymbol sds, ref OutBuffer buf, Scope* sc)
buf.writestring(m);
size_t offset2 = buf.length; // to see if we write anything
sc = sc.push(sds);
- for (size_t i = 0; i < sds.members.dim; i++)
+ for (size_t i = 0; i < sds.members.length; i++)
{
Dsymbol s = (*sds.members)[i];
//printf("\ts = '%s'\n", s.toChars());
@@ -998,7 +998,7 @@ private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
// Put previous doc comment if exists
if (DocComment* dc = sc.lastdc)
{
- assert(dc.a.dim > 0, "Expects at least one declaration for a" ~
+ assert(dc.a.length > 0, "Expects at least one declaration for a" ~
"documentation comment");
auto symbol = dc.a[0];
@@ -1010,7 +1010,7 @@ private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
// Put the declaration signatures as the document 'title'
buf.writestring(ddoc_decl_s);
- for (size_t i = 0; i < dc.a.dim; i++)
+ for (size_t i = 0; i < dc.a.length; i++)
{
Dsymbol sx = dc.a[i];
// the added linebreaks in here make looking at multiple
@@ -1138,7 +1138,7 @@ private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
return;
if (ed.isAnonymous() && ed.members)
{
- for (size_t i = 0; i < ed.members.dim; i++)
+ for (size_t i = 0; i < ed.members.length; i++)
{
Dsymbol s = (*ed.members)[i];
emitComment(s, *buf, sc);
@@ -1176,7 +1176,7 @@ private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
Dsymbols* d = ad.include(null);
if (d)
{
- for (size_t i = 0; i < d.dim; i++)
+ for (size_t i = 0; i < d.length; i++)
{
Dsymbol s = (*d)[i];
//printf("AttribDeclaration::emitComment %s\n", s.toChars());
@@ -1210,7 +1210,7 @@ private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
* a template, then include(null) will fail.
*/
Dsymbols* d = cd.decl ? cd.decl : cd.elsedecl;
- for (size_t i = 0; i < d.dim; i++)
+ for (size_t i = 0; i < d.length; i++)
{
Dsymbol s = (*d)[i];
emitComment(s, *buf, sc);
@@ -1324,9 +1324,9 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
if (d.isVarDeclaration() && td)
{
buf.writeByte('(');
- if (td.origParameters && td.origParameters.dim)
+ if (td.origParameters && td.origParameters.length)
{
- for (size_t i = 0; i < td.origParameters.dim; i++)
+ for (size_t i = 0; i < td.origParameters.length; i++)
{
if (i)
buf.writestring(", ");
@@ -1484,7 +1484,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
buf.printf("%s %s", cd.kind(), cd.toChars());
}
int any = 0;
- for (size_t i = 0; i < cd.baseclasses.dim; i++)
+ for (size_t i = 0; i < cd.baseclasses.length; i++)
{
BaseClass* bc = (*cd.baseclasses)[i];
if (bc.sym && bc.sym.ident == Id.Object)
@@ -1557,7 +1557,7 @@ struct DocComment
if (!comment)
return dc;
dc.parseSections(comment);
- for (size_t i = 0; i < dc.sections.dim; i++)
+ for (size_t i = 0; i < dc.sections.length; i++)
{
Section sec = dc.sections[i];
if (iequals("copyright", sec.name))
@@ -1873,7 +1873,7 @@ struct DocComment
void writeSections(Scope* sc, Dsymbols* a, OutBuffer* buf)
{
- assert(a.dim);
+ assert(a.length);
//printf("DocComment::writeSections()\n");
Loc loc = (*a)[0].loc;
if (Module m = (*a)[0].isModule())
@@ -1884,7 +1884,7 @@ struct DocComment
size_t offset1 = buf.length;
buf.writestring("$(DDOC_SECTIONS ");
size_t offset2 = buf.length;
- for (size_t i = 0; i < sections.dim; i++)
+ for (size_t i = 0; i < sections.length; i++)
{
Section sec = sections[i];
if (sec.nooutput)
@@ -1902,7 +1902,7 @@ struct DocComment
else
sec.write(loc, &this, sc, a, buf);
}
- for (size_t i = 0; i < a.dim; i++)
+ for (size_t i = 0; i < a.length; i++)
{
Dsymbol s = (*a)[i];
if (Dsymbol td = getEponymousParent(s))
@@ -2719,7 +2719,7 @@ private Parameter isEponymousFunctionParameter(Dsymbols *a, const(char)[] p) @sa
*/
private TemplateParameter isTemplateParameter(Dsymbols* a, const(char)* p, size_t len)
{
- for (size_t i = 0; i < a.dim; i++)
+ for (size_t i = 0; i < a.length; i++)
{
TemplateDeclaration td = (*a)[i].isTemplateDeclaration();
// Check for the parent, if the current symbol is not a template declaration.
@@ -5004,10 +5004,10 @@ private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, s
private void highlightCode(Scope* sc, Dsymbol s, ref OutBuffer buf, size_t offset)
{
auto imp = s.isImport();
- if (imp && imp.aliases.dim > 0)
+ if (imp && imp.aliases.length > 0)
{
// For example: `public import core.stdc.string : memcpy, memcmp;`
- for(int i = 0; i < imp.aliases.dim; i++)
+ for(int i = 0; i < imp.aliases.length; i++)
{
// Need to distinguish between
// `public import core.stdc.string : memcpy, memcmp;` and
@@ -5089,7 +5089,7 @@ private void highlightCode(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t off
size_t previ = i;
// hunt for template declarations:
- foreach (symi; 0 .. a.dim)
+ foreach (symi; 0 .. a.length)
{
FuncDeclaration fd = (*a)[symi].isFuncDeclaration();
@@ -5102,14 +5102,14 @@ private void highlightCode(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t off
// build the template parameters
Array!(size_t) paramLens;
- paramLens.reserve(td.parameters.dim);
+ paramLens.reserve(td.parameters.length);
OutBuffer parametersBuf;
HdrGenState hgs;
parametersBuf.writeByte('(');
- foreach (parami; 0 .. td.parameters.dim)
+ foreach (parami; 0 .. td.parameters.length)
{
TemplateParameter tp = (*td.parameters)[parami];
diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d
index c816759..362e7f2 100644
--- a/gcc/d/dmd/dscope.d
+++ b/gcc/d/dmd/dscope.d
@@ -71,13 +71,14 @@ private enum PersistentFlags =
SCOPE.noaccesscheck | SCOPE.ignoresymbolvisibility |
SCOPE.Cfile;
-struct Scope
+extern (C++) struct Scope
{
Scope* enclosing; /// enclosing Scope
Module _module; /// Root module
ScopeDsymbol scopesym; /// current symbol
FuncDeclaration func; /// function we are in
+ VarDeclaration varDecl; /// variable we are in during semantic2
Dsymbol parent; /// parent to use
LabelStatement slabel; /// enclosing labelled statement
SwitchStatement sw; /// enclosing switch statement
@@ -177,7 +178,7 @@ struct Scope
return sc;
}
- extern (C++) Scope* copy()
+ extern (D) Scope* copy()
{
Scope* sc = Scope.alloc();
*sc = this;
@@ -188,7 +189,7 @@ struct Scope
return sc;
}
- extern (C++) Scope* push()
+ extern (D) Scope* push()
{
Scope* s = copy();
//printf("Scope::push(this = %p) new = %p\n", this, s);
@@ -214,7 +215,7 @@ struct Scope
return s;
}
- extern (C++) Scope* push(ScopeDsymbol ss)
+ extern (D) Scope* push(ScopeDsymbol ss)
{
//printf("Scope::push(%s)\n", ss.toChars());
Scope* s = push();
@@ -222,7 +223,7 @@ struct Scope
return s;
}
- extern (C++) Scope* pop()
+ extern (D) Scope* pop()
{
//printf("Scope::pop() %p nofree = %d\n", this, nofree);
if (enclosing)
@@ -252,7 +253,7 @@ struct Scope
pop();
}
- extern (C++) Scope* startCTFE()
+ extern (D) Scope* startCTFE()
{
Scope* sc = this.push();
sc.flags = this.flags | SCOPE.ctfe;
@@ -279,7 +280,7 @@ struct Scope
return sc;
}
- extern (C++) Scope* endCTFE()
+ extern (D) Scope* endCTFE()
{
assert(flags & SCOPE.ctfe);
return pop();
@@ -663,7 +664,7 @@ struct Scope
/********************************************
* Search enclosing scopes for ScopeDsymbol.
*/
- ScopeDsymbol getScopesym()
+ extern (D) ScopeDsymbol getScopesym()
{
for (Scope* sc = &this; sc; sc = sc.enclosing)
{
@@ -676,7 +677,7 @@ struct Scope
/********************************************
* Search enclosing scopes for ClassDeclaration.
*/
- extern (C++) ClassDeclaration getClassScope()
+ extern (D) ClassDeclaration getClassScope()
{
for (Scope* sc = &this; sc; sc = sc.enclosing)
{
@@ -691,7 +692,7 @@ struct Scope
/********************************************
* Search enclosing scopes for ClassDeclaration or StructDeclaration.
*/
- extern (C++) AggregateDeclaration getStructClassScope()
+ extern (D) AggregateDeclaration getStructClassScope()
{
for (Scope* sc = &this; sc; sc = sc.enclosing)
{
@@ -713,7 +714,7 @@ struct Scope
*
* Returns: the function or null
*/
- inout(FuncDeclaration) getEnclosingFunction() inout
+ extern (D) inout(FuncDeclaration) getEnclosingFunction() inout
{
if (!this.func)
return null;
@@ -752,7 +753,7 @@ struct Scope
}
/******************************
*/
- structalign_t alignment()
+ extern (D) structalign_t alignment()
{
if (aligndecl)
{
@@ -772,7 +773,7 @@ struct Scope
*
* Returns: `true` if this or any parent scope is deprecated, `false` otherwise`
*/
- extern(C++) bool isDeprecated()
+ extern (D) bool isDeprecated()
{
for (const(Dsymbol)* sp = &(this.parent); *sp; sp = &(sp.parent))
{
@@ -802,7 +803,7 @@ struct Scope
*
* Returns: `true` if this `Scope` is known to be from one of these speculative contexts
*/
- extern(C++) bool isFromSpeculativeSemanticContext() scope
+ extern (D) bool isFromSpeculativeSemanticContext() scope
{
return this.intypeof || this.flags & SCOPE.compile;
}
diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d
index 1c2f226..2115fda 100644
--- a/gcc/d/dmd/dstruct.d
+++ b/gcc/d/dmd/dstruct.d
@@ -292,14 +292,14 @@ extern (C++) class StructDeclaration : AggregateDeclaration
}
sizeok = Sizeok.inProcess;
- //printf("+StructDeclaration::finalizeSize() %s, fields.dim = %d, sizeok = %d\n", toChars(), fields.dim, sizeok);
+ //printf("+StructDeclaration::finalizeSize() %s, fields.length = %d, sizeok = %d\n", toChars(), fields.length, sizeok);
fields.setDim(0); // workaround
// Set the offsets of the fields and determine the size of the struct
FieldState fieldState;
bool isunion = isUnionDeclaration() !is null;
- for (size_t i = 0; i < members.dim; i++)
+ for (size_t i = 0; i < members.length; i++)
{
Dsymbol s = (*members)[i];
s.setFieldOffset(this, fieldState, isunion);
@@ -353,7 +353,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration
sizeok = Sizeok.done;
- //printf("-StructDeclaration::finalizeSize() %s, fields.dim = %d, structsize = %d\n", toChars(), fields.dim, structsize);
+ //printf("-StructDeclaration::finalizeSize() %s, fields.length = %d, structsize = %d\n", toChars(), fields.length, structsize);
if (errors)
return;
@@ -454,7 +454,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration
}
// Recursively check all fields are POD.
- for (size_t i = 0; i < fields.dim; i++)
+ for (size_t i = 0; i < fields.length; i++)
{
VarDeclaration v = fields[i];
if (v.storage_class & STC.ref_)
@@ -491,7 +491,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration
final uint numArgTypes() const
{
- return argTypes && argTypes.arguments ? cast(uint) argTypes.arguments.dim : 0;
+ return argTypes && argTypes.arguments ? cast(uint) argTypes.arguments.length : 0;
}
final Type argType(uint index)
@@ -570,7 +570,7 @@ private bool _isZeroInit(Expression exp)
case EXP.structLiteral:
{
auto sle = cast(StructLiteralExp) exp;
- foreach (i; 0 .. sle.sd.fields.dim)
+ foreach (i; 0 .. sle.sd.fields.length)
{
auto field = sle.sd.fields[i];
if (field.type.size(field.loc))
@@ -588,7 +588,7 @@ private bool _isZeroInit(Expression exp)
{
auto ale = cast(ArrayLiteralExp)exp;
- const dim = ale.elements ? ale.elements.dim : 0;
+ const dim = ale.elements ? ale.elements.length : 0;
if (ale.type.toBasetype().ty == Tarray) // if initializing a dynamic array
return dim == 0;
diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d
index 2f10e83..2cf5500 100644
--- a/gcc/d/dmd/dsymbol.d
+++ b/gcc/d/dmd/dsymbol.d
@@ -73,7 +73,7 @@ int foreachDsymbol(Dsymbols* symbols, scope int delegate(Dsymbol) dg)
{
/* Do not use foreach, as the size of the array may expand during iteration
*/
- for (size_t i = 0; i < symbols.dim; ++i)
+ for (size_t i = 0; i < symbols.length; ++i)
{
Dsymbol s = (*symbols)[i];
const result = dg(s);
@@ -99,7 +99,7 @@ void foreachDsymbol(Dsymbols* symbols, scope void delegate(Dsymbol) dg)
{
/* Do not use foreach, as the size of the array may expand during iteration
*/
- for (size_t i = 0; i < symbols.dim; ++i)
+ for (size_t i = 0; i < symbols.length; ++i)
{
Dsymbol s = (*symbols)[i];
dg(s);
@@ -739,7 +739,7 @@ extern (C++) class Dsymbol : ASTNode
if (a)
{
b = a.copy();
- for (size_t i = 0; i < b.dim; i++)
+ for (size_t i = 0; i < b.length; i++)
{
(*b)[i] = (*b)[i].syntaxCopy(null);
}
@@ -1164,7 +1164,7 @@ extern (C++) class Dsymbol : ASTNode
*/
extern (D) static bool oneMembers(Dsymbols* members, Dsymbol* ps, Identifier ident)
{
- //printf("Dsymbol::oneMembers() %d\n", members ? members.dim : 0);
+ //printf("Dsymbol::oneMembers() %d\n", members ? members.length : 0);
Dsymbol s = null;
if (!members)
{
@@ -1172,7 +1172,7 @@ extern (C++) class Dsymbol : ASTNode
return true;
}
- for (size_t i = 0; i < members.dim; i++)
+ for (size_t i = 0; i < members.length; i++)
{
Dsymbol sx = (*members)[i];
bool x = sx.oneMember(ps, ident);
@@ -1489,7 +1489,7 @@ public:
Dsymbol s = null;
OverloadSet a = null;
// Look in imported modules
- for (size_t i = 0; i < importedScopes.dim; i++)
+ for (size_t i = 0; i < importedScopes.length; i++)
{
// If private import, don't search it
if ((flags & IgnorePrivateImports) && visibilities[i] == Visibility.Kind.private_)
@@ -1628,14 +1628,14 @@ public:
if (OverloadSet os2 = s.isOverloadSet())
{
// Merge the cross-module overload set 'os2' into 'os'
- if (os.a.dim == 0)
+ if (os.a.length == 0)
{
- os.a.setDim(os2.a.dim);
- memcpy(os.a.tdata(), os2.a.tdata(), (os.a[0]).sizeof * os2.a.dim);
+ os.a.setDim(os2.a.length);
+ memcpy(os.a.tdata(), os2.a.tdata(), (os.a[0]).sizeof * os2.a.length);
}
else
{
- for (size_t i = 0; i < os2.a.dim; i++)
+ for (size_t i = 0; i < os2.a.length; i++)
{
os = mergeOverloadSet(ident, os, os2.a[i]);
}
@@ -1646,7 +1646,7 @@ public:
assert(s.isOverloadable());
/* Don't add to os[] if s is alias of previous sym
*/
- for (size_t j = 0; j < os.a.dim; j++)
+ for (size_t j = 0; j < os.a.length; j++)
{
Dsymbol s2 = os.a[j];
if (s.toAlias() == s2.toAlias())
@@ -1674,7 +1674,7 @@ public:
importedScopes = new Dsymbols();
else
{
- for (size_t i = 0; i < importedScopes.dim; i++)
+ for (size_t i = 0; i < importedScopes.length; i++)
{
Dsymbol ss = (*importedScopes)[i];
if (ss == s) // if already imported
@@ -1686,8 +1686,8 @@ public:
}
}
importedScopes.push(s);
- visibilities = cast(Visibility.Kind*)mem.xrealloc(visibilities, importedScopes.dim * (visibilities[0]).sizeof);
- visibilities[importedScopes.dim - 1] = visibility.kind;
+ visibilities = cast(Visibility.Kind*)mem.xrealloc(visibilities, importedScopes.length * (visibilities[0]).sizeof);
+ visibilities[importedScopes.length - 1] = visibility.kind;
}
}
@@ -1714,7 +1714,7 @@ public:
if (!importedScopes)
return null;
- return (() @trusted => visibilities[0 .. importedScopes.dim])();
+ return (() @trusted => visibilities[0 .. importedScopes.length])();
}
extern (D) final void addAccessiblePackage(Package p, Visibility visibility) nothrow
@@ -1755,9 +1755,9 @@ public:
}
if (loc.isValid())
{
- .error(loc, "%s `%s` at %s conflicts with %s `%s` at %s",
- s1.kind(), s1.toPrettyChars(), s1.locToChars(),
- s2.kind(), s2.toPrettyChars(), s2.locToChars());
+ .error(loc, "`%s` matches conflicting symbols:", s1.ident.toChars());
+ errorSupplemental(s1.loc, "%s `%s`", s1.kind(), s1.toPrettyChars());
+ errorSupplemental(s2.loc, "%s `%s`", s2.kind(), s2.toPrettyChars());
static if (0)
{
@@ -1854,7 +1854,7 @@ public:
{
if (members)
{
- for (size_t i = 0; i < members.dim; i++)
+ for (size_t i = 0; i < members.length; i++)
{
Dsymbol member = (*members)[i];
if (member.hasStaticCtorOrDtor())
@@ -1883,7 +1883,7 @@ public:
return 0;
size_t n = pn ? *pn : 0; // take over index
int result = 0;
- foreach (size_t i; 0 .. members.dim)
+ foreach (size_t i; 0 .. members.length)
{
Dsymbol s = (*members)[i];
if (AttribDeclaration a = s.isAttribDeclaration())
@@ -2020,7 +2020,7 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol
/* $ gives the number of type entries in the type tuple
*/
auto v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null);
- Expression e = new IntegerExp(Loc.initial, tt.arguments.dim, Type.tsize_t);
+ Expression e = new IntegerExp(Loc.initial, tt.arguments.length, Type.tsize_t);
v._init = new ExpInitializer(Loc.initial, e);
v.storage_class |= STC.temp | STC.static_ | STC.const_;
v.dsymbolSemantic(sc);
@@ -2035,7 +2035,7 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol
/* $ gives the number of elements in the tuple
*/
auto v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null);
- Expression e = new IntegerExp(Loc.initial, td.objects.dim, Type.tsize_t);
+ Expression e = new IntegerExp(Loc.initial, td.objects.length, Type.tsize_t);
v._init = new ExpInitializer(Loc.initial, e);
v.storage_class |= STC.temp | STC.static_ | STC.const_;
v.dsymbolSemantic(sc);
@@ -2098,7 +2098,7 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol
/* It is for an expression tuple, so the
* length will be a const.
*/
- Expression e = new IntegerExp(Loc.initial, tupexp.exps.dim, Type.tsize_t);
+ Expression e = new IntegerExp(Loc.initial, tupexp.exps.length, Type.tsize_t);
v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, new ExpInitializer(Loc.initial, e));
v.storage_class |= STC.temp | STC.static_ | STC.const_;
}
@@ -2142,7 +2142,7 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol
* Note that it's impossible to have both template & function opDollar,
* because both take no arguments.
*/
- if (exp.op == EXP.array && (cast(ArrayExp)exp).arguments.dim != 1)
+ if (exp.op == EXP.array && (cast(ArrayExp)exp).arguments.length != 1)
{
exp.error("`%s` only defines opDollar for one dimension", ad.toChars());
return null;
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index b877828..b842dc8 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -559,19 +559,19 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
auto iexps = new Expressions();
iexps.push(ie);
auto exps = new Expressions();
- for (size_t pos = 0; pos < iexps.dim; pos++)
+ for (size_t pos = 0; pos < iexps.length; pos++)
{
Lexpand1:
Expression e = (*iexps)[pos];
Parameter arg = Parameter.getNth(tt.arguments, pos);
arg.type = arg.type.typeSemantic(dsym.loc, sc);
- //printf("[%d] iexps.dim = %d, ", pos, iexps.dim);
+ //printf("[%d] iexps.length = %d, ", pos, iexps.length);
//printf("e = (%s %s, %s), ", Token.tochars[e.op], e.toChars(), e.type.toChars());
//printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
if (e != ie)
{
- if (iexps.dim > nelems)
+ if (iexps.length > nelems)
goto Lnomatch;
if (e.type.implicitConvTo(arg.type))
continue;
@@ -579,7 +579,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (auto te = e.isTupleExp())
{
- if (iexps.dim - 1 + te.exps.dim > nelems)
+ if (iexps.length - 1 + te.exps.length > nelems)
goto Lnomatch;
iexps.remove(pos);
@@ -598,17 +598,17 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
(*exps)[0] = ve;
expandAliasThisTuples(exps, 0);
- for (size_t u = 0; u < exps.dim; u++)
+ for (size_t u = 0; u < exps.length; u++)
{
Lexpand2:
Expression ee = (*exps)[u];
arg = Parameter.getNth(tt.arguments, pos + u);
arg.type = arg.type.typeSemantic(dsym.loc, sc);
- //printf("[%d+%d] exps.dim = %d, ", pos, u, exps.dim);
+ //printf("[%d+%d] exps.length = %d, ", pos, u, exps.length);
//printf("ee = (%s %s, %s), ", Token.tochars[ee.op], ee.toChars(), ee.type.toChars());
//printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
- size_t iexps_dim = iexps.dim - 1 + exps.dim;
+ size_t iexps_dim = iexps.length - 1 + exps.length;
if (iexps_dim > nelems)
goto Lnomatch;
if (ee.type.implicitConvTo(arg.type))
@@ -630,7 +630,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
}
}
}
- if (iexps.dim < nelems)
+ if (iexps.length < nelems)
goto Lnomatch;
ie = new TupleExp(dsym._init.loc, iexps);
@@ -640,7 +640,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (ie && ie.op == EXP.tuple)
{
auto te = ie.isTupleExp();
- size_t tedim = te.exps.dim;
+ size_t tedim = te.exps.length;
if (tedim != nelems)
{
error(dsym.loc, "tuple of %d elements cannot be assigned to tuple of %d elements", cast(int)tedim, cast(int)nelems);
@@ -1065,7 +1065,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
else if (auto ale = ex.isArrayLiteralExp())
{
// or an array literal assigned to a `scope` variable
- if (!dsym.type.nextOf().needsDestruction())
+ if (global.params.useDIP1000 == FeatureState.enabled
+ && !dsym.type.nextOf().needsDestruction())
ale.onstack = true;
}
}
@@ -1333,7 +1334,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (sc.explicitVisibility)
imp.visibility = sc.visibility;
- if (!imp.aliasId && !imp.names.dim) // neither a selective nor a renamed import
+ if (!imp.aliasId && !imp.names.length) // neither a selective nor a renamed import
{
ScopeDsymbol scopesym = sc.getScopesym();
@@ -1359,7 +1360,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
sc = sc.push(imp.mod);
sc.visibility = imp.visibility;
- for (size_t i = 0; i < imp.aliasdecls.dim; i++)
+ for (size_t i = 0; i < imp.aliasdecls.length; i++)
{
AliasDeclaration ad = imp.aliasdecls[i];
//printf("\tImport %s alias %s = %s, scope = %p\n", toPrettyChars(), aliases[i].toChars(), names[i].toChars(), ad._scope);
@@ -1471,7 +1472,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
{
Scope* sc2 = ad.newScope(sc);
bool errors;
- for (size_t i = 0; i < d.dim; i++)
+ for (size_t i = 0; i < d.length; i++)
{
Dsymbol s = (*d)[i];
s.dsymbolSemantic(sc2);
@@ -1509,7 +1510,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
sc.stc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.gshared);
sc.inunion = scd.isunion ? scd : null;
sc.flags = 0;
- for (size_t i = 0; i < scd.decl.dim; i++)
+ for (size_t i = 0; i < scd.decl.length; i++)
{
Dsymbol s = (*scd.decl)[i];
if (auto var = s.isVarDeclaration)
@@ -1627,7 +1628,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (agg)
{
ad.pMangleOverride.agg = agg;
- if (pd.args.dim == 2)
+ if (pd.args.length == 2)
{
setString((*pd.args)[1]);
}
@@ -1668,7 +1669,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
{
if (pd.ident == Id.linkerDirective)
{
- if (!pd.args || pd.args.dim != 1)
+ if (!pd.args || pd.args.length != 1)
pd.error("one string argument expected for pragma(linkerDirective)");
else
{
@@ -1694,7 +1695,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
}
else if (pd.ident == Id.lib)
{
- if (!pd.args || pd.args.dim != 1)
+ if (!pd.args || pd.args.length != 1)
pd.error("string expected for library name");
else
{
@@ -1737,9 +1738,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
{
if (!pd.args)
pd.args = new Expressions();
- if (pd.args.dim == 0 || pd.args.dim > 2)
+ if (pd.args.length == 0 || pd.args.length > 2)
{
- pd.error(pd.args.dim == 0 ? "string expected for mangled name"
+ pd.error(pd.args.length == 0 ? "string expected for mangled name"
: "expected 1 or 2 arguments");
pd.args.setDim(1);
(*pd.args)[0] = ErrorExp.get(); // error recovery
@@ -1748,7 +1749,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
}
else if (pd.ident == Id.crt_constructor || pd.ident == Id.crt_destructor)
{
- if (pd.args && pd.args.dim != 0)
+ if (pd.args && pd.args.length != 0)
pd.error("takes no argument");
else
{
@@ -1762,7 +1763,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
auto decls = ad.include(null);
if (decls)
{
- for (size_t i = 0; i < decls.dim; ++i)
+ for (size_t i = 0; i < decls.length; ++i)
nestedCount += recurse((*decls)[i], isCtor);
}
return nestedCount;
@@ -1788,7 +1789,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
}
else if (pd.ident == Id.printf || pd.ident == Id.scanf)
{
- if (pd.args && pd.args.dim != 0)
+ if (pd.args && pd.args.length != 0)
pd.error("takes no argument");
return declarations();
}
@@ -1808,7 +1809,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (pd.args)
{
const errors_save = global.startGagging();
- for (size_t i = 0; i < pd.args.dim; i++)
+ for (size_t i = 0; i < pd.args.length; i++)
{
Expression e = (*pd.args)[i];
sc = sc.startCTFE();
@@ -1822,7 +1823,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
buf.writeByte(',');
buf.writestring(e.toChars());
}
- if (pd.args.dim)
+ if (pd.args.length)
buf.writeByte(')');
global.endGagging(errors_save);
}
@@ -1880,7 +1881,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (cd._scope && cd.decl)
{
- for (size_t i = 0; i < cd.decl.dim; i++)
+ for (size_t i = 0; i < cd.decl.length; i++)
{
Dsymbol s = (*cd.decl)[i];
s.setScope(cd._scope);
@@ -1919,11 +1920,11 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
{
expandTuples(te.exps);
CPPNamespaceDeclaration current = ns.cppnamespace;
- for (size_t d = 0; d < te.exps.dim; ++d)
+ for (size_t d = 0; d < te.exps.length; ++d)
{
auto exp = (*te.exps)[d];
auto prev = d ? current : ns.cppnamespace;
- current = (d + 1) != te.exps.dim
+ current = (d + 1) != te.exps.length
? new CPPNamespaceDeclaration(ns.loc, exp, null)
: ns;
current.exp = exp;
@@ -2122,7 +2123,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
return;
}
- if (ed.members.dim == 0)
+ if (ed.members.length == 0)
{
ed.error("enum `%s` must have at least one member", ed.toChars());
ed.errors = true;
@@ -2566,15 +2567,15 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (global.params.ddoc.doOutput)
{
- tempdecl.origParameters = new TemplateParameters(tempdecl.parameters.dim);
- for (size_t i = 0; i < tempdecl.parameters.dim; i++)
+ tempdecl.origParameters = new TemplateParameters(tempdecl.parameters.length);
+ for (size_t i = 0; i < tempdecl.parameters.length; i++)
{
TemplateParameter tp = (*tempdecl.parameters)[i];
(*tempdecl.origParameters)[i] = tp.syntaxCopy();
}
}
- for (size_t i = 0; i < tempdecl.parameters.dim; i++)
+ for (size_t i = 0; i < tempdecl.parameters.length; i++)
{
TemplateParameter tp = (*tempdecl.parameters)[i];
if (!tp.declareParameter(paramscope))
@@ -2586,7 +2587,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
{
tempdecl.errors = true;
}
- if (i + 1 != tempdecl.parameters.dim && tp.isTemplateTupleParameter())
+ if (i + 1 != tempdecl.parameters.length && tp.isTemplateTupleParameter())
{
tempdecl.error("template tuple parameter must be last one");
tempdecl.errors = true;
@@ -2596,12 +2597,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
/* Calculate TemplateParameter.dependent
*/
TemplateParameters tparams = TemplateParameters(1);
- for (size_t i = 0; i < tempdecl.parameters.dim; i++)
+ for (size_t i = 0; i < tempdecl.parameters.length; i++)
{
TemplateParameter tp = (*tempdecl.parameters)[i];
tparams[0] = tp;
- for (size_t j = 0; j < tempdecl.parameters.dim; j++)
+ for (size_t j = 0; j < tempdecl.parameters.length; j++)
{
// Skip cases like: X(T : T)
if (i == j)
@@ -2742,10 +2743,10 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
/* Different argument list lengths happen with variadic args
*/
- if (tm.tiargs.dim != tmix.tiargs.dim)
+ if (tm.tiargs.length != tmix.tiargs.length)
continue;
- for (size_t i = 0; i < tm.tiargs.dim; i++)
+ for (size_t i = 0; i < tm.tiargs.length; i++)
{
RootObject o = (*tm.tiargs)[i];
Type ta = isType(o);
@@ -2825,7 +2826,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
printf("\tdo semantic() on template instance members '%s'\n", tm.toChars());
}
Scope* sc2 = argscope.push(tm);
- //size_t deferred_dim = Module.deferred.dim;
+ //size_t deferred_dim = Module.deferred.length;
__gshared int nest;
//printf("%d\n", nest);
@@ -2848,7 +2849,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
* Because the members would already call Module.addDeferredSemantic() for themselves.
* See Struct, Class, Interface, and EnumDeclaration.dsymbolSemantic().
*/
- //if (!sc.func && Module.deferred.dim > deferred_dim) {}
+ //if (!sc.func && Module.deferred.length > deferred_dim) {}
AggregateDeclaration ad = tm.isMember();
if (sc.func && !ad)
@@ -3275,6 +3276,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
funcdecl.error("must return `void` for `pragma(%s)`", idStr.ptr);
if (funcdecl._linkage != LINK.c && f.parameterList.length != 0)
funcdecl.error("must be `extern(C)` for `pragma(%s)` when taking parameters", idStr.ptr);
+ if (funcdecl.isThis())
+ funcdecl.error("cannot be a non-static member function for `pragma(%s)`", idStr.ptr);
}
if (funcdecl.overnext && funcdecl.isCsymbol())
@@ -3344,7 +3347,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
{
if (!funcdecl.isStatic() || funcdecl.type.nextOf().ty != Tvoid)
funcdecl.error("static constructors / destructors must be `static void`");
- if (f.arguments && f.arguments.dim)
+ if (f.arguments && f.arguments.length)
funcdecl.error("static constructors / destructors must have empty parameter list");
// BUG: check for invalid storage classes
}
@@ -3451,13 +3454,13 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
goto Ldone;
bool may_override = false;
- for (size_t i = 0; i < cd.baseclasses.dim; i++)
+ for (size_t i = 0; i < cd.baseclasses.length; i++)
{
BaseClass* b = (*cd.baseclasses)[i];
ClassDeclaration cbd = b.type.toBasetype().isClassHandle();
if (!cbd)
continue;
- for (size_t j = 0; j < cbd.vtbl.dim; j++)
+ for (size_t j = 0; j < cbd.vtbl.length; j++)
{
FuncDeclaration f2 = cbd.vtbl[j].isFuncDeclaration();
if (!f2 || f2.ident != funcdecl.ident)
@@ -3481,7 +3484,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
/* Find index of existing function in base class's vtbl[] to override
* (the index will be the same as in cd's current vtbl[])
*/
- int vi = cd.baseClass ? funcdecl.findVtblIndex(&cd.baseClass.vtbl, cast(int)cd.baseClass.vtbl.dim) : -1;
+ int vi = cd.baseClass ? funcdecl.findVtblIndex(&cd.baseClass.vtbl, cast(int)cd.baseClass.vtbl.length) : -1;
bool doesoverride = false;
switch (vi)
@@ -3513,7 +3516,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
with offsets to each of the virtual bases.
*/
if (target.cpp.splitVBasetable && cd.classKind == ClassKind.cpp &&
- cd.baseClass && cd.baseClass.vtbl.dim)
+ cd.baseClass && cd.baseClass.vtbl.length)
{
/* if overriding an interface function, then this is not
* introducing and don't put it in the class vtbl[]
@@ -3544,7 +3547,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
* Search for first function of overload group, and insert
* funcdecl into vtbl[] immediately before it.
*/
- funcdecl.vtblIndex = cast(int)cd.vtbl.dim;
+ funcdecl.vtblIndex = cast(int)cd.vtbl.length;
bool found;
foreach (const i, s; cd.vtbl)
{
@@ -3574,7 +3577,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
else
{
// Append to end of vtbl[]
- vi = cast(int)cd.vtbl.dim;
+ vi = cast(int)cd.vtbl.length;
cd.vtbl.push(funcdecl);
funcdecl.vtblIndex = vi;
}
@@ -3672,7 +3675,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
* will be updated at the end of the enclosing `if` block
* to point to the current (non-mixined) function.
*/
- auto vitmp = cast(int)cd.vtbl.dim;
+ auto vitmp = cast(int)cd.vtbl.length;
cd.vtbl.push(fdc);
fdc.vtblIndex = vitmp;
}
@@ -3683,7 +3686,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
* vtbl, but keep the previous (non-mixined) function as
* the overriding one.
*/
- auto vitmp = cast(int)cd.vtbl.dim;
+ auto vitmp = cast(int)cd.vtbl.length;
cd.vtbl.push(funcdecl);
funcdecl.vtblIndex = vitmp;
break;
@@ -3743,7 +3746,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
{
foreach (b; bcd.interfaces)
{
- vi = funcdecl.findVtblIndex(&b.sym.vtbl, cast(int)b.sym.vtbl.dim);
+ vi = funcdecl.findVtblIndex(&b.sym.vtbl, cast(int)b.sym.vtbl.length);
switch (vi)
{
case -1:
@@ -3811,7 +3814,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
{
BaseClass* bc = null;
Dsymbol s = null;
- for (size_t i = 0; i < cd.baseclasses.dim; i++)
+ for (size_t i = 0; i < cd.baseclasses.length; i++)
{
bc = (*cd.baseclasses)[i];
s = bc.sym.search_correct(funcdecl.ident);
@@ -4207,7 +4210,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
else if (!dd.isFinal())
{
// reserve the dtor slot for the destructor (which we'll create later)
- cldec.cppDtorVtblIndex = cast(int)cldec.vtbl.dim;
+ cldec.cppDtorVtblIndex = cast(int)cldec.vtbl.length;
cldec.vtbl.push(dd);
if (target.cpp.twoDtorInVtable)
cldec.vtbl.push(dd); // deleting destructor uses a second slot
@@ -4865,7 +4868,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
cldec.baseok = Baseok.start;
// Expand any tuples in baseclasses[]
- for (size_t i = 0; i < cldec.baseclasses.dim;)
+ for (size_t i = 0; i < cldec.baseclasses.length;)
{
auto b = (*cldec.baseclasses)[i];
b.type = resolveBase(b.type.typeSemantic(cldec.loc, sc));
@@ -4895,7 +4898,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
}
// See if there's a base class as first in baseclasses[]
- if (cldec.baseclasses.dim)
+ if (cldec.baseclasses.length)
{
BaseClass* b = (*cldec.baseclasses)[0];
Type tb = b.type.toBasetype();
@@ -4955,7 +4958,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
int multiClassError = cldec.baseClass is null ? 0 : 1;
BCLoop:
- for (size_t i = (cldec.baseClass ? 1 : 0); i < cldec.baseclasses.dim;)
+ for (size_t i = (cldec.baseClass ? 1 : 0); i < cldec.baseclasses.length;)
{
BaseClass* b = (*cldec.baseclasses)[i];
Type tb = b.type.toBasetype();
@@ -4978,7 +4981,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
" Use multiple interface inheritance and/or composition.", cldec.toPrettyChars());
multiClassError += 1;
- if (tc.sym.fields.dim)
+ if (tc.sym.fields.length)
errorSupplemental(cldec.loc,"`%s` has fields, consider making it a member of `%s`",
b.type.toChars(), cldec.type.toChars());
else
@@ -5087,7 +5090,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
cldec.storage_class |= cldec.baseClass.storage_class & STC.TYPECTOR;
}
- cldec.interfaces = cldec.baseclasses.tdata()[(cldec.baseClass ? 1 : 0) .. cldec.baseclasses.dim];
+ cldec.interfaces = cldec.baseclasses.tdata()[(cldec.baseClass ? 1 : 0) .. cldec.baseclasses.length];
foreach (b; cldec.interfaces)
{
// If this is an interface, and it derives from a COM interface,
@@ -5133,7 +5136,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
sc2.pop();
}
- for (size_t i = 0; i < cldec.baseclasses.dim; i++)
+ for (size_t i = 0; i < cldec.baseclasses.length; i++)
{
BaseClass* b = (*cldec.baseclasses)[i];
Type tb = b.type.toBasetype();
@@ -5156,14 +5159,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
// initialize vtbl
if (cldec.baseClass)
{
- if (cldec.classKind == ClassKind.cpp && cldec.baseClass.vtbl.dim == 0)
+ if (cldec.classKind == ClassKind.cpp && cldec.baseClass.vtbl.length == 0)
{
cldec.error("C++ base class `%s` needs at least one virtual function", cldec.baseClass.toChars());
}
// Copy vtbl[] from base class
- cldec.vtbl.setDim(cldec.baseClass.vtbl.dim);
- memcpy(cldec.vtbl.tdata(), cldec.baseClass.vtbl.tdata(), (void*).sizeof * cldec.vtbl.dim);
+ cldec.vtbl.setDim(cldec.baseClass.vtbl.length);
+ memcpy(cldec.vtbl.tdata(), cldec.baseClass.vtbl.tdata(), (void*).sizeof * cldec.vtbl.length);
cldec.vthis = cldec.baseClass.vthis;
cldec.vthis2 = cldec.baseClass.vthis2;
@@ -5237,7 +5240,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
cldec.members.foreachDsymbol( s => s.importAll(sc2) );
- // Note that members.dim can grow due to tuple expansion during semantic()
+ // Note that members.length can grow due to tuple expansion during semantic()
cldec.members.foreachDsymbol( s => s.dsymbolSemantic(sc2) );
if (!cldec.determineFields())
@@ -5503,7 +5506,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
idec.baseok = Baseok.start;
// Expand any tuples in baseclasses[]
- for (size_t i = 0; i < idec.baseclasses.dim;)
+ for (size_t i = 0; i < idec.baseclasses.length;)
{
auto b = (*idec.baseclasses)[i];
b.type = resolveBase(b.type.typeSemantic(idec.loc, sc));
@@ -5532,7 +5535,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
goto Lancestorsdone;
}
- if (!idec.baseclasses.dim && sc.linkage == LINK.cpp)
+ if (!idec.baseclasses.length && sc.linkage == LINK.cpp)
idec.classKind = ClassKind.cpp;
idec.cppnamespace = sc.namespace;
UserAttributeDeclaration.checkGNUABITag(idec, sc.linkage);
@@ -5543,7 +5546,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
// Check for errors, handle forward references
BCLoop:
- for (size_t i = 0; i < idec.baseclasses.dim;)
+ for (size_t i = 0; i < idec.baseclasses.length;)
{
BaseClass* b = (*idec.baseclasses)[i];
Type tb = b.type.toBasetype();
@@ -5603,7 +5606,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
}
idec.baseok = Baseok.done;
- idec.interfaces = idec.baseclasses.tdata()[0 .. idec.baseclasses.dim];
+ idec.interfaces = idec.baseclasses.tdata()[0 .. idec.baseclasses.length];
foreach (b; idec.interfaces)
{
// If this is an interface, and it derives from a COM interface,
@@ -5626,7 +5629,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (!idec.symtab)
idec.symtab = new DsymbolTable();
- for (size_t i = 0; i < idec.baseclasses.dim; i++)
+ for (size_t i = 0; i < idec.baseclasses.length; i++)
{
BaseClass* b = (*idec.baseclasses)[i];
Type tb = b.type.toBasetype();
@@ -5662,7 +5665,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
// Copy vtbl[] from base class
if (b.sym.vtblOffset())
{
- size_t d = b.sym.vtbl.dim;
+ size_t d = b.sym.vtbl.length;
if (d > 1)
{
idec.vtbl.pushSlice(b.sym.vtbl[1 .. d]);
@@ -6055,13 +6058,13 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
// Store the place we added it to in target_symbol_list(_idx) so we can
// remove it later if we encounter an error.
Dsymbols* target_symbol_list = tempinst.appendToModuleMember();
- size_t target_symbol_list_idx = target_symbol_list ? target_symbol_list.dim - 1 : 0;
+ size_t target_symbol_list_idx = target_symbol_list ? target_symbol_list.length - 1 : 0;
// Copy the syntax trees from the TemplateDeclaration
tempinst.members = Dsymbol.arraySyntaxCopy(tempdecl.members);
// resolve TemplateThisParameter
- for (size_t i = 0; i < tempdecl.parameters.dim; i++)
+ for (size_t i = 0; i < tempdecl.parameters.length; i++)
{
if ((*tempdecl.parameters)[i].isTemplateThisParameter() is null)
continue;
@@ -6126,8 +6129,8 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
* member has the same name as the template instance.
* If so, this template instance becomes an alias for that member.
*/
- //printf("members.dim = %d\n", tempinst.members.dim);
- if (tempinst.members.dim)
+ //printf("members.length = %d\n", tempinst.members.length);
+ if (tempinst.members.length)
{
Dsymbol s;
if (Dsymbol.oneMembers(tempinst.members, &s, tempdecl.ident) && s)
@@ -6172,7 +6175,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
/* ConditionalDeclaration may introduce eponymous declaration,
* so we should find it once again after semantic.
*/
- if (tempinst.members.dim)
+ if (tempinst.members.length)
{
Dsymbol s;
if (Dsymbol.oneMembers(tempinst.members, &s, tempdecl.ident) && s)
@@ -6195,7 +6198,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
*/
{
bool found_deferred_ad = false;
- for (size_t i = 0; i < Module.deferred.dim; i++)
+ for (size_t i = 0; i < Module.deferred.length; i++)
{
Dsymbol sd = Module.deferred[i];
AggregateDeclaration ad = sd.isAggregateDeclaration();
@@ -6211,7 +6214,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
}
}
}
- if (found_deferred_ad || Module.deferred.dim)
+ if (found_deferred_ad || Module.deferred.length)
goto Laftersemantic;
}
@@ -6245,7 +6248,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
//printf("Run semantic3 on %s\n", toChars());
tempinst.trySemantic3(sc2);
- for (size_t i = 0; i < deferred.dim; i++)
+ for (size_t i = 0; i < deferred.length; i++)
{
//printf("+ run deferred semantic3 on %s\n", deferred[i].toChars());
deferred[i].semantic3(null);
@@ -6288,7 +6291,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
{
if (!td.literal)
continue;
- assert(td.members && td.members.dim == 1);
+ assert(td.members && td.members.length == 1);
s = (*td.members)[0];
}
if (auto fld = s.isFuncLiteralDeclaration())
@@ -6322,7 +6325,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
//printf("deferred semantic3 of %p %s, ti = %s, ti.deferred = %p\n", this, toChars(), ti.toChars());
for (size_t i = 0;; i++)
{
- if (i == ti.deferred.dim)
+ if (i == ti.deferred.length)
{
ti.deferred.push(tempinst);
break;
@@ -6553,7 +6556,7 @@ void aliasSemantic(AliasDeclaration ds, Scope* sc)
// Selective imports are allowed to alias to the same name `import mod : sym=sym`.
if (!ds._import)
{
- if (tident.ident is ds.ident && !tident.idents.dim)
+ if (tident.ident is ds.ident && !tident.idents.length)
{
error(ds.loc, "`alias %s = %s;` cannot alias itself, use a qualified name to create an overload set",
ds.ident.toChars(), tident.ident.toChars());
@@ -6958,7 +6961,7 @@ private TupleDeclaration aliasAssignInPlace(Scope* sc, TemplateInstance tempinst
private TemplateInstance isAliasSeq(Scope* sc, TypeInstance ti)
{
auto tovers = ti.tempinst.tempdecl.isOverloadSet();
- foreach (size_t oi; 0 .. tovers ? tovers.a.dim : 1)
+ foreach (size_t oi; 0 .. tovers ? tovers.a.length : 1)
{
Dsymbol dstart = tovers ? tovers.a[oi] : ti.tempinst.tempdecl;
int r = overloadApply(dstart, (Dsymbol s)
@@ -6994,7 +6997,7 @@ bool determineFields(AggregateDeclaration ad)
if (ad.sizeok != Sizeok.none)
return true;
- //printf("determineFields() %s, fields.dim = %d\n", toChars(), fields.dim);
+ //printf("determineFields() %s, fields.length = %d\n", toChars(), fields.length);
// determineFields can be called recursively from one of the fields's v.semantic
ad.fields.setDim(0);
@@ -7046,7 +7049,7 @@ bool determineFields(AggregateDeclaration ad)
if (ad.members)
{
- for (size_t i = 0; i < ad.members.dim; i++)
+ for (size_t i = 0; i < ad.members.length; i++)
{
auto s = (*ad.members)[i];
if (s.apply(&func, ad))
@@ -7123,12 +7126,12 @@ private CallExp doAtomicOp (string op, Identifier var, Expression arg)
*/
PINLINE evalPragmaInline(Loc loc, Scope* sc, Expressions* args)
{
- if (!args || args.dim == 0)
+ if (!args || args.length == 0)
return PINLINE.default_;
- if (args && args.dim > 1)
+ if (args && args.length > 1)
{
- .error(loc, "one boolean expression expected for `pragma(inline)`, not %llu", cast(ulong) args.dim);
+ .error(loc, "one boolean expression expected for `pragma(inline)`, not %llu", cast(ulong) args.length);
args.setDim(1);
(*args)[0] = ErrorExp.get();
}
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index 1f99c58..6095dcc 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -362,9 +362,9 @@ private bool arrayObjectMatch(Objects* oa1, Objects* oa2)
{
if (oa1 == oa2)
return true;
- if (oa1.dim != oa2.dim)
+ if (oa1.length != oa2.length)
return false;
- immutable oa1dim = oa1.dim;
+ immutable oa1dim = oa1.length;
auto oa1d = (*oa1)[].ptr;
auto oa2d = (*oa2)[].ptr;
foreach (j; 0 .. oa1dim)
@@ -454,7 +454,7 @@ private size_t expressionHash(Expression e)
{
auto ae = e.isArrayLiteralExp();
size_t hash;
- foreach (i; 0 .. ae.elements.dim)
+ foreach (i; 0 .. ae.elements.length)
hash = mixHash(hash, expressionHash(ae[i]));
return hash;
}
@@ -463,7 +463,7 @@ private size_t expressionHash(Expression e)
{
auto ae = e.isAssocArrayLiteralExp();
size_t hash;
- foreach (i; 0 .. ae.keys.dim)
+ foreach (i; 0 .. ae.keys.length)
// reduction needs associative op as keys are unsorted (use XOR)
hash ^= mixHash(expressionHash((*ae.keys)[i]), expressionHash((*ae.values)[i]));
return hash;
@@ -586,7 +586,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
version (none)
{
if (parameters)
- for (int i = 0; i < parameters.dim; i++)
+ for (int i = 0; i < parameters.length; i++)
{
TemplateParameter tp = (*parameters)[i];
//printf("\tparameter[%d] = %p\n", i, tp);
@@ -660,7 +660,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
TemplateParameters* p = null;
if (parameters)
{
- p = new TemplateParameters(parameters.dim);
+ p = new TemplateParameters(parameters.length);
foreach (i, ref param; *p)
param = (*parameters)[i].syntaxCopy();
}
@@ -1059,9 +1059,9 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
}
version (none)
{
- printf("dedtypes.dim = %d, parameters.dim = %d\n", dedtypes.dim, parameters.dim);
- if (ti.tiargs.dim)
- printf("ti.tiargs.dim = %d, [0] = %p\n", ti.tiargs.dim, (*ti.tiargs)[0]);
+ printf("dedtypes.length = %d, parameters.length = %d\n", dedtypes.length, parameters.length);
+ if (ti.tiargs.length)
+ printf("ti.tiargs.length = %d, [0] = %p\n", ti.tiargs.length, (*ti.tiargs)[0]);
}
MATCH nomatch()
{
@@ -1072,18 +1072,18 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
return MATCH.nomatch;
}
MATCH m;
- size_t dedtypes_dim = dedtypes.dim;
+ size_t dedtypes_dim = dedtypes.length;
dedtypes.zero();
if (errors)
return MATCH.nomatch;
- size_t parameters_dim = parameters.dim;
+ size_t parameters_dim = parameters.length;
int variadic = isVariadic() !is null;
// If more arguments than parameters, no match
- if (ti.tiargs.dim > parameters_dim && !variadic)
+ if (ti.tiargs.length > parameters_dim && !variadic)
{
static if (LOGM)
{
@@ -1093,7 +1093,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
}
assert(dedtypes_dim == parameters_dim);
- assert(dedtypes_dim >= ti.tiargs.dim || variadic);
+ assert(dedtypes_dim >= ti.tiargs.length || variadic);
assert(_scope);
@@ -1152,7 +1152,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
{
if (!dedtype)
{
- assert(i < ti.tiargs.dim);
+ assert(i < ti.tiargs.length);
dedtype = cast(Type)(*ti.tiargs)[i];
}
}
@@ -1210,7 +1210,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
TemplateParameter tp = (*parameters)[i];
RootObject oarg;
printf(" [%d]", i);
- if (i < ti.tiargs.dim)
+ if (i < ti.tiargs.length)
oarg = (*ti.tiargs)[i];
else
oarg = null;
@@ -1257,7 +1257,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
// Set type arguments to dummy template instance to be types
// generated from the parameters to this template declaration
auto tiargs = new Objects();
- tiargs.reserve(parameters.dim);
+ tiargs.reserve(parameters.length);
foreach (tp; *parameters)
{
if (tp.dependent)
@@ -1271,7 +1271,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
scope TemplateInstance ti = new TemplateInstance(Loc.initial, ident, tiargs); // create dummy template instance
// Temporary Array to hold deduced types
- Objects dedtypes = Objects(td2.parameters.dim);
+ Objects dedtypes = Objects(td2.parameters.length);
// Attempt a type deduction
MATCH m = td2.matchWithInstance(sc, ti, &dedtypes, fargs, 1);
@@ -1327,13 +1327,13 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
Loc instLoc = ti.loc;
Objects* tiargs = ti.tiargs;
- auto dedargs = new Objects(parameters.dim);
+ auto dedargs = new Objects(parameters.length);
Objects* dedtypes = &ti.tdtypes; // for T:T*, the dedargs is the T*, dedtypes is the T
version (none)
{
printf("\nTemplateDeclaration.deduceFunctionTemplateMatch() %s\n", toChars());
- for (size_t i = 0; i < (fargs ? fargs.dim : 0); i++)
+ for (size_t i = 0; i < (fargs ? fargs.length : 0); i++)
{
Expression e = (*fargs)[i];
printf("\tfarg[%d] is %s, type is %s\n", i, e.toChars(), e.type.toChars());
@@ -1348,7 +1348,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
dedargs.zero();
- dedtypes.setDim(parameters.dim);
+ dedtypes.setDim(parameters.length);
dedtypes.zero();
if (errors || fd.errors)
@@ -1381,7 +1381,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
version (none)
{
- for (size_t i = 0; i < dedargs.dim; i++)
+ for (size_t i = 0; i < dedargs.length; i++)
{
printf("\tdedarg[%d] = ", i);
RootObject oarg = (*dedargs)[i];
@@ -1395,8 +1395,8 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
if (tiargs)
{
// Set initial template arguments
- ntargs = tiargs.dim;
- size_t n = parameters.dim;
+ ntargs = tiargs.length;
+ size_t n = parameters.length;
if (tp)
n--;
if (ntargs > n)
@@ -1408,10 +1408,10 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
* now form the tuple argument.
*/
auto t = new Tuple(ntargs - n);
- assert(parameters.dim);
- (*dedargs)[parameters.dim - 1] = t;
+ assert(parameters.length);
+ (*dedargs)[parameters.length - 1] = t;
- for (size_t i = 0; i < t.objects.dim; i++)
+ for (size_t i = 0; i < t.objects.length; i++)
{
t.objects[i] = (*tiargs)[n + i];
}
@@ -1425,7 +1425,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
for (size_t i = 0; i < n; i++)
{
- assert(i < parameters.dim);
+ assert(i < parameters.length);
Declaration sparam = null;
MATCH m = (*parameters)[i].matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, &sparam);
//printf("\tdeduceType m = %d\n", m);
@@ -1438,17 +1438,17 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
if (!paramscope.insert(sparam))
return nomatch();
}
- if (n < parameters.dim && !declaredTuple)
+ if (n < parameters.length && !declaredTuple)
{
inferStart = n;
}
else
- inferStart = parameters.dim;
+ inferStart = parameters.length;
//printf("tiargs matchTiargs = %d\n", matchTiargs);
}
version (none)
{
- for (size_t i = 0; i < dedargs.dim; i++)
+ for (size_t i = 0; i < dedargs.length; i++)
{
printf("\tdedarg[%d] = ", i);
RootObject oarg = (*dedargs)[i];
@@ -1460,7 +1460,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
fparameters = fd.getParameterList();
nfparams = fparameters.length; // number of function parameters
- nfargs = fargs ? fargs.dim : 0; // number of function arguments
+ nfargs = fargs ? fargs.length : 0; // number of function arguments
/* Check for match of function arguments with variadic template
* parameter, such as:
@@ -1479,7 +1479,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
{
auto t = new Tuple();
//printf("t = %p\n", t);
- (*dedargs)[parameters.dim - 1] = t;
+ (*dedargs)[parameters.length - 1] = t;
declareParameter(paramscope, tp, t);
declaredTuple = t;
}
@@ -1497,7 +1497,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
if (fparam.type.ty != Tident)
continue;
TypeIdentifier tid = cast(TypeIdentifier)fparam.type;
- if (!tp.ident.equals(tid.ident) || tid.idents.dim)
+ if (!tp.ident.equals(tid.ident) || tid.idents.length)
continue;
if (fparameters.varargs != VarArg.none) // variadic function doesn't
@@ -1570,7 +1570,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
// Loop through the function parameters
{
- //printf("%s\n\tnfargs = %d, nfparams = %d, tuple_dim = %d\n", toChars(), nfargs, nfparams, declaredTuple ? declaredTuple.objects.dim : 0);
+ //printf("%s\n\tnfargs = %d, nfparams = %d, tuple_dim = %d\n", toChars(), nfargs, nfparams, declaredTuple ? declaredTuple.objects.length : 0);
//printf("\ttp = %p, fptupindex = %d, found = %d, declaredTuple = %s\n", tp, fptupindex, fptupindex != IDX_NOTFOUND, declaredTuple ? declaredTuple.toChars() : NULL);
size_t argi = 0;
size_t nfargs2 = nfargs; // nfargs + supplied defaultArgs
@@ -1596,7 +1596,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
* now form the tuple argument.
*/
declaredTuple = new Tuple();
- (*dedargs)[parameters.dim - 1] = declaredTuple;
+ (*dedargs)[parameters.length - 1] = declaredTuple;
/* Count function parameters with no defaults following a tuple parameter.
* void foo(U, T...)(int y, T, U, double, int bar = 0) {} // rem == 2 (U, double)
@@ -1609,10 +1609,10 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
{
break;
}
- if (!reliesOnTemplateParameters(p.type, (*parameters)[inferStart .. parameters.dim]))
+ if (!reliesOnTemplateParameters(p.type, (*parameters)[inferStart .. parameters.length]))
{
Type pt = p.type.syntaxCopy().typeSemantic(fd.loc, paramscope);
- rem += pt.ty == Ttuple ? (cast(TypeTuple)pt).arguments.dim : 1;
+ rem += pt.ty == Ttuple ? (cast(TypeTuple)pt).arguments.length : 1;
}
else
{
@@ -1623,7 +1623,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
if (nfargs2 - argi < rem)
return nomatch();
declaredTuple.objects.setDim(nfargs2 - argi - rem);
- for (size_t i = 0; i < declaredTuple.objects.dim; i++)
+ for (size_t i = 0; i < declaredTuple.objects.length; i++)
{
farg = (*fargs)[argi + i];
@@ -1665,20 +1665,20 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
// https://issues.dlang.org/show_bug.cgi?id=6810
// If declared tuple is not a type tuple,
// it cannot be function parameter types.
- for (size_t i = 0; i < declaredTuple.objects.dim; i++)
+ for (size_t i = 0; i < declaredTuple.objects.length; i++)
{
if (!isType(declaredTuple.objects[i]))
return nomatch();
}
}
assert(declaredTuple);
- argi += declaredTuple.objects.dim;
+ argi += declaredTuple.objects.length;
continue;
}
// If parameter type doesn't depend on inferred template parameters,
// semantic it to get actual type.
- if (!reliesOnTemplateParameters(prmtype, (*parameters)[inferStart .. parameters.dim]))
+ if (!reliesOnTemplateParameters(prmtype, (*parameters)[inferStart .. parameters.length]))
{
// should copy prmtype to avoid affecting semantic result
prmtype = prmtype.syntaxCopy().typeSemantic(fd.loc, paramscope);
@@ -1686,7 +1686,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
if (prmtype.ty == Ttuple)
{
TypeTuple tt = cast(TypeTuple)prmtype;
- size_t tt_dim = tt.arguments.dim;
+ size_t tt_dim = tt.arguments.length;
for (size_t j = 0; j < tt_dim; j++, ++argi)
{
Parameter p = (*tt.arguments)[j];
@@ -1748,7 +1748,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
dedtype = xt.tded; // 'unbox'
}
}
- for (size_t i = ntargs; i < dedargs.dim; i++)
+ for (size_t i = ntargs; i < dedargs.length; i++)
{
TemplateParameter tparam = (*parameters)[i];
@@ -1850,7 +1850,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
/* Allow expressions that have CT-known boundaries and type [] to match with [dim]
*/
Type taai;
- if (argtype.ty == Tarray && (prmtype.ty == Tsarray || prmtype.ty == Taarray && (taai = (cast(TypeAArray)prmtype).index).ty == Tident && (cast(TypeIdentifier)taai).idents.dim == 0))
+ if (argtype.ty == Tarray && (prmtype.ty == Tsarray || prmtype.ty == Taarray && (taai = (cast(TypeAArray)prmtype).index).ty == Tident && (cast(TypeIdentifier)taai).idents.length == 0))
{
if (farg.op == EXP.string_)
{
@@ -1860,7 +1860,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
else if (farg.op == EXP.arrayLiteral)
{
ArrayLiteralExp ae = cast(ArrayLiteralExp)farg;
- argtype = ae.type.nextOf().sarrayOf(ae.elements.dim);
+ argtype = ae.type.nextOf().sarrayOf(ae.elements.length);
}
else if (farg.op == EXP.slice)
{
@@ -1872,7 +1872,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
oarg = argtype;
}
- else if ((fparam.storageClass & STC.out_) == 0 && (argtype.ty == Tarray || argtype.ty == Tpointer) && templateParameterLookup(prmtype, parameters) != IDX_NOTFOUND && (cast(TypeIdentifier)prmtype).idents.dim == 0)
+ else if ((fparam.storageClass & STC.out_) == 0 && (argtype.ty == Tarray || argtype.ty == Tpointer) && templateParameterLookup(prmtype, parameters) != IDX_NOTFOUND && (cast(TypeIdentifier)prmtype).idents.length == 0)
{
/* The farg passing to the prmtype always make a copy. Therefore,
* we can shrink the set of the deduced type arguments for prmtype
@@ -2124,7 +2124,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
dedtype = at.merge2();
}
}
- for (size_t i = ntargs; i < dedargs.dim; i++)
+ for (size_t i = ntargs; i < dedargs.length; i++)
{
TemplateParameter tparam = (*parameters)[i];
//printf("tparam[%d] = %s\n", i, tparam.ident.toChars());
@@ -2176,7 +2176,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
// we're one or more arguments short (i.e. no tuple argument)
if (tparam == tp &&
fptupindex == IDX_NOTFOUND &&
- ntargs <= dedargs.dim - 1)
+ ntargs <= dedargs.length - 1)
{
// make tuple argument an empty tuple
oded = new Tuple();
@@ -2215,7 +2215,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
* As same as the code for 7469 in findBestMatch,
* expand a Tuple in dedargs to normalize template arguments.
*/
- if (auto d = dedargs.dim)
+ if (auto d = dedargs.length)
{
if (auto va = isTuple((*dedargs)[d - 1]))
{
@@ -2253,7 +2253,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
version (none)
{
- for (size_t i = 0; i < dedargs.dim; i++)
+ for (size_t i = 0; i < dedargs.length; i++)
{
RootObject o = (*dedargs)[i];
printf("\tdedargs[%d] = %d, %s\n", i, o.dyncast(), o.toChars());
@@ -2515,7 +2515,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
*/
TemplateTupleParameter isVariadic()
{
- size_t dim = parameters.dim;
+ size_t dim = parameters.length;
if (dim == 0)
return null;
return (*parameters)[dim - 1].isTemplateTupleParameter();
@@ -2612,14 +2612,14 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
printf(" tiargs:\n");
if (tiargs)
{
- for (size_t i = 0; i < tiargs.dim; i++)
+ for (size_t i = 0; i < tiargs.length; i++)
{
RootObject arg = (*tiargs)[i];
printf("\t%s\n", arg.toChars());
}
}
printf(" fargs:\n");
- for (size_t i = 0; i < (fargs ? fargs.dim : 0); i++)
+ for (size_t i = 0; i < (fargs ? fargs.length : 0); i++)
{
Expression arg = (*fargs)[i];
printf("\t%s %s\n", arg.type.toChars(), arg.toChars());
@@ -2645,7 +2645,7 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
if (fd == m.lastf)
return 0;
// explicitly specified tiargs never match to non template function
- if (tiargs && tiargs.dim > 0)
+ if (tiargs && tiargs.length > 0)
return 0;
// constructors need a valid scope in order to detect semantic errors
@@ -2847,7 +2847,7 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
if (!tiargs)
tiargs = new Objects();
auto ti = new TemplateInstance(loc, td, tiargs);
- Objects dedtypes = Objects(td.parameters.dim);
+ Objects dedtypes = Objects(td.parameters.length);
assert(td.semanticRun != PASS.initial);
MATCH mta = td.matchWithInstance(sc, ti, &dedtypes, fargs, 0);
//printf("matchWithInstance = %d\n", mta);
@@ -3154,7 +3154,7 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
*/
private size_t templateIdentifierLookup(Identifier id, TemplateParameters* parameters)
{
- for (size_t i = 0; i < parameters.dim; i++)
+ for (size_t i = 0; i < parameters.length; i++)
{
TemplateParameter tp = (*parameters)[i];
if (tp.ident.equals(id))
@@ -3536,7 +3536,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
/* Need a loc to go with the semantic routine.
*/
Loc loc;
- if (parameters.dim)
+ if (parameters.length)
{
TemplateParameter tp = (*parameters)[0];
loc = tp.loc;
@@ -3554,11 +3554,11 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
TemplateParameter tp = (*parameters)[i];
TypeIdentifier tident = cast(TypeIdentifier)tparam;
- if (tident.idents.dim > 0)
+ if (tident.idents.length > 0)
{
//printf("matching %s to %s\n", tparam.toChars(), t.toChars());
Dsymbol s = t.toDsymbol(sc);
- for (size_t j = tident.idents.dim; j-- > 0;)
+ for (size_t j = tident.idents.length; j-- > 0;)
{
RootObject id = tident.idents[j];
if (id.dyncast() == DYNCAST.identifier)
@@ -3707,7 +3707,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
/* Need a loc to go with the semantic routine.
*/
Loc loc;
- if (parameters.dim)
+ if (parameters.length)
{
TemplateParameter tp = (*parameters)[0];
loc = tp.loc;
@@ -3845,7 +3845,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
// The "type" (it hasn't been resolved yet) of the function parameter
// does not have a location but the parameter it is related to does,
// so we use that for the resolution (better error message).
- if (inferStart < parameters.dim)
+ if (inferStart < parameters.length)
{
TemplateParameter loctp = (*parameters)[inferStart];
loc = loctp.loc;
@@ -3905,7 +3905,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
// https://issues.dlang.org/show_bug.cgi?id=15243
// Resolve parameter type if it's not related with template parameters
- if (!reliesOnTemplateParameters(fparam.type, (*parameters)[inferStart .. parameters.dim]))
+ if (!reliesOnTemplateParameters(fparam.type, (*parameters)[inferStart .. parameters.length]))
{
auto tx = fparam.type.typeSemantic(Loc.initial, sc);
if (tx.ty == Terror)
@@ -3933,7 +3933,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
if (fparam.type.ty != Tident)
goto L1;
TypeIdentifier tid = cast(TypeIdentifier)fparam.type;
- if (tid.idents.dim)
+ if (tid.idents.length)
goto L1;
/* Look through parameters to find tuple matching tid.ident
@@ -3941,7 +3941,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
size_t tupi = 0;
for (; 1; tupi++)
{
- if (tupi == parameters.dim)
+ if (tupi == parameters.length)
goto L1;
TemplateParameter tx = (*parameters)[tupi];
TemplateTupleParameter tup = tx.isTemplateTupleParameter();
@@ -3961,7 +3961,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
{
// Existing deduced argument must be a tuple, and must match
Tuple tup = isTuple(o);
- if (!tup || tup.objects.dim != tuple_dim)
+ if (!tup || tup.objects.length != tuple_dim)
{
result = MATCH.nomatch;
return;
@@ -4023,7 +4023,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
if (tparam && tparam.ty == Tident)
{
TypeIdentifier tp = cast(TypeIdentifier)tparam;
- for (size_t i = 0; i < t.idents.dim; i++)
+ for (size_t i = 0; i < t.idents.length; i++)
{
RootObject id1 = t.idents[i];
RootObject id2 = tp.idents[i];
@@ -4112,19 +4112,19 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
{
//printf("\ttest: tempinst.tiargs[%d]\n", i);
RootObject o1 = null;
- if (i < t.tempinst.tiargs.dim)
+ if (i < t.tempinst.tiargs.length)
o1 = (*t.tempinst.tiargs)[i];
- else if (i < t.tempinst.tdtypes.dim && i < tp.tempinst.tiargs.dim)
+ else if (i < t.tempinst.tdtypes.length && i < tp.tempinst.tiargs.length)
{
// Pick up default arg
o1 = t.tempinst.tdtypes[i];
}
- else if (i >= tp.tempinst.tiargs.dim)
+ else if (i >= tp.tempinst.tiargs.length)
break;
- if (i >= tp.tempinst.tiargs.dim)
+ if (i >= tp.tempinst.tiargs.length)
{
- size_t dim = tempdecl.parameters.dim - (tempdecl.isVariadic() ? 1 : 0);
+ size_t dim = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0);
while (i < dim && ((*tempdecl.parameters)[i].dependent || (*tempdecl.parameters)[i].hasDefaultArg()))
{
i++;
@@ -4137,9 +4137,9 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
RootObject o2 = (*tp.tempinst.tiargs)[i];
Type t2 = isType(o2);
- size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.dim - 1)
+ size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.length - 1)
? templateParameterLookup(t2, parameters) : IDX_NOTFOUND;
- if (j != IDX_NOTFOUND && j == parameters.dim - 1 &&
+ if (j != IDX_NOTFOUND && j == parameters.length - 1 &&
(*parameters)[j].isTemplateTupleParameter())
{
/* Given:
@@ -4151,12 +4151,12 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
/* Create tuple from remaining args
*/
- size_t vtdim = (tempdecl.isVariadic() ? t.tempinst.tiargs.dim : t.tempinst.tdtypes.dim) - i;
+ size_t vtdim = (tempdecl.isVariadic() ? t.tempinst.tiargs.length : t.tempinst.tdtypes.length) - i;
auto vt = new Tuple(vtdim);
for (size_t k = 0; k < vtdim; k++)
{
RootObject o;
- if (k < t.tempinst.tiargs.dim)
+ if (k < t.tempinst.tiargs.length)
o = (*t.tempinst.tiargs)[i + k];
else // Pick up default arg
o = t.tempinst.tdtypes[i + k];
@@ -4315,9 +4315,9 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
* S!(T).foo
*/
TypeInstance tpi = cast(TypeInstance)tparam;
- if (tpi.idents.dim)
+ if (tpi.idents.length)
{
- RootObject id = tpi.idents[tpi.idents.dim - 1];
+ RootObject id = tpi.idents[tpi.idents.length - 1];
if (id.dyncast() == DYNCAST.identifier && t.sym.ident.equals(cast(Identifier)id))
{
Type tparent = t.sym.parent.getType();
@@ -4325,9 +4325,9 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
{
/* Slice off the .foo in S!(T).foo
*/
- tpi.idents.dim--;
+ tpi.idents.length--;
result = deduceType(tparent, sc, tpi, parameters, dedtypes, wm);
- tpi.idents.dim++;
+ tpi.idents.length++;
return;
}
}
@@ -4398,8 +4398,8 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
if (parti)
{
// Make a temporary copy of dedtypes so we don't destroy it
- auto tmpdedtypes = new Objects(dedtypes.dim);
- memcpy(tmpdedtypes.tdata(), dedtypes.tdata(), dedtypes.dim * (void*).sizeof);
+ auto tmpdedtypes = new Objects(dedtypes.length);
+ memcpy(tmpdedtypes.tdata(), dedtypes.tdata(), dedtypes.length * (void*).sizeof);
auto t = new TypeInstance(Loc.initial, parti);
MATCH m = deduceType(t, sc, tparam, parameters, tmpdedtypes);
@@ -4407,9 +4407,9 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
{
// If this is the first ever match, it becomes our best estimate
if (numBaseClassMatches == 0)
- memcpy(best.tdata(), tmpdedtypes.tdata(), tmpdedtypes.dim * (void*).sizeof);
+ memcpy(best.tdata(), tmpdedtypes.tdata(), tmpdedtypes.length * (void*).sizeof);
else
- for (size_t k = 0; k < tmpdedtypes.dim; ++k)
+ for (size_t k = 0; k < tmpdedtypes.length; ++k)
{
// If we've found more than one possible type for a parameter,
// mark it as unknown.
@@ -4456,9 +4456,9 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
* S!(T).foo
*/
TypeInstance tpi = cast(TypeInstance)tparam;
- if (tpi.idents.dim)
+ if (tpi.idents.length)
{
- RootObject id = tpi.idents[tpi.idents.dim - 1];
+ RootObject id = tpi.idents[tpi.idents.length - 1];
if (id.dyncast() == DYNCAST.identifier && t.sym.ident.equals(cast(Identifier)id))
{
Type tparent = t.sym.parent.getType();
@@ -4466,9 +4466,9 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
{
/* Slice off the .foo in S!(T).foo
*/
- tpi.idents.dim--;
+ tpi.idents.length--;
result = deduceType(tparent, sc, tpi, parameters, dedtypes, wm);
- tpi.idents.dim++;
+ tpi.idents.length++;
return;
}
}
@@ -4487,10 +4487,10 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
int numBaseClassMatches = 0; // Have we found an interface match?
// Our best guess at dedtypes
- auto best = new Objects(dedtypes.dim);
+ auto best = new Objects(dedtypes.length);
ClassDeclaration s = t.sym;
- while (s && s.baseclasses.dim > 0)
+ while (s && s.baseclasses.length > 0)
{
// Test the base class
deduceBaseClassParameters(*(*s.baseclasses)[0], sc, tparam, parameters, dedtypes, best, numBaseClassMatches);
@@ -4510,7 +4510,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
}
// If we got at least one match, copy the known types into dedtypes
- memcpy(dedtypes.tdata(), best.tdata(), best.dim * (void*).sizeof);
+ memcpy(dedtypes.tdata(), best.tdata(), best.length * (void*).sizeof);
result = MATCH.convert;
return;
}
@@ -4536,7 +4536,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
{
//printf("Expression.deduceType(e = %s)\n", e.toChars());
size_t i = templateParameterLookup(tparam, parameters);
- if (i == IDX_NOTFOUND || (cast(TypeIdentifier)tparam).idents.dim > 0)
+ if (i == IDX_NOTFOUND || (cast(TypeIdentifier)tparam).idents.length > 0)
{
if (e == emptyArrayElement && tparam.ty == Tarray)
{
@@ -4721,7 +4721,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
override void visit(StringExp e)
{
Type taai;
- if (e.type.ty == Tarray && (tparam.ty == Tsarray || tparam.ty == Taarray && (taai = (cast(TypeAArray)tparam).index).ty == Tident && (cast(TypeIdentifier)taai).idents.dim == 0))
+ if (e.type.ty == Tarray && (tparam.ty == Tsarray || tparam.ty == Taarray && (taai = (cast(TypeAArray)tparam).index).ty == Tident && (cast(TypeIdentifier)taai).idents.length == 0))
{
// Consider compile-time known boundaries
e.type.nextOf().sarrayOf(e.len).accept(this);
@@ -4733,19 +4733,19 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
override void visit(ArrayLiteralExp e)
{
// https://issues.dlang.org/show_bug.cgi?id=20092
- if (e.elements && e.elements.dim && e.type.toBasetype().nextOf().ty == Tvoid)
+ if (e.elements && e.elements.length && e.type.toBasetype().nextOf().ty == Tvoid)
{
result = deduceEmptyArrayElement();
return;
}
- if ((!e.elements || !e.elements.dim) && e.type.toBasetype().nextOf().ty == Tvoid && tparam.ty == Tarray)
+ if ((!e.elements || !e.elements.length) && e.type.toBasetype().nextOf().ty == Tvoid && tparam.ty == Tarray)
{
// tparam:T[] <- e:[] (void[])
result = deduceEmptyArrayElement();
return;
}
- if (tparam.ty == Tarray && e.elements && e.elements.dim)
+ if (tparam.ty == Tarray && e.elements && e.elements.length)
{
Type tn = (cast(TypeDArray)tparam).next;
result = MATCH.exact;
@@ -4769,10 +4769,10 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
}
Type taai;
- if (e.type.ty == Tarray && (tparam.ty == Tsarray || tparam.ty == Taarray && (taai = (cast(TypeAArray)tparam).index).ty == Tident && (cast(TypeIdentifier)taai).idents.dim == 0))
+ if (e.type.ty == Tarray && (tparam.ty == Tsarray || tparam.ty == Taarray && (taai = (cast(TypeAArray)tparam).index).ty == Tident && (cast(TypeIdentifier)taai).idents.length == 0))
{
// Consider compile-time known boundaries
- e.type.nextOf().sarrayOf(e.elements.dim).accept(this);
+ e.type.nextOf().sarrayOf(e.elements.length).accept(this);
return;
}
visit(cast(Expression)e);
@@ -4780,7 +4780,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
override void visit(AssocArrayLiteralExp e)
{
- if (tparam.ty == Taarray && e.keys && e.keys.dim)
+ if (tparam.ty == Taarray && e.keys && e.keys.length)
{
TypeAArray taa = cast(TypeAArray)tparam;
result = MATCH.exact;
@@ -4825,7 +4825,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
return;
auto tiargs = new Objects();
- tiargs.reserve(e.td.parameters.dim);
+ tiargs.reserve(e.td.parameters.length);
foreach (tp; *e.td.parameters)
{
@@ -4841,7 +4841,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
if (!pto)
break;
Type t = pto.type.syntaxCopy(); // https://issues.dlang.org/show_bug.cgi?id=11774
- if (reliesOnTemplateParameters(t, (*parameters)[inferStart .. parameters.dim]))
+ if (reliesOnTemplateParameters(t, (*parameters)[inferStart .. parameters.length]))
return;
t = t.typeSemantic(e.loc, sc);
if (t.ty == Terror)
@@ -4885,7 +4885,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
override void visit(SliceExp e)
{
Type taai;
- if (e.type.ty == Tarray && (tparam.ty == Tsarray || tparam.ty == Taarray && (taai = (cast(TypeAArray)tparam).index).ty == Tident && (cast(TypeIdentifier)taai).idents.dim == 0))
+ if (e.type.ty == Tarray && (tparam.ty == Tsarray || tparam.ty == Taarray && (taai = (cast(TypeAArray)tparam).index).ty == Tident && (cast(TypeIdentifier)taai).idents.length == 0))
{
// Consider compile-time known boundaries
if (Type tsa = toStaticArrayType(e))
@@ -4928,7 +4928,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
*/
bool reliesOnTident(Type t, TemplateParameters* tparams, size_t iStart = 0)
{
- return reliesOnTemplateParameters(t, (*tparams)[0 .. tparams.dim]);
+ return reliesOnTemplateParameters(t, (*tparams)[0 .. tparams.length]);
}
/***********************************************************
@@ -5739,7 +5739,7 @@ extern (C++) final class TemplateTupleParameter : TemplateParameter
Tuple v = isTuple(oded);
assert(v);
- //printf("|%d| ", v.objects.dim);
+ //printf("|%d| ", v.objects.length);
foreach (i, o; v.objects)
{
if (i)
@@ -5901,7 +5901,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
Objects* a = null;
if (objs)
{
- a = new Objects(objs.dim);
+ a = new Objects(objs.length);
foreach (i, o; *objs)
(*a)[i] = objectSyntaxCopy(o);
}
@@ -6094,7 +6094,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
final bool equalsx(TemplateInstance ti)
{
//printf("this = %p, ti = %p\n", this, ti);
- assert(tdtypes.dim == ti.tdtypes.dim);
+ assert(tdtypes.length == ti.tdtypes.length);
// Nesting must match
if (enclosing != ti.enclosing)
@@ -6121,7 +6121,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
Parameter fparam = fparameters[j];
if (fparam.storageClass & STC.autoref) // if "auto ref"
{
- Expression farg = fargs && j < fargs.dim ? (*fargs)[j] : fparam.defaultArg;
+ Expression farg = fargs && j < fargs.length ? (*fargs)[j] : fparam.defaultArg;
if (!farg)
goto Lnotequals;
if (farg.isLvalue())
@@ -6423,7 +6423,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
// Look for forward references
auto tovers = tempdecl.isOverloadSet();
- foreach (size_t oi; 0 .. tovers ? tovers.a.dim : 1)
+ foreach (size_t oi; 0 .. tovers ? tovers.a.length : 1)
{
Dsymbol dstart = tovers ? tovers.a[oi] : tempdecl;
int r = overloadApply(dstart, (Dsymbol s)
@@ -6583,7 +6583,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
if (!tiargs)
return true;
bool err = false;
- for (size_t j = 0; j < tiargs.dim; j++)
+ for (size_t j = 0; j < tiargs.length; j++)
{
RootObject o = (*tiargs)[j];
Type ta = isType(o);
@@ -6612,7 +6612,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
{
// Expand tuple
TypeTuple tt = cast(TypeTuple)ta;
- size_t dim = tt.arguments.dim;
+ size_t dim = tt.arguments.length;
tiargs.remove(j);
if (dim)
{
@@ -6688,7 +6688,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
{
// Expand tuple
TupleExp te = cast(TupleExp)ea;
- size_t dim = te.exps.dim;
+ size_t dim = te.exps.length;
tiargs.remove(j);
if (dim)
{
@@ -6820,7 +6820,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
version (none)
{
printf("-TemplateInstance.semanticTiargs()\n");
- for (size_t j = 0; j < tiargs.dim; j++)
+ for (size_t j = 0; j < tiargs.length; j++)
{
RootObject o = (*tiargs)[j];
Type ta = isType(o);
@@ -6875,7 +6875,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
assert(tempdecl);
assert(tempdecl._scope);
// Deduce tdtypes
- tdtypes.setDim(tempdecl.parameters.dim);
+ tdtypes.setDim(tempdecl.parameters.length);
if (!tempdecl.matchWithInstance(sc, this, &tdtypes, fargs, 2))
{
error("incompatible arguments for template instantiation");
@@ -6898,7 +6898,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
* name, look for the best match.
*/
auto tovers = tempdecl.isOverloadSet();
- foreach (size_t oi; 0 .. tovers ? tovers.a.dim : 1)
+ foreach (size_t oi; 0 .. tovers ? tovers.a.length : 1)
{
TemplateDeclaration td_best;
TemplateDeclaration td_ambig;
@@ -6921,13 +6921,13 @@ extern (C++) class TemplateInstance : ScopeDsymbol
//printf("td = %s\n", td.toPrettyChars());
// If more arguments than parameters,
// then this is no match.
- if (td.parameters.dim < tiargs.dim)
+ if (td.parameters.length < tiargs.length)
{
if (!td.isVariadic())
return 0;
}
- dedtypes.setDim(td.parameters.dim);
+ dedtypes.setDim(td.parameters.length);
dedtypes.zero();
assert(td.semanticRun != PASS.initial);
@@ -6960,8 +6960,8 @@ extern (C++) class TemplateInstance : ScopeDsymbol
td_ambig = null;
td_best = td;
m_best = m;
- tdtypes.setDim(dedtypes.dim);
- memcpy(tdtypes.tdata(), dedtypes.tdata(), tdtypes.dim * (void*).sizeof);
+ tdtypes.setDim(dedtypes.length);
+ memcpy(tdtypes.tdata(), dedtypes.tdata(), tdtypes.length * (void*).sizeof);
return 0;
});
@@ -7000,12 +7000,12 @@ extern (C++) class TemplateInstance : ScopeDsymbol
* S!num s; // S!1 is instantiated, not S!num
* }
*/
- size_t dim = td_last.parameters.dim - (td_last.isVariadic() ? 1 : 0);
+ size_t dim = td_last.parameters.length - (td_last.isVariadic() ? 1 : 0);
for (size_t i = 0; i < dim; i++)
{
- if (tiargs.dim <= i)
+ if (tiargs.length <= i)
tiargs.push(tdtypes[i]);
- assert(i < tiargs.dim);
+ assert(i < tiargs.length);
auto tvp = (*td_last.parameters)[i].isTemplateValueParameter();
if (!tvp)
@@ -7015,7 +7015,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
(*tiargs)[i] = tdtypes[i];
}
- if (td_last.isVariadic() && tiargs.dim == dim && tdtypes[dim])
+ if (td_last.isVariadic() && tiargs.length == dim && tdtypes[dim])
{
Tuple va = isTuple(tdtypes[dim]);
assert(va);
@@ -7051,7 +7051,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
{
error("%s `%s`", msg, tmsg);
- if (tdecl.parameters.dim == tiargs.dim)
+ if (tdecl.parameters.length == tiargs.length)
{
// https://issues.dlang.org/show_bug.cgi?id=7352
// print additional information, e.g. `foo` is not a type
@@ -7081,7 +7081,17 @@ extern (C++) class TemplateInstance : ScopeDsymbol
}
}
else
- .error(loc, "%s `%s.%s` does not match any template declaration", tempdecl.kind(), tempdecl.parent.toPrettyChars(), tempdecl.ident.toChars());
+ {
+ .error(loc, "%s `%s` does not match any template declaration", kind(), toPrettyChars());
+ bool found;
+ overloadApply(tempdecl, (s){
+ if (!found)
+ errorSupplemental(loc, "Candidates are:");
+ found = true;
+ errorSupplemental(s.loc, "%s", s.toChars());
+ return 0;
+ });
+ }
return false;
}
@@ -7115,7 +7125,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
size_t count = 0;
auto tovers = tempdecl.isOverloadSet();
- foreach (size_t oi; 0 .. tovers ? tovers.a.dim : 1)
+ foreach (size_t oi; 0 .. tovers ? tovers.a.length : 1)
{
Dsymbol dstart = tovers ? tovers.a[oi] : tempdecl;
int r = overloadApply(dstart, (Dsymbol s)
@@ -7138,7 +7148,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
{
if (!td2.onemember || !td2.onemember.isFuncDeclaration())
return 0;
- if (tiargs.dim >= td.parameters.dim - (td.isVariadic() ? 1 : 0))
+ if (tiargs.length >= td.parameters.length - (td.isVariadic() ? 1 : 0))
return 0;
return 1;
}
@@ -7155,18 +7165,18 @@ extern (C++) class TemplateInstance : ScopeDsymbol
/* Determine if the instance arguments, tiargs, are all that is necessary
* to instantiate the template.
*/
- //printf("tp = %p, td.parameters.dim = %d, tiargs.dim = %d\n", tp, td.parameters.dim, tiargs.dim);
+ //printf("tp = %p, td.parameters.length = %d, tiargs.length = %d\n", tp, td.parameters.length, tiargs.length);
auto tf = cast(TypeFunction)fd.type;
if (tf.parameterList.length)
{
auto tp = td.isVariadic();
- if (tp && td.parameters.dim > 1)
+ if (tp && td.parameters.length > 1)
return 1;
- if (!tp && tiargs.dim < td.parameters.dim)
+ if (!tp && tiargs.length < td.parameters.length)
{
// Can remain tiargs be filled by default arguments?
- foreach (size_t i; tiargs.dim .. td.parameters.dim)
+ foreach (size_t i; tiargs.length .. td.parameters.length)
{
if (!(*td.parameters)[i].hasDefaultArg())
return 1;
@@ -7186,7 +7196,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
/* Calculate the need for overload resolution.
* When only one template can match with tiargs, inference is not necessary.
*/
- dedtypes.setDim(td.parameters.dim);
+ dedtypes.setDim(td.parameters.length);
dedtypes.zero();
if (td.semanticRun == PASS.initial)
{
@@ -7653,7 +7663,7 @@ extern (C++) final class TemplateMixin : TemplateInstance
extern (D) this(const ref Loc loc, Identifier ident, TypeQualified tqual, Objects* tiargs)
{
super(loc,
- tqual.idents.dim ? cast(Identifier)tqual.idents[tqual.idents.dim - 1] : (cast(TypeIdentifier)tqual).ident,
+ tqual.idents.length ? cast(Identifier)tqual.idents[tqual.idents.length - 1] : (cast(TypeIdentifier)tqual).ident,
tiargs ? tiargs : new Objects());
//printf("TemplateMixin(ident = '%s')\n", ident ? ident.toChars() : "");
this.ident = ident;
@@ -7745,7 +7755,7 @@ extern (C++) final class TemplateMixin : TemplateInstance
// Look for forward references
auto tovers = tempdecl.isOverloadSet();
- foreach (size_t oi; 0 .. tovers ? tovers.a.dim : 1)
+ foreach (size_t oi; 0 .. tovers ? tovers.a.length : 1)
{
Dsymbol dstart = tovers ? tovers.a[oi] : tempdecl;
int r = overloadApply(dstart, (Dsymbol s)
@@ -7865,7 +7875,7 @@ MATCH matchArg(TemplateParameter tp, Loc instLoc, Scope* sc, Objects* tiargs, si
{
RootObject oarg;
- if (i < tiargs.dim)
+ if (i < tiargs.length)
oarg = (*tiargs)[i];
else
{
@@ -7873,7 +7883,7 @@ MATCH matchArg(TemplateParameter tp, Loc instLoc, Scope* sc, Objects* tiargs, si
oarg = tp.defaultArg(instLoc, sc);
if (!oarg)
{
- assert(i < dedtypes.dim);
+ assert(i < dedtypes.length);
// It might have already been deduced
oarg = (*dedtypes)[i];
if (!oarg)
@@ -7888,7 +7898,7 @@ MATCH matchArg(TemplateParameter tp, Loc instLoc, Scope* sc, Objects* tiargs, si
/* The rest of the actual arguments (tiargs[]) form the match
* for the variadic parameter.
*/
- assert(i + 1 == dedtypes.dim); // must be the last one
+ assert(i + 1 == dedtypes.length); // must be the last one
Tuple ovar;
if (Tuple u = isTuple((*dedtypes)[i]))
@@ -7896,16 +7906,16 @@ MATCH matchArg(TemplateParameter tp, Loc instLoc, Scope* sc, Objects* tiargs, si
// It has already been deduced
ovar = u;
}
- else if (i + 1 == tiargs.dim && isTuple((*tiargs)[i]))
+ else if (i + 1 == tiargs.length && isTuple((*tiargs)[i]))
ovar = isTuple((*tiargs)[i]);
else
{
ovar = new Tuple();
//printf("ovar = %p\n", ovar);
- if (i < tiargs.dim)
+ if (i < tiargs.length)
{
- //printf("i = %d, tiargs.dim = %d\n", i, tiargs.dim);
- ovar.objects.setDim(tiargs.dim - i);
+ //printf("i = %d, tiargs.length = %d\n", i, tiargs.length);
+ ovar.objects.setDim(tiargs.length - i);
foreach (j, ref obj; ovar.objects)
obj = (*tiargs)[i + j];
}
diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d
index c570068..432e88d 100644
--- a/gcc/d/dmd/dtoh.d
+++ b/gcc/d/dmd/dtoh.d
@@ -1945,7 +1945,7 @@ public:
}
if (tf.parameterList.varargs)
{
- if (tf.parameterList.parameters.dim && tf.parameterList.varargs == 1)
+ if (tf.parameterList.parameters.length && tf.parameterList.varargs == 1)
buf.writestring(", ");
buf.writestring("...");
}
@@ -2280,7 +2280,7 @@ public:
}
if (tf.parameterList.varargs)
{
- if (tf.parameterList.parameters.dim && tf.parameterList.varargs == 1)
+ if (tf.parameterList.parameters.length && tf.parameterList.varargs == 1)
buf.writestring(", ");
buf.writestring("...");
}
diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d
index e7626b0..24a428b 100644
--- a/gcc/d/dmd/escape.d
+++ b/gcc/d/dmd/escape.d
@@ -328,7 +328,7 @@ void printScopeFailure(E)(E printFunc, VarDeclaration v, int recursionLimit)
* Params:
* sc = used to determine current function and module
* fdc = function being called, `null` if called indirectly
- * par = function parameter (`this` if null)
+ * parId = name of function parameter for error messages
* vPar = `VarDeclaration` corresponding to `par`
* parStc = storage classes of function parameter (may have added `scope` from `pure`)
* arg = initializer for param
@@ -337,12 +337,12 @@ void printScopeFailure(E)(E printFunc, VarDeclaration v, int recursionLimit)
* Returns:
* `true` if pointers to the stack can escape via assignment
*/
-bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Parameter par, VarDeclaration vPar, STC parStc, Expression arg, bool assertmsg, bool gag)
+bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId, VarDeclaration vPar, STC parStc, Expression arg, bool assertmsg, bool gag)
{
enum log = false;
if (log) printf("checkParamArgumentEscape(arg: %s par: %s)\n",
arg ? arg.toChars() : "null",
- par ? par.toChars() : "this");
+ parId ? parId.toChars() : "null");
//printf("type = %s, %d\n", arg.type.toChars(), arg.type.hasPointers());
if (!arg.type.hasPointers())
@@ -361,7 +361,7 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Parameter par, Var
er.byexp.setDim(0);
}
- if (!er.byref.dim && !er.byvalue.dim && !er.byfunc.dim && !er.byexp.dim)
+ if (!er.byref.length && !er.byvalue.length && !er.byfunc.length && !er.byexp.length)
return false;
bool result = false;
@@ -374,24 +374,18 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Parameter par, Var
{
result |= sc.setUnsafeDIP1000(gag, arg.loc,
desc ~ " `%s` assigned to non-scope parameter calling `assert()`", v);
+ return;
}
- else if (par)
- {
- if (sc.setUnsafeDIP1000(gag, arg.loc,
- desc ~ " `%s` assigned to non-scope parameter `%s` calling `%s`", v, par, fdc))
- {
- result = true;
- printScopeFailure(previewSupplementalFunc(sc.isDeprecated(), global.params.useDIP1000), vPar, 10);
- }
- }
- else
+ const(char)* msg =
+ (fdc && parId) ? (desc ~ " `%s` assigned to non-scope parameter `%s` calling `%s`") :
+ (fdc && !parId) ? (desc ~ " `%s` assigned to non-scope anonymous parameter calling `%s`") :
+ (!fdc && parId) ? (desc ~ " `%s` assigned to non-scope parameter `%s`") :
+ (desc ~ " `%s` assigned to non-scope anonymous parameter");
+
+ if (sc.setUnsafeDIP1000(gag, arg.loc, msg, v, parId ? parId : fdc, fdc))
{
- if (sc.setUnsafeDIP1000(gag, arg.loc,
- desc ~ " `%s` assigned to non-scope parameter `this` calling `%s`", v, fdc))
- {
- result = true;
- printScopeFailure(previewSupplementalFunc(sc.isDeprecated(), global.params.useDIP1000), fdc.vthis, 10);
- }
+ result = true;
+ printScopeFailure(previewSupplementalFunc(sc.isDeprecated(), global.params.useDIP1000), vPar, 10);
}
}
@@ -465,16 +459,11 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Parameter par, Var
foreach (Expression ee; er.byexp)
{
- if (!par)
- {
- result |= sc.setUnsafeDIP1000(gag, ee.loc,
- "reference to stack allocated value returned by `%s` assigned to non-scope parameter `this`", ee);
- }
- else
- {
- result |= sc.setUnsafeDIP1000(gag, ee.loc,
- "reference to stack allocated value returned by `%s` assigned to non-scope parameter `%s`", ee, par);
- }
+ const(char)* msg = parId ?
+ "reference to stack allocated value returned by `%s` assigned to non-scope parameter `%s`" :
+ "reference to stack allocated value returned by `%s` assigned to non-scope anonymous parameter";
+
+ result |= sc.setUnsafeDIP1000(gag, ee.loc, msg, ee, parId);
}
return result;
@@ -537,7 +526,7 @@ bool checkConstructorEscape(Scope* sc, CallExp ce, bool gag)
if (!tthis.hasPointers())
return false;
- if (!ce.arguments && ce.arguments.dim)
+ if (!ce.arguments && ce.arguments.length)
return false;
DotVarExp dve = ce.e1.isDotVarExp();
@@ -545,7 +534,7 @@ bool checkConstructorEscape(Scope* sc, CallExp ce, bool gag)
TypeFunction tf = ctor.type.isTypeFunction();
const nparams = tf.parameterList.length;
- const n = ce.arguments.dim;
+ const n = ce.arguments.length;
// j=1 if _arguments[] is first argument
const j = tf.isDstyleVariadic();
@@ -625,7 +614,7 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef)
else
escapeByValue(e2, &er);
- if (!er.byref.dim && !er.byvalue.dim && !er.byfunc.dim && !er.byexp.dim)
+ if (!er.byref.length && !er.byvalue.length && !er.byfunc.length && !er.byexp.length)
return false;
VarDeclaration va = expToVariable(e1);
@@ -959,7 +948,7 @@ bool checkThrowEscape(Scope* sc, Expression e, bool gag)
escapeByValue(e, &er);
- if (!er.byref.dim && !er.byvalue.dim && !er.byexp.dim)
+ if (!er.byref.length && !er.byvalue.length && !er.byexp.length)
return false;
bool result = false;
@@ -1007,7 +996,7 @@ bool checkNewEscape(Scope* sc, Expression e, bool gag)
escapeByValue(e, &er);
- if (!er.byref.dim && !er.byvalue.dim && !er.byexp.dim)
+ if (!er.byref.length && !er.byvalue.length && !er.byexp.length)
return false;
bool result = false;
@@ -1187,7 +1176,7 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
else
escapeByValue(e, &er);
- if (!er.byref.dim && !er.byvalue.dim && !er.byexp.dim)
+ if (!er.byref.length && !er.byvalue.length && !er.byexp.length)
return false;
bool result = false;
@@ -1739,13 +1728,13 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re
if (!e.type.hasPointers())
return;
- if (e.arguments && e.arguments.dim)
+ if (e.arguments && e.arguments.length)
{
/* j=1 if _arguments[] is first argument,
* skip it because it is not passed by ref
*/
int j = tf.isDstyleVariadic();
- for (size_t i = j; i < e.arguments.dim; ++i)
+ for (size_t i = j; i < e.arguments.length; ++i)
{
Expression arg = (*e.arguments)[i];
size_t nparams = tf.parameterList.length;
@@ -2048,13 +2037,13 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR
return;
if (tf.isref)
{
- if (e.arguments && e.arguments.dim)
+ if (e.arguments && e.arguments.length)
{
/* j=1 if _arguments[] is first argument,
* skip it because it is not passed by ref
*/
int j = tf.isDstyleVariadic();
- for (size_t i = j; i < e.arguments.dim; ++i)
+ for (size_t i = j; i < e.arguments.length; ++i)
{
Expression arg = (*e.arguments)[i];
size_t nparams = tf.parameterList.length;
@@ -2323,7 +2312,7 @@ void finishScopeParamInference(FuncDeclaration funcdecl, ref TypeFunction f)
{
// Create and fill array[] with maybe candidates from the `this` and the parameters
VarDeclaration[10] tmp = void;
- size_t dim = (funcdecl.vthis !is null) + (funcdecl.parameters ? funcdecl.parameters.dim : 0);
+ size_t dim = (funcdecl.vthis !is null) + (funcdecl.parameters ? funcdecl.parameters.length : 0);
import dmd.common.string : SmallBuffer;
auto sb = SmallBuffer!VarDeclaration(dim, tmp[]);
@@ -2345,7 +2334,7 @@ void finishScopeParamInference(FuncDeclaration funcdecl, ref TypeFunction f)
// Infer STC.scope_
if (funcdecl.parameters && !funcdecl.errors)
{
- assert(f.parameterList.length == funcdecl.parameters.dim);
+ assert(f.parameterList.length == funcdecl.parameters.length);
foreach (u, p; f.parameterList)
{
auto v = (*funcdecl.parameters)[u];
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 21f5cc7..4f14d66 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -260,7 +260,7 @@ extern (C++) void expandTuples(Expressions* exps)
if (exps is null)
return;
- for (size_t i = 0; i < exps.dim; i++)
+ for (size_t i = 0; i < exps.length; i++)
{
Expression arg = (*exps)[i];
if (!arg)
@@ -271,10 +271,10 @@ extern (C++) void expandTuples(Expressions* exps)
{
if (auto tt = e.type.toBasetype().isTypeTuple())
{
- if (!tt.arguments || tt.arguments.dim == 0)
+ if (!tt.arguments || tt.arguments.length == 0)
{
exps.remove(i);
- if (i == exps.dim)
+ if (i == exps.length)
return;
}
else // Expand a TypeTuple
@@ -296,7 +296,7 @@ extern (C++) void expandTuples(Expressions* exps)
TupleExp te = cast(TupleExp)arg;
exps.remove(i); // remove arg
exps.insert(i, te.exps); // replace with tuple contents
- if (i == exps.dim)
+ if (i == exps.length)
return; // empty tuple, no more arguments
(*exps)[i] = Expression.combine(te.e0, (*exps)[i]);
arg = (*exps)[i];
@@ -339,10 +339,10 @@ TupleDeclaration isAliasThisTuple(Expression e)
int expandAliasThisTuples(Expressions* exps, size_t starti = 0)
{
- if (!exps || exps.dim == 0)
+ if (!exps || exps.length == 0)
return -1;
- for (size_t u = starti; u < exps.dim; u++)
+ for (size_t u = starti; u < exps.length; u++)
{
Expression exp = (*exps)[u];
if (TupleDeclaration td = exp.isAliasThisTuple)
@@ -924,7 +924,7 @@ extern (C++) abstract class Expression : ASTNode
Expressions* a = null;
if (exps)
{
- a = new Expressions(exps.dim);
+ a = new Expressions(exps.length);
foreach (i, e; *exps)
{
(*a)[i] = e ? e.syntaxCopy() : null;
@@ -1214,7 +1214,7 @@ extern (C++) abstract class Expression : ASTNode
auto ad = cast(AggregateDeclaration) f.toParent2();
assert(ad);
- if (ad.userDtors.dim)
+ if (ad.userDtors.length)
{
if (!check(ad.userDtors[0])) // doesn't match check (e.g. is impure as well)
return;
@@ -1401,14 +1401,32 @@ extern (C++) abstract class Expression : ASTNode
*/
extern (D) final bool checkSafety(Scope* sc, FuncDeclaration f)
{
- if (!sc.func)
- return false;
if (sc.func == f)
return false;
if (sc.intypeof == 1)
return false;
- if (sc.flags & (SCOPE.ctfe | SCOPE.debug_))
+ if (sc.flags & SCOPE.debug_)
return false;
+ if ((sc.flags & SCOPE.ctfe) && sc.func)
+ return false;
+
+ if (!sc.func)
+ {
+ if (sc.varDecl && !f.safetyInprocess && !f.isSafe() && !f.isTrusted())
+ {
+ if (sc.varDecl.storage_class & STC.safe)
+ {
+ error("`@safe` variable `%s` cannot be initialized by calling `@system` function `%s`",
+ sc.varDecl.toChars(), f.toChars());
+ return true;
+ }
+ else
+ {
+ sc.varDecl.storage_class |= STC.system;
+ }
+ }
+ return false;
+ }
if (!f.isSafe() && !f.isTrusted())
{
@@ -2867,7 +2885,7 @@ extern (C++) final class TupleExp : Expression
super(loc, EXP.tuple, __traits(classInstanceSize, TupleExp));
this.exps = new Expressions();
- this.exps.reserve(tup.objects.dim);
+ this.exps.reserve(tup.objects.length);
foreach (o; *tup.objects)
{
if (Dsymbol s = getDsymbol(o))
@@ -2913,7 +2931,7 @@ extern (C++) final class TupleExp : Expression
if (auto e = o.isExpression())
if (auto te = e.isTupleExp())
{
- if (exps.dim != te.exps.dim)
+ if (exps.length != te.exps.length)
return false;
if (e0 && !e0.equals(te.e0) || !e0 && te.e0)
return false;
@@ -3002,9 +3020,9 @@ extern (C++) final class ArrayLiteralExp : Expression
return false;
if (auto ae = e.isArrayLiteralExp())
{
- if (elements.dim != ae.elements.dim)
+ if (elements.length != ae.elements.length)
return false;
- if (elements.dim == 0 && !type.equals(ae.type))
+ if (elements.length == 0 && !type.equals(ae.type))
{
return false;
}
@@ -3036,14 +3054,14 @@ extern (C++) final class ArrayLiteralExp : Expression
override Optional!bool toBool()
{
- size_t dim = elements ? elements.dim : 0;
+ size_t dim = elements ? elements.length : 0;
return typeof(return)(dim != 0);
}
override StringExp toStringExp()
{
TY telem = type.nextOf().toBasetype().ty;
- if (telem.isSomeChar || (telem == Tvoid && (!elements || elements.dim == 0)))
+ if (telem.isSomeChar || (telem == Tvoid && (!elements || elements.length == 0)))
{
ubyte sz = 1;
if (telem == Twchar)
@@ -3054,7 +3072,7 @@ extern (C++) final class ArrayLiteralExp : Expression
OutBuffer buf;
if (elements)
{
- foreach (i; 0 .. elements.dim)
+ foreach (i; 0 .. elements.length)
{
auto ch = this[i];
if (ch.op != EXP.int64)
@@ -3114,7 +3132,7 @@ extern (C++) final class AssocArrayLiteralExp : Expression
extern (D) this(const ref Loc loc, Expressions* keys, Expressions* values)
{
super(loc, EXP.assocArrayLiteral, __traits(classInstanceSize, AssocArrayLiteralExp));
- assert(keys.dim == values.dim);
+ assert(keys.length == values.length);
this.keys = keys;
this.values = values;
}
@@ -3128,7 +3146,7 @@ extern (C++) final class AssocArrayLiteralExp : Expression
return false;
if (auto ae = e.isAssocArrayLiteralExp())
{
- if (keys.dim != ae.keys.dim)
+ if (keys.length != ae.keys.length)
return false;
size_t count = 0;
foreach (i, key; *keys)
@@ -3143,7 +3161,7 @@ extern (C++) final class AssocArrayLiteralExp : Expression
}
}
}
- return count == keys.dim;
+ return count == keys.length;
}
return false;
}
@@ -3155,7 +3173,7 @@ extern (C++) final class AssocArrayLiteralExp : Expression
override Optional!bool toBool()
{
- size_t dim = keys.dim;
+ size_t dim = keys.length;
return typeof(return)(dim != 0);
}
@@ -3232,7 +3250,7 @@ extern (C++) final class StructLiteralExp : Expression
{
if (!type.equals(se.type))
return false;
- if (elements.dim != se.elements.dim)
+ if (elements.length != se.elements.length)
return false;
foreach (i, e1; *elements)
{
@@ -3269,7 +3287,7 @@ extern (C++) final class StructLiteralExp : Expression
if (i >= sd.nonHiddenFields())
return null;
- assert(i < elements.dim);
+ assert(i < elements.length);
e = (*elements)[i];
if (e)
{
@@ -3310,7 +3328,7 @@ extern (C++) final class StructLiteralExp : Expression
{
/* Find which field offset is by looking at the field offsets
*/
- if (elements.dim)
+ if (elements.length)
{
const sz = type.size();
if (sz == SIZE_INVALID)
@@ -3797,7 +3815,7 @@ extern (C++) final class FuncExp : Expression
if (td)
{
assert(td.literal);
- assert(td.members && td.members.dim == 1);
+ assert(td.members && td.members.length == 1);
fd = (*td.members)[0].isFuncLiteralDeclaration();
}
tok = fd.tok; // save original kind of function/delegate/(infer)
@@ -3928,7 +3946,7 @@ extern (C++) final class FuncExp : Expression
return cannotInfer(this, to, flag);
auto tiargs = new Objects();
- tiargs.reserve(td.parameters.dim);
+ tiargs.reserve(td.parameters.length);
foreach (tp; *td.parameters)
{
@@ -4211,7 +4229,7 @@ extern (C++) final class IsExp : Expression
TemplateParameters* p = null;
if (parameters)
{
- p = new TemplateParameters(parameters.dim);
+ p = new TemplateParameters(parameters.length);
foreach (i, el; *parameters)
(*p)[i] = el.syntaxCopy();
}
@@ -4655,7 +4673,7 @@ extern (C++) final class MixinExp : Expression
return false;
if (auto ce = e.isMixinExp())
{
- if (exps.dim != ce.exps.dim)
+ if (exps.length != ce.exps.length)
return false;
foreach (i, e1; *exps)
{
@@ -4846,7 +4864,7 @@ extern (C++) final class DotVarExp : UnaExp
if (VarDeclaration vd = var.isVarDeclaration())
{
auto ad = vd.isMember2();
- if (ad && ad.fields.dim == sc.ctorflow.fieldinit.length)
+ if (ad && ad.fields.length == sc.ctorflow.fieldinit.length)
{
foreach (i, f; ad.fields)
{
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index f899bd7..60b51cb 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -220,7 +220,7 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, Expression* pe0)
if (e.op == EXP.interval && !(slice && slice.isTemplateDeclaration()))
{
Lfallback:
- if (ae.arguments.dim == 1)
+ if (ae.arguments.length == 1)
return null;
ae.error("multi-dimensional slicing requires template `opSlice`");
return ErrorExp.get();
@@ -534,7 +534,7 @@ private Expression resolveUFCS(Scope* sc, CallExp ce)
/* Transform:
* aa.remove(arg) into delete aa[arg]
*/
- if (!ce.arguments || ce.arguments.dim != 1)
+ if (!ce.arguments || ce.arguments.length != 1)
{
ce.error("expected key as argument to `aa.remove()`");
return ErrorExp.get();
@@ -1189,7 +1189,7 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
Expressions a;
a.push(e2);
- for (size_t i = 0; i < os.a.dim; i++)
+ for (size_t i = 0; i < os.a.length; i++)
{
if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, &a, FuncResolveFlag.quiet))
{
@@ -1206,7 +1206,7 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
}
}
{
- for (size_t i = 0; i < os.a.dim; i++)
+ for (size_t i = 0; i < os.a.length; i++)
{
if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, null, FuncResolveFlag.quiet))
{
@@ -1439,7 +1439,7 @@ private Type arrayExpressionToCommonType(Scope* sc, ref Expressions exps)
Expression e0 = null;
bool foundType;
- for (size_t i = 0; i < exps.dim; i++)
+ for (size_t i = 0; i < exps.length; i++)
{
Expression e = exps[i];
if (!e)
@@ -1506,7 +1506,7 @@ private Type arrayExpressionToCommonType(Scope* sc, ref Expressions exps)
if (t0.ty == Terror)
return null;
- for (size_t i = 0; i < exps.dim; i++)
+ for (size_t i = 0; i < exps.length; i++)
{
Expression e = exps[i];
if (!e)
@@ -1633,7 +1633,7 @@ private bool preFunctionParameters(Scope* sc, Expressions* exps, const bool repo
{
expandTuples(exps);
- for (size_t i = 0; i < exps.dim; i++)
+ for (size_t i = 0; i < exps.length; i++)
{
Expression arg = (*exps)[i];
arg = resolveProperties(sc, arg);
@@ -1721,7 +1721,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
//printf("functionParameters() %s\n", fd ? fd.toChars() : "");
assert(arguments);
assert(fd || tf.next);
- size_t nargs = arguments ? arguments.dim : 0;
+ size_t nargs = arguments ? arguments.length : 0;
const size_t nparams = tf.parameterList.length;
const olderrors = global.errors;
bool err = false;
@@ -1843,7 +1843,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
Type tret = p.isLazyArray();
auto elements = new Expressions(nargs - i);
- foreach (u; 0 .. elements.dim)
+ foreach (u; 0 .. elements.length)
{
Expression a = (*arguments)[i + u];
if (tret && a.implicitConvTo(tret))
@@ -2085,7 +2085,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
* Check arg to see if it matters.
*/
VarDeclaration vPar = fd ? (fd.parameters ? (*fd.parameters)[i] : null) : null;
- err |= checkParamArgumentEscape(sc, fd, p, vPar, cast(STC) pStc, arg, false, false);
+ err |= checkParamArgumentEscape(sc, fd, p.ident, vPar, cast(STC) pStc, arg, false, false);
}
// Turning heap allocations into stack allocations is dangerous without dip1000, since `scope` inference
@@ -2451,10 +2451,10 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
// If D linkage and variadic, add _arguments[] as first argument
if (tf.isDstyleVariadic())
{
- assert(arguments.dim >= nparams);
+ assert(arguments.length >= nparams);
- auto args = new Parameters(arguments.dim - nparams);
- for (size_t i = 0; i < arguments.dim - nparams; i++)
+ auto args = new Parameters(arguments.length - nparams);
+ for (size_t i = 0; i < arguments.length - nparams; i++)
{
auto arg = new Parameter(STC.in_, (*arguments)[nparams + i].type, null, null, null);
(*args)[i] = arg;
@@ -3109,7 +3109,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// Run semantic() on each argument
bool err = false;
- for (size_t i = 0; i < exp.exps.dim; i++)
+ for (size_t i = 0; i < exp.exps.length; i++)
{
Expression e = (*exp.exps)[i];
e = e.expressionSemantic(sc);
@@ -3169,7 +3169,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
/* Disallow array literals of type void being used.
*/
- if (e.elements.dim > 0 && t0.ty == Tvoid)
+ if (e.elements.length > 0 && t0.ty == Tvoid)
{
e.error("`%s` of type `%s` has no value", e.toChars(), e.type.toChars());
return setError();
@@ -3201,10 +3201,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
expandTuples(e.keys);
expandTuples(e.values);
- if (e.keys.dim != e.values.dim)
+ if (e.keys.length != e.values.length)
{
e.error("number of keys is %llu, must match number of values %llu",
- cast(ulong) e.keys.dim, cast(ulong) e.values.dim);
+ cast(ulong) e.keys.length, cast(ulong) e.values.length);
return setError();
}
@@ -3263,7 +3263,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return setError();
}
- if (checkFrameAccess(e.loc, sc, e.sd, e.elements.dim))
+ if (checkFrameAccess(e.loc, sc, e.sd, e.elements.length))
return setError();
e.type = e.stype ? e.stype : e.sd.type;
@@ -3579,7 +3579,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return setError();
}
- const size_t nargs = exp.arguments ? exp.arguments.dim : 0;
+ const size_t nargs = exp.arguments ? exp.arguments.length : 0;
Expression newprefix = null;
if (auto tc = tb.isTypeClass())
@@ -3605,7 +3605,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (cd.isAbstract())
{
exp.error("cannot create instance of abstract class `%s`", cd.toChars());
- for (size_t i = 0; i < cd.vtbl.dim; i++)
+ for (size_t i = 0; i < cd.vtbl.length; i++)
{
FuncDeclaration fd = cd.vtbl[i].isFuncDeclaration();
if (fd && fd.isAbstract())
@@ -3836,7 +3836,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
exp.member = f.isCtorDeclaration();
assert(exp.member);
- if (checkFrameAccess(exp.loc, sc, sd, sd.fields.dim))
+ if (checkFrameAccess(exp.loc, sc, sd, sd.fields.length))
return setError();
}
else
@@ -3850,7 +3850,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!sd.fill(exp.loc, *exp.arguments, false))
return setError();
- if (checkFrameAccess(exp.loc, sc, sd, exp.arguments ? exp.arguments.dim : 0))
+ if (checkFrameAccess(exp.loc, sc, sd, exp.arguments ? exp.arguments.length : 0))
return setError();
/* Since a `new` allocation may escape, check each of the arguments for escaping
@@ -4113,7 +4113,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
//printf("td = %p, treq = %p\n", td, fd.treq);
if (exp.td)
{
- assert(exp.td.parameters && exp.td.parameters.dim);
+ assert(exp.td.parameters && exp.td.parameters.length);
exp.td.dsymbolSemantic(sc);
exp.type = Type.tvoid; // temporary type
@@ -4199,9 +4199,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
*/
Expression callExpSemantic(FuncExp exp, Scope* sc, Expressions* arguments)
{
- if ((!exp.type || exp.type == Type.tvoid) && exp.td && arguments && arguments.dim)
+ if ((!exp.type || exp.type == Type.tvoid) && exp.td && arguments && arguments.length)
{
- for (size_t k = 0; k < arguments.dim; k++)
+ for (size_t k = 0; k < arguments.length; k++)
{
Expression checkarg = (*arguments)[k];
if (checkarg.op == EXP.error)
@@ -4210,21 +4210,21 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
exp.genIdent(sc);
- assert(exp.td.parameters && exp.td.parameters.dim);
+ assert(exp.td.parameters && exp.td.parameters.length);
exp.td.dsymbolSemantic(sc);
TypeFunction tfl = cast(TypeFunction)exp.fd.type;
size_t dim = tfl.parameterList.length;
- if (arguments.dim < dim)
+ if (arguments.length < dim)
{
// Default arguments are always typed, so they don't need inference.
- Parameter p = tfl.parameterList[arguments.dim];
+ Parameter p = tfl.parameterList[arguments.length];
if (p.defaultArg)
- dim = arguments.dim;
+ dim = arguments.length;
}
- if ((tfl.parameterList.varargs == VarArg.none && arguments.dim > dim) ||
- arguments.dim < dim)
+ if ((tfl.parameterList.varargs == VarArg.none && arguments.length > dim) ||
+ arguments.length < dim)
{
OutBuffer buf;
foreach (idx, ref arg; *arguments)
@@ -4232,16 +4232,16 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
exp.error("function literal `%s%s` is not callable using argument types `(%s)`",
exp.fd.toChars(), parametersTypeToChars(tfl.parameterList),
buf.peekChars());
- exp.errorSupplemental("too %s arguments, expected `%d`, got `%d`",
- arguments.dim < dim ? "few".ptr : "many".ptr,
- cast(int)dim, cast(int)arguments.dim);
+ exp.errorSupplemental("too %s arguments, expected %d, got %d",
+ arguments.length < dim ? "few".ptr : "many".ptr,
+ cast(int)dim, cast(int)arguments.length);
return ErrorExp.get();
}
auto tiargs = new Objects();
- tiargs.reserve(exp.td.parameters.dim);
+ tiargs.reserve(exp.td.parameters.length);
- for (size_t i = 0; i < exp.td.parameters.dim; i++)
+ for (size_t i = 0; i < exp.td.parameters.length; i++)
{
TemplateParameter tp = (*exp.td.parameters)[i];
assert(dim <= tfl.parameterList.length);
@@ -4571,7 +4571,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// First look for constructor
if (exp.e1.op == EXP.type && sd.ctor)
{
- if (!sd.noDefaultCtor && !(exp.arguments && exp.arguments.dim))
+ if (!sd.noDefaultCtor && !(exp.arguments && exp.arguments.length))
goto Lx;
/* https://issues.dlang.org/show_bug.cgi?id=20695
@@ -4587,7 +4587,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
auto sle = new StructLiteralExp(exp.loc, sd, null, exp.e1.type);
if (!sd.fill(exp.loc, *sle.elements, true))
return setError();
- if (checkFrameAccess(exp.loc, sc, sd, sle.elements.dim))
+ if (checkFrameAccess(exp.loc, sc, sd, sle.elements.length))
return setError();
// https://issues.dlang.org/show_bug.cgi?id=14556
@@ -4664,11 +4664,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
t1 = exp.e1.type;
}
- if (!exp.arguments || exp.arguments.dim == 0)
+ if (!exp.arguments || exp.arguments.length == 0)
{
e = t1.defaultInitLiteral(exp.loc);
}
- else if (exp.arguments.dim == 1)
+ else if (exp.arguments.length == 1)
{
e = (*exp.arguments)[0];
if (!e.type.isTypeNoreturn())
@@ -4685,7 +4685,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
}
- static FuncDeclaration resolveOverloadSet(Loc loc, Scope* sc,
+ FuncDeclaration resolveOverloadSet(Loc loc, Scope* sc,
OverloadSet os, Objects* tiargs, Type tthis, Expressions* arguments)
{
FuncDeclaration f = null;
@@ -4709,7 +4709,21 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
}
if (!f)
- .error(loc, "no overload matches for `%s`", os.toChars());
+ {
+ .error(loc, "no overload matches for `%s`", exp.toChars());
+ errorSupplemental(loc, "Candidates are:");
+ foreach (s; os.a)
+ {
+ overloadApply(s, (ds){
+ if (auto fd = ds.isFuncDeclaration())
+ .errorSupplemental(ds.loc, "%s%s", fd.toChars(),
+ fd.type.toTypeFunction().parameterList.parametersTypeToChars());
+ else
+ .errorSupplemental(ds.loc, "%s", ds.toChars());
+ return 0;
+ });
+ }
+ }
else if (f.errors)
f = null;
return f;
@@ -4751,7 +4765,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
auto ad2 = b.sym;
ue.e1 = ue.e1.castTo(sc, ad2.type.addMod(ue.e1.type.mod));
ue.e1 = ue.e1.expressionSemantic(sc);
- auto vi = exp.f.findVtblIndex(&ad2.vtbl, cast(int)ad2.vtbl.dim);
+ auto vi = exp.f.findVtblIndex(&ad2.vtbl, cast(int)ad2.vtbl.length);
assert(vi >= 0);
exp.f = ad2.vtbl[vi].isFuncDeclaration();
assert(exp.f);
@@ -4769,7 +4783,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
tthis = ue.e1.type;
if (!(exp.f.type.ty == Tfunction && (cast(TypeFunction)exp.f.type).isScopeQual))
{
- if (checkParamArgumentEscape(sc, exp.f, null, null, STC.undefined_, ethis, false, false))
+ if (checkParamArgumentEscape(sc, exp.f, Id.This, exp.f.vthis, STC.undefined_, ethis, false, false))
return setError();
}
}
@@ -5283,7 +5297,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
AttribDeclaration ad = s.isAttribDeclaration();
if (ad)
{
- if (ad.decl && ad.decl.dim == 1)
+ if (ad.decl && ad.decl.length == 1)
{
s = (*ad.decl)[0];
continue;
@@ -5683,10 +5697,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
ClassDeclaration cd = (cast(TypeClass)e.targ).sym;
auto args = new Parameters();
- args.reserve(cd.baseclasses.dim);
+ args.reserve(cd.baseclasses.length);
if (cd.semanticRun < PASS.semanticdone)
cd.dsymbolSemantic(null);
- for (size_t i = 0; i < cd.baseclasses.dim; i++)
+ for (size_t i = 0; i < cd.baseclasses.length; i++)
{
BaseClass* b = (*cd.baseclasses)[i];
args.push(new Parameter(STC.in_, b.type, null, null, null));
@@ -5775,7 +5789,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return yes();
return no();
}
- else if (e.tspec && !e.id && !(e.parameters && e.parameters.dim))
+ else if (e.tspec && !e.id && !(e.parameters && e.parameters.length))
{
/* Evaluate to true if targ matches tspec
* is(targ == tspec)
@@ -5833,7 +5847,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
Identifier tid = e.id ? e.id : Identifier.generateId("__isexp_id");
e.parameters.insert(0, new TemplateTypeParameter(e.loc, tid, null, null));
- Objects dedtypes = Objects(e.parameters.dim);
+ Objects dedtypes = Objects(e.parameters.length);
dedtypes.zero();
MATCH m = deduceType(e.targ, sc, e.tspec, e.parameters, &dedtypes, null, 0, e.tok == TOK.equal);
@@ -5853,7 +5867,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
/* Declare trailing parameters
*/
- for (size_t i = 1; i < e.parameters.dim; i++)
+ for (size_t i = 1; i < e.parameters.length; i++)
{
TemplateParameter tp = (*e.parameters)[i];
Declaration s = null;
@@ -6502,13 +6516,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
result = expressionSemantic(e, sc);
return;
}
- }
- if (exp.arrow) // ImportC only
- exp.e1 = exp.e1.expressionSemantic(sc).arrayFuncConv(sc);
+ if (exp.arrow) // ImportC only
+ exp.e1 = exp.e1.expressionSemantic(sc).arrayFuncConv(sc);
- if (sc.flags & SCOPE.Cfile)
- {
if (exp.ident == Id.__xalignof && exp.e1.isTypeExp())
{
// C11 6.5.3 says _Alignof only applies to types
@@ -6538,12 +6549,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
assert(0);
return;
}
- }
- if (sc.flags & SCOPE.Cfile && exp.ident != Id.__sizeof)
- {
- result = fieldLookup(exp.e1, sc, exp.ident);
- return;
+ if (exp.ident != Id.__sizeof)
+ {
+ result = fieldLookup(exp.e1, sc, exp.ident);
+ return;
+ }
}
Expression e = exp.semanticY(sc, 1);
@@ -6618,8 +6629,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
Expression ev = sc.func ? extractSideEffect(sc, "__tup", e0, exp.e1) : exp.e1;
auto exps = new Expressions();
- exps.reserve(tup.objects.dim);
- for (size_t i = 0; i < tup.objects.dim; i++)
+ exps.reserve(tup.objects.length);
+ for (size_t i = 0; i < tup.objects.length; i++)
{
RootObject o = (*tup.objects)[i];
Expression e;
@@ -7560,7 +7571,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
}
TupleExp te = exp.e1.isTupleExp();
- if (te.exps.dim == 1)
+ if (te.exps.length == 1)
exp.e1 = (*te.exps)[0];
}
@@ -7646,14 +7657,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// Check for unsafe casts
if (!isSafeCast(ex, t1b, tob))
{
- // This is an ad-hoc fix for https://issues.dlang.org/show_bug.cgi?id=19646
- // Should be replaced by a more general @system variables implementation
- if (!sc.func && sc.stc & STC.safe)
- {
- exp.error("cast from `%s` to `%s` not allowed in safe code", exp.e1.type.toChars(), exp.to.toChars());
- return setError();
- }
-
if (sc.setUnsafe(false, exp.loc, "cast from `%s` to `%s` not allowed in safe code", exp.e1.type, exp.to))
{
return setError();
@@ -8000,7 +8003,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
te = cast(TupleExp)exp.e1;
tup = null;
- length = te.exps.dim;
+ length = te.exps.length;
}
else if (exp.e1.op == EXP.type) // slicing a type tuple
{
@@ -8403,7 +8406,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (exp.e2.op == EXP.tuple)
{
TupleExp te = cast(TupleExp)exp.e2;
- if (te.exps && te.exps.dim == 1)
+ if (te.exps && te.exps.length == 1)
exp.e2 = Expression.combine(te.e0, (*te.exps)[0]); // bug 4444 fix
}
if (sc != scx)
@@ -8467,6 +8470,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
semanticTypeInfo(sc, taa);
+ checkNewEscape(sc, exp.e2, false);
exp.type = taa.next;
break;
@@ -8487,7 +8491,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
te = cast(TupleExp)exp.e1;
tup = null;
- length = te.exps.dim;
+ length = te.exps.length;
}
else if (exp.e1.op == EXP.type)
{
@@ -8710,7 +8714,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
auto sle = new StructLiteralExp(loc, sd, null, t);
if (!sd.fill(loc, *sle.elements, true))
return ErrorExp.get();
- if (checkFrameAccess(loc, sc, sd, sle.elements.dim))
+ if (checkFrameAccess(loc, sc, sd, sle.elements.length))
return ErrorExp.get();
sle.type = t;
@@ -8769,11 +8773,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
Expression ae1old = ae.e1;
const(bool) maybeSlice =
- (ae.arguments.dim == 0 ||
- ae.arguments.dim == 1 && (*ae.arguments)[0].op == EXP.interval);
+ (ae.arguments.length == 0 ||
+ ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
IntervalExp ie = null;
- if (maybeSlice && ae.arguments.dim)
+ if (maybeSlice && ae.arguments.length)
{
assert((*ae.arguments)[0].op == EXP.interval);
ie = cast(IntervalExp)(*ae.arguments)[0];
@@ -8983,11 +8987,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
TupleExp tup1 = cast(TupleExp)exp.e1;
TupleExp tup2 = cast(TupleExp)e2x;
- size_t dim = tup1.exps.dim;
+ size_t dim = tup1.exps.length;
Expression e = null;
- if (dim != tup2.exps.dim)
+ if (dim != tup2.exps.length)
{
- exp.error("mismatched tuple lengths, %d and %d", cast(int)dim, cast(int)tup2.exps.dim);
+ exp.error("mismatched tuple lengths, %d and %d", cast(int)dim, cast(int)tup2.exps.length);
return setError();
}
if (dim == 0)
@@ -9026,13 +9030,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
auto iexps = new Expressions();
iexps.push(ev);
- for (size_t u = 0; u < iexps.dim; u++)
+ for (size_t u = 0; u < iexps.length; u++)
{
Lexpand:
Expression e = (*iexps)[u];
Parameter arg = Parameter.getNth(tt.arguments, u);
- //printf("[%d] iexps.dim = %d, ", u, iexps.dim);
+ //printf("[%d] iexps.length = %d, ", u, iexps.length);
//printf("e = (%s %s, %s), ", Token.toChars[e.op], e.toChars(), e.type.toChars());
//printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
@@ -9041,7 +9045,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// expand initializer to tuple
if (expandAliasThisTuples(iexps, u) != -1)
{
- if (iexps.dim <= u)
+ if (iexps.length <= u)
break;
goto Lexpand;
}
@@ -9527,7 +9531,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
uinteger_t dim2 = dim1;
if (auto ale = e2x.isArrayLiteralExp())
{
- dim2 = ale.elements ? ale.elements.dim : 0;
+ dim2 = ale.elements ? ale.elements.length : 0;
}
else if (auto se = e2x.isSliceExp())
{
@@ -9752,7 +9756,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
TypeSArray tsa1 = cast(TypeSArray)toStaticArrayType(se1);
TypeSArray tsa2 = null;
if (auto ale = e2x.isArrayLiteralExp())
- tsa2 = cast(TypeSArray)t2.nextOf().sarrayOf(ale.elements.dim);
+ tsa2 = cast(TypeSArray)t2.nextOf().sarrayOf(ale.elements.length);
else if (auto se = e2x.isSliceExp())
tsa2 = cast(TypeSArray)toStaticArrayType(se);
else
@@ -10359,9 +10363,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return setError();
exp.type = exp.e1.type;
+ auto assignElem = exp.e2;
auto res = exp.reorderSettingAAElem(sc);
- if (exp.op == EXP.concatenateElemAssign || exp.op == EXP.concatenateDcharAssign)
+ if (res != exp) // `AA[k] = v` rewrite was performed
+ checkNewEscape(sc, assignElem, false);
+ else if (exp.op == EXP.concatenateElemAssign || exp.op == EXP.concatenateDcharAssign)
checkAssignEscape(sc, res, false, false);
+
result = res;
if ((exp.op == EXP.concatenateAssign || exp.op == EXP.concatenateElemAssign) &&
@@ -11917,7 +11925,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
static struct Result { bool ttEmpty; bool te; }
auto tt = e.op == EXP.type ? e.isTypeExp().type.isTypeTuple() : null;
- return Result(tt && (!tt.arguments || !tt.arguments.dim), e.isTupleExp() !is null);
+ return Result(tt && (!tt.arguments || !tt.arguments.length), e.isTupleExp() !is null);
}
auto tups1 = extractTypeTupAndExpTup(exp.e1);
auto tups2 = extractTypeTupAndExpTup(exp.e2);
@@ -12599,7 +12607,7 @@ Expression semanticX(DotIdExp exp, Scope* sc)
{
/* 'distribute' the .offsetof to each of the tuple elements.
*/
- auto exps = new Expressions(te.exps.dim);
+ auto exps = new Expressions(te.exps.length);
foreach (i, e; (*te.exps)[])
{
(*exps)[i] = new DotIdExp(e.loc, e, Id.offsetof);
@@ -12612,7 +12620,7 @@ Expression semanticX(DotIdExp exp, Scope* sc)
if (exp.ident == Id.length)
{
// Don't evaluate te.e0 in runtime
- return new IntegerExp(exp.loc, te.exps.dim, Type.tsize_t);
+ return new IntegerExp(exp.loc, te.exps.length, Type.tsize_t);
}
}
@@ -13564,7 +13572,7 @@ private bool fit(StructDeclaration sd, const ref Loc loc, Scope* sc, Expressions
const nfields = sd.nonHiddenFields();
size_t offset = 0;
- for (size_t i = 0; i < elements.dim; i++)
+ for (size_t i = 0; i < elements.length; i++)
{
Expression e = (*elements)[i];
if (!e)
@@ -13573,7 +13581,7 @@ private bool fit(StructDeclaration sd, const ref Loc loc, Scope* sc, Expressions
e = resolveProperties(sc, e);
if (i >= nfields)
{
- if (i < sd.fields.dim && e.op == EXP.null_)
+ if (i < sd.fields.length && e.op == EXP.null_)
{
// CTFE sometimes creates null as hidden pointer; we'll allow this.
continue;
diff --git a/gcc/d/dmd/file_manager.d b/gcc/d/dmd/file_manager.d
index 0ea7303..a941115 100644
--- a/gcc/d/dmd/file_manager.d
+++ b/gcc/d/dmd/file_manager.d
@@ -12,7 +12,7 @@ module dmd.file_manager;
import dmd.root.stringtable : StringTable;
import dmd.root.file : File, Buffer;
-import dmd.root.filename : FileName;
+import dmd.root.filename : FileName, isDirSeparator;
import dmd.root.string : toDString;
import dmd.globals;
import dmd.identifier;
@@ -26,14 +26,86 @@ bool isPackageFileName(scope FileName fileName) nothrow
return FileName.equals(fileName.name, package_d) || FileName.equals(fileName.name, package_di);
}
+// A path stack that allows one to go up and down the path using directory
+// separators. `cur` is the current path, `up` goes up one path, `down` goes
+// down one path. if `up` or `down` return false, there are no further paths.
+private struct PathStack
+{
+ private const(char)[] path;
+ private size_t pos;
+
+ @safe @nogc nothrow pure:
+
+ this(const(char)[] p)
+ {
+ path = p;
+ pos = p.length;
+ }
+
+ const(char)[] cur()
+ {
+ return path[0 .. pos];
+ }
+
+ bool up()
+ {
+ if (pos == 0)
+ return false;
+ while (--pos != 0)
+ if (isDirSeparator(path[pos]))
+ return true;
+ return false;
+ }
+
+ bool down()
+ {
+ if (pos == path.length)
+ return false;
+ while (++pos != path.length)
+ if (isDirSeparator(path[pos]))
+ return true;
+ return false;
+ }
+}
+
final class FileManager
{
private StringTable!(const(ubyte)[]) files;
+ private StringTable!(bool) packageStatus;
+
+ // check if the package path of the given path exists. The input path is
+ // expected to contain the full path to the module, so the parent
+ // directories of that path are checked.
+ private bool packageExists(const(char)[] p) nothrow
+ {
+ // step 1, look for the closest parent path that is cached
+ bool exists = true;
+ auto st = PathStack(p);
+ while (st.up) {
+ if (auto cached = packageStatus.lookup(st.cur)) {
+ exists = cached.value;
+ break;
+ }
+ }
+ // found a parent that is cached (or reached the end of the stack).
+ // step 2, traverse back up the stack storing either false if the
+ // parent doesn't exist, or the result of the `exists` call if it does.
+ while (st.down) {
+ if (!exists)
+ packageStatus.insert(st.cur, false);
+ else
+ exists = packageStatus.insert(st.cur, FileName.exists(st.cur) == 2).value;
+ }
+
+ // at this point, exists should be the answer.
+ return exists;
+ }
///
public this () nothrow
{
this.files._init();
+ this.packageStatus._init();
}
nothrow:
@@ -48,13 +120,15 @@ nothrow:
* the found file name or
* `null` if it is not different from filename.
*/
- static const(char)[] lookForSourceFile(const char[] filename, const char*[] path)
+ const(char)[] lookForSourceFile(const char[] filename, const char*[] path)
{
//printf("lookForSourceFile(`%.*s`)\n", cast(int)filename.length, filename.ptr);
/* Search along path[] for .di file, then .d file, then .i file, then .c file.
*/
+ // see if we should check for the module locally.
+ bool checkLocal = packageExists(filename);
const sdi = FileName.forceExt(filename, hdr_ext);
- if (FileName.exists(sdi) == 1)
+ if (checkLocal && FileName.exists(sdi) == 1)
return sdi;
scope(exit) FileName.free(sdi.ptr);
@@ -62,36 +136,43 @@ nothrow:
// Special file name representing `stdin`, always assume its presence
if (sd == "__stdin.d")
return sd;
- if (FileName.exists(sd) == 1)
+ if (checkLocal && FileName.exists(sd) == 1)
return sd;
scope(exit) FileName.free(sd.ptr);
const si = FileName.forceExt(filename, i_ext);
- if (FileName.exists(si) == 1)
+ if (checkLocal && FileName.exists(si) == 1)
return si;
scope(exit) FileName.free(si.ptr);
const sc = FileName.forceExt(filename, c_ext);
- if (FileName.exists(sc) == 1)
+ if (checkLocal && FileName.exists(sc) == 1)
return sc;
scope(exit) FileName.free(sc.ptr);
- if (FileName.exists(filename) == 2)
+ if (checkLocal)
{
- /* The filename exists and it's a directory.
- * Therefore, the result should be: filename/package.d
- * iff filename/package.d is a file
- */
- const ni = FileName.combine(filename, package_di);
- if (FileName.exists(ni) == 1)
- return ni;
- FileName.free(ni.ptr);
-
- const n = FileName.combine(filename, package_d);
- if (FileName.exists(n) == 1)
- return n;
- FileName.free(n.ptr);
+ auto cached = packageStatus.lookup(filename);
+ if (!cached)
+ cached = packageStatus.insert(filename, FileName.exists(filename) == 2);
+ if (cached.value)
+ {
+ /* The filename exists and it's a directory.
+ * Therefore, the result should be: filename/package.d
+ * iff filename/package.d is a file
+ */
+ const ni = FileName.combine(filename, package_di);
+ if (FileName.exists(ni) == 1)
+ return ni;
+ FileName.free(ni.ptr);
+
+ const n = FileName.combine(filename, package_d);
+ if (FileName.exists(n) == 1)
+ return n;
+ FileName.free(n.ptr);
+ }
}
+
if (FileName.absolute(filename))
return null;
if (!path.length)
@@ -101,6 +182,11 @@ nothrow:
const p = entry.toDString();
const(char)[] n = FileName.combine(p, sdi);
+
+ if (!packageExists(n)) {
+ FileName.free(n.ptr);
+ continue; // no need to check for anything else.
+ }
if (FileName.exists(n) == 1) {
return n;
}
@@ -127,7 +213,16 @@ nothrow:
const b = FileName.removeExt(filename);
n = FileName.combine(p, b);
FileName.free(b.ptr);
- if (FileName.exists(n) == 2)
+
+ scope(exit) FileName.free(n.ptr);
+
+ // also cache this if we are looking for package.d[i]
+ auto cached = packageStatus.lookup(n);
+ if (!cached) {
+ cached = packageStatus.insert(n, FileName.exists(n) == 2);
+ }
+
+ if (cached.value)
{
const n2i = FileName.combine(n, package_di);
if (FileName.exists(n2i) == 1)
@@ -139,7 +234,6 @@ nothrow:
}
FileName.free(n2.ptr);
}
- FileName.free(n.ptr);
}
return null;
}
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index 3b0b34e..93e3634 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -640,7 +640,7 @@ extern (C++) class FuncDeclaration : Declaration
}
/*************************************************
- * Find index of function in vtbl[0..dim] that
+ * Find index of function in vtbl[0..length] that
* this function overrides.
* Prefer an exact match to a covariant one.
* Params:
@@ -777,7 +777,7 @@ extern (C++) class FuncDeclaration : Declaration
{
foreach (b; cd.interfaces)
{
- auto v = findVtblIndex(&b.sym.vtbl, cast(int)b.sym.vtbl.dim);
+ auto v = findVtblIndex(&b.sym.vtbl, cast(int)b.sym.vtbl.length);
if (v >= 0)
return b;
}
@@ -1810,7 +1810,7 @@ extern (C++) class FuncDeclaration : Declaration
if (!isVirtual())
return false;
// If it's a final method, and does not override anything, then it is not virtual
- if (isFinalFunc() && foverrides.dim == 0)
+ if (isFinalFunc() && foverrides.length == 0)
{
return false;
}
@@ -1967,7 +1967,7 @@ extern (C++) class FuncDeclaration : Declaration
if (fdthis != this)
{
bool found = false;
- for (size_t i = 0; i < siblingCallers.dim; ++i)
+ for (size_t i = 0; i < siblingCallers.length; ++i)
{
if (siblingCallers[i] == fdthis)
found = true;
@@ -2033,12 +2033,12 @@ extern (C++) class FuncDeclaration : Declaration
if (requiresClosure)
goto Lyes;
- for (size_t i = 0; i < closureVars.dim; i++)
+ for (size_t i = 0; i < closureVars.length; i++)
{
VarDeclaration v = closureVars[i];
//printf("\tv = %s\n", v.toChars());
- for (size_t j = 0; j < v.nestedrefs.dim; j++)
+ for (size_t j = 0; j < v.nestedrefs.length; j++)
{
FuncDeclaration f = v.nestedrefs[j];
assert(f != this);
@@ -2167,7 +2167,7 @@ extern (C++) class FuncDeclaration : Declaration
*/
final bool hasNestedFrameRefs()
{
- if (closureVars.dim)
+ if (closureVars.length)
return true;
/* If a virtual function has contracts, assume its variables are referenced
@@ -2181,9 +2181,9 @@ extern (C++) class FuncDeclaration : Declaration
if (fdrequire || fdensure)
return true;
- if (foverrides.dim && isVirtualMethod())
+ if (foverrides.length && isVirtualMethod())
{
- for (size_t i = 0; i < foverrides.dim; i++)
+ for (size_t i = 0; i < foverrides.length; i++)
{
FuncDeclaration fdv = foverrides[i];
if (fdv.hasNestedFrameRefs())
@@ -2406,7 +2406,7 @@ extern (C++) class FuncDeclaration : Declaration
* becomes:
* in { { statements1... } { statements2... } ... }
*/
- assert(frequires.dim);
+ assert(frequires.length);
auto loc = (*frequires)[0].loc;
auto s = new Statements;
foreach (r; *frequires)
@@ -2425,7 +2425,7 @@ extern (C++) class FuncDeclaration : Declaration
* out(__result) { { ref id1 = __result; { statements1... } }
* { ref id2 = __result; { statements2... } } ... }
*/
- assert(fensures.dim);
+ assert(fensures.length);
auto loc = (*fensures)[0].ensure.loc;
auto s = new Statements;
foreach (r; *fensures)
@@ -3133,7 +3133,7 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s,
printf("\tthis: %s\n", tthis.toChars());
if (fargs)
{
- for (size_t i = 0; i < fargs.dim; i++)
+ for (size_t i = 0; i < fargs.length; i++)
{
Expression arg = (*fargs)[i];
assert(arg.type);
@@ -3352,46 +3352,40 @@ if (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration))
{
// max num of overloads to print (-v overrides this).
enum int DisplayLimit = 5;
- int displayed;
const(char)* constraintsTip;
-
// determine if the first candidate was printed
- bool printed = false;
+ int printed;
- overloadApply(declaration, (Dsymbol s)
+ bool matchSymbol(Dsymbol s, bool print, bool single_candidate = false)
{
- Dsymbol nextOverload;
-
if (auto fd = s.isFuncDeclaration())
{
// Don't print overloads which have errors.
// Not that if the whole overload set has errors, we'll never reach
// this point so there's no risk of printing no candidate
if (fd.errors || fd.type.ty == Terror)
- return 0;
+ return false;
// Don't print disabled functions, or `deprecated` outside of deprecated scope
if (fd.storage_class & STC.disable || (fd.isDeprecated() && !showDeprecated))
- return 0;
-
- const single_candidate = fd.overnext is null;
+ return false;
+ if (!print)
+ return true;
auto tf = cast(TypeFunction) fd.type;
.errorSupplemental(fd.loc,
printed ? " `%s%s`" :
single_candidate ? "Candidate is: `%s%s`" : "Candidates are: `%s%s`",
fd.toPrettyChars(),
parametersTypeToChars(tf.parameterList));
- printed = true;
- nextOverload = fd.overnext;
}
else if (auto td = s.isTemplateDeclaration())
{
import dmd.staticcond;
+ if (!print)
+ return true;
const tmsg = td.toCharsNoConstraints();
const cmsg = td.getConstraintEvalError(constraintsTip);
- const single_candidate = td.overnext is null;
-
// add blank space if there are multiple candidates
// the length of the blank space is `strlen("Candidates are: ")`
@@ -3401,7 +3395,6 @@ if (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration))
printed ? " `%s`\n%s" :
single_candidate ? "Candidate is: `%s`\n%s" : "Candidates are: `%s`\n%s",
tmsg, cmsg);
- printed = true;
}
else
{
@@ -3409,26 +3402,38 @@ if (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration))
printed ? " `%s`" :
single_candidate ? "Candidate is: `%s`" : "Candidates are: `%s`",
tmsg);
- printed = true;
}
- nextOverload = td.overnext;
}
-
- if (global.params.verbose || ++displayed < DisplayLimit)
- return 0;
-
- // Too many overloads to sensibly display.
- // Just show count of remaining overloads.
- int num = 0;
- overloadApply(nextOverload, (s) { ++num; return 0; });
-
- if (num > 0)
- .errorSupplemental(loc, "... (%d more, -v to show) ...", num);
- return 1; // stop iterating
+ return true;
+ }
+ // determine if there's > 1 candidate
+ int count = 0;
+ overloadApply(declaration, (s) {
+ if (matchSymbol(s, false))
+ count++;
+ return count > 1;
+ });
+ int skipped = 0;
+ overloadApply(declaration, (s) {
+ if (global.params.verbose || printed < DisplayLimit)
+ {
+ if (matchSymbol(s, true, count == 1))
+ printed++;
+ }
+ else
+ {
+ // Too many overloads to sensibly display.
+ // Just show count of remaining overloads.
+ if (matchSymbol(s, false))
+ skipped++;
+ }
+ return 0;
});
+ if (skipped > 0)
+ .errorSupplemental(loc, "... (%d more, -v to show) ...", skipped);
// Nothing was displayed, all overloads are either disabled or deprecated
- if (!displayed)
+ if (!printed)
.errorSupplemental(loc, "All possible candidates are marked as `deprecated` or `@disable`");
// should be only in verbose mode
if (constraintsTip)
@@ -3570,7 +3575,7 @@ private void markAsNeedingClosure(Dsymbol f, FuncDeclaration outerFunc)
for (Dsymbol sx = f; sx && sx != outerFunc; sx = sx.toParentP(outerFunc))
{
FuncDeclaration fy = sx.isFuncDeclaration();
- if (fy && fy.closureVars.dim)
+ if (fy && fy.closureVars.length)
{
/* fy needs a closure if it has closureVars[],
* because the frame pointer in the closure will be accessed.
@@ -3608,7 +3613,7 @@ private bool checkEscapingSiblings(FuncDeclaration f, FuncDeclaration outerFunc,
//printf("checkEscapingSiblings(f = %s, outerfunc = %s)\n", f.toChars(), outerFunc.toChars());
bool bAnyClosures = false;
- for (size_t i = 0; i < f.siblingCallers.dim; ++i)
+ for (size_t i = 0; i < f.siblingCallers.length; ++i)
{
FuncDeclaration g = f.siblingCallers[i];
if (g.isThis() || g.tookAddressOf)
@@ -4351,19 +4356,30 @@ bool setUnsafe(Scope* sc,
bool gag = false, Loc loc = Loc.init, const(char)* fmt = null,
RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
{
- // TODO:
- // For @system variables, unsafe initializers at global scope should mark
- // the variable @system, see https://dlang.org/dips/1035
-
- if (!sc.func)
- return false;
-
if (sc.intypeof)
return false; // typeof(cast(int*)0) is safe
if (sc.flags & SCOPE.debug_) // debug {} scopes are permissive
return false;
+ if (!sc.func)
+ {
+ if (sc.varDecl)
+ {
+ if (sc.varDecl.storage_class & STC.safe)
+ {
+ .error(loc, fmt, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");
+ return true;
+ }
+ else if (!(sc.varDecl.storage_class & STC.system))
+ {
+ sc.varDecl.storage_class |= STC.system;
+ }
+ }
+ return false;
+ }
+
+
if (sc.flags & SCOPE.compile) // __traits(compiles, x)
{
if (sc.func.isSafeBypassingInference())
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index debf01d..6b51a81 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -484,7 +484,7 @@ public:
{
buf.writestring("pragma (");
buf.writestring(s.ident.toString());
- if (s.args && s.args.dim)
+ if (s.args && s.args.length)
{
buf.writestring(", ");
argsToBuffer(s.args, buf, hgs);
@@ -883,7 +883,7 @@ public:
buf.printf("%s.", pid.toChars());
}
buf.writestring(imp.id.toString());
- if (imp.names.dim)
+ if (imp.names.length)
{
buf.writestring(" : ");
foreach (const i, const name; imp.names)
@@ -922,13 +922,13 @@ public:
buf.writenl();
return;
}
- if (d.decl.dim == 0 || (hgs.hdrgen && d.decl.dim == 1 && (*d.decl)[0].isUnitTestDeclaration()))
+ if (d.decl.length == 0 || (hgs.hdrgen && d.decl.length == 1 && (*d.decl)[0].isUnitTestDeclaration()))
{
// hack for bugzilla 8081
if (hasSTC) buf.writeByte(' ');
buf.writestring("{}");
}
- else if (d.decl.dim == 1)
+ else if (d.decl.length == 1)
{
if (hasSTC) buf.writeByte(' ');
(*d.decl)[0].accept(this);
@@ -993,9 +993,9 @@ public:
{
visibilityToBuffer(buf, d.visibility);
AttribDeclaration ad = cast(AttribDeclaration)d;
- if (ad.decl.dim <= 1)
+ if (ad.decl.length <= 1)
buf.writeByte(' ');
- if (ad.decl.dim == 1 && (*ad.decl)[0].isVisibilityDeclaration)
+ if (ad.decl.length == 1 && (*ad.decl)[0].isVisibilityDeclaration)
visit(cast(AttribDeclaration)(*ad.decl)[0]);
else
visit(cast(AttribDeclaration)d);
@@ -1011,7 +1011,7 @@ public:
buf.writeByte(' ');
buf.printf("align (%s)", exp.toChars());
}
- if (d.decl && d.decl.dim < 2)
+ if (d.decl && d.decl.length < 2)
buf.writeByte(' ');
}
else
@@ -1041,7 +1041,7 @@ public:
{
buf.writestring("pragma (");
buf.writestring(d.ident.toString());
- if (d.args && d.args.dim)
+ if (d.args && d.args.length)
{
buf.writestring(", ");
argsToBuffer(d.args, buf, hgs);
@@ -1210,7 +1210,7 @@ public:
bool visitEponymousMember(TemplateDeclaration d)
{
- if (!d.members || d.members.dim != 1)
+ if (!d.members || d.members.length != 1)
return false;
Dsymbol onemember = (*d.members)[0];
if (onemember.ident != d.ident)
@@ -1286,7 +1286,7 @@ public:
void visitTemplateParameters(TemplateParameters* parameters)
{
- if (!parameters || !parameters.dim)
+ if (!parameters || !parameters.length)
return;
foreach (i, p; *parameters)
{
@@ -1437,7 +1437,7 @@ public:
void visitBaseClasses(ClassDeclaration d)
{
- if (!d || !d.baseclasses.dim)
+ if (!d || !d.baseclasses.length)
return;
if (!d.isAnonymous())
buf.writestring(" : ");
@@ -1722,7 +1722,7 @@ public:
Statement s1;
if (f.semanticRun >= PASS.semantic3done && cs)
{
- s1 = (*cs.statements)[cs.statements.dim - 1];
+ s1 = (*cs.statements)[cs.statements.length - 1];
}
else
s1 = !cs ? f.fbody : null;
@@ -2130,7 +2130,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
}
buf.writestring("new ");
typeToBuffer(e.newtype, null, buf, hgs);
- if (e.arguments && e.arguments.dim)
+ if (e.arguments && e.arguments.length)
{
buf.writeByte('(');
argsToBuffer(e.arguments, buf, hgs);
@@ -2147,7 +2147,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
}
buf.writestring("new");
buf.writestring(" class ");
- if (e.arguments && e.arguments.dim)
+ if (e.arguments && e.arguments.length)
{
buf.writeByte('(');
argsToBuffer(e.arguments, buf, hgs);
@@ -2271,7 +2271,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
buf.writestring(" == ");
typeToBuffer(e.tspec, null, buf, hgs);
}
- if (e.parameters && e.parameters.dim)
+ if (e.parameters && e.parameters.length)
{
buf.writestring(", ");
scope v = new DsymbolPrettyPrintVisitor(buf, hgs);
@@ -3100,7 +3100,7 @@ void toCBuffer(const Expression e, OutBuffer* buf, HdrGenState* hgs)
*/
void argExpTypesToCBuffer(OutBuffer* buf, Expressions* arguments)
{
- if (!arguments || !arguments.dim)
+ if (!arguments || !arguments.length)
return;
HdrGenState hgs;
foreach (i, arg; *arguments)
@@ -3119,7 +3119,7 @@ void toCBuffer(const TemplateParameter tp, OutBuffer* buf, HdrGenState* hgs)
void arrayObjectsToBuffer(OutBuffer* buf, Objects* objects)
{
- if (!objects || !objects.dim)
+ if (!objects || !objects.length)
return;
HdrGenState hgs;
foreach (i, o; *objects)
@@ -3160,7 +3160,7 @@ const(char)* parameterToChars(Parameter parameter, TypeFunction tf, bool fullQua
parameterToBuffer(parameter, &buf, &hgs);
- if (tf.parameterList.varargs == VarArg.typesafe && parameter == tf.parameterList[tf.parameterList.parameters.dim - 1])
+ if (tf.parameterList.varargs == VarArg.typesafe && parameter == tf.parameterList[tf.parameterList.parameters.length - 1])
{
buf.writestring("...");
}
@@ -3219,7 +3219,7 @@ private void parameterToBuffer(Parameter p, OutBuffer* buf, HdrGenState* hgs)
{
buf.writeByte('@');
- bool isAnonymous = p.userAttribDecl.atts.dim > 0 && !(*p.userAttribDecl.atts)[0].isCallExp();
+ bool isAnonymous = p.userAttribDecl.atts.length > 0 && !(*p.userAttribDecl.atts)[0].isCallExp();
if (isAnonymous)
buf.writeByte('(');
@@ -3281,7 +3281,7 @@ private void parameterToBuffer(Parameter p, OutBuffer* buf, HdrGenState* hgs)
*/
private void argsToBuffer(Expressions* expressions, OutBuffer* buf, HdrGenState* hgs, Expression basis = null)
{
- if (!expressions || !expressions.dim)
+ if (!expressions || !expressions.length)
return;
version (all)
{
@@ -3298,11 +3298,11 @@ private void argsToBuffer(Expressions* expressions, OutBuffer* buf, HdrGenState*
else
{
// Sparse style formatting, for debug use only
- // [0..dim: basis, 1: e1, 5: e5]
+ // [0..length: basis, 1: e1, 5: e5]
if (basis)
{
buf.writestring("0..");
- buf.print(expressions.dim);
+ buf.print(expressions.length);
buf.writestring(": ");
expToBuffer(basis, PREC.assign, buf, hgs);
}
@@ -3483,12 +3483,12 @@ private void tiargsToBuffer(TemplateInstance ti, OutBuffer* buf, HdrGenState* hg
buf.writestring("()");
return;
}
- if (ti.tiargs.dim == 1)
+ if (ti.tiargs.length == 1)
{
RootObject oarg = (*ti.tiargs)[0];
if (Type t = isType(oarg))
{
- if (t.equals(Type.tstring) || t.equals(Type.twstring) || t.equals(Type.tdstring) || t.mod == 0 && (t.isTypeBasic() || t.ty == Tident && (cast(TypeIdentifier)t).idents.dim == 0))
+ if (t.equals(Type.tstring) || t.equals(Type.twstring) || t.equals(Type.tdstring) || t.mod == 0 && (t.isTypeBasic() || t.ty == Tident && (cast(TypeIdentifier)t).idents.length == 0))
{
buf.writestring(t.toChars());
return;
diff --git a/gcc/d/dmd/iasmgcc.d b/gcc/d/dmd/iasmgcc.d
index 7a840ff..f85e1ab 100644
--- a/gcc/d/dmd/iasmgcc.d
+++ b/gcc/d/dmd/iasmgcc.d
@@ -332,7 +332,7 @@ extern (C++) public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
// Analyse all input and output operands.
if (s.args)
{
- foreach (i; 0 .. s.args.dim)
+ foreach (i; 0 .. s.args.length)
{
Expression e = (*s.args)[i];
e = e.expressionSemantic(sc);
@@ -353,7 +353,7 @@ extern (C++) public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
// Analyse all clobbers.
if (s.clobbers)
{
- foreach (i; 0 .. s.clobbers.dim)
+ foreach (i; 0 .. s.clobbers.length)
{
Expression e = (*s.clobbers)[i];
e = e.expressionSemantic(sc);
@@ -365,7 +365,7 @@ extern (C++) public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
// Analyse all goto labels.
if (s.labels)
{
- foreach (i; 0 .. s.labels.dim)
+ foreach (i; 0 .. s.labels.length)
{
Identifier ident = (*s.labels)[i];
GotoStatement gs = new GotoStatement(s.loc, ident);
diff --git a/gcc/d/dmd/init.d b/gcc/d/dmd/init.d
index 523b5b8..f57b4e6 100644
--- a/gcc/d/dmd/init.d
+++ b/gcc/d/dmd/init.d
@@ -271,10 +271,10 @@ Initializer syntaxCopy(Initializer inx)
static Initializer copyStruct(StructInitializer vi)
{
auto si = new StructInitializer(vi.loc);
- assert(vi.field.dim == vi.value.dim);
- si.field.setDim(vi.field.dim);
- si.value.setDim(vi.value.dim);
- foreach (const i; 0 .. vi.field.dim)
+ assert(vi.field.length == vi.value.length);
+ si.field.setDim(vi.field.length);
+ si.value.setDim(vi.value.length);
+ foreach (const i; 0 .. vi.field.length)
{
si.field[i] = vi.field[i];
si.value[i] = vi.value[i].syntaxCopy();
@@ -285,10 +285,10 @@ Initializer syntaxCopy(Initializer inx)
static Initializer copyArray(ArrayInitializer vi)
{
auto ai = new ArrayInitializer(vi.loc);
- assert(vi.index.dim == vi.value.dim);
- ai.index.setDim(vi.index.dim);
- ai.value.setDim(vi.value.dim);
- foreach (const i; 0 .. vi.value.dim)
+ assert(vi.index.length == vi.value.length);
+ ai.index.setDim(vi.index.length);
+ ai.value.setDim(vi.value.length);
+ foreach (const i; 0 .. vi.value.length)
{
ai.index[i] = vi.index[i] ? vi.index[i].syntaxCopy() : null;
ai.value[i] = vi.value[i].syntaxCopy();
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index ef39f59..ecaa5e8 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -55,7 +55,7 @@ Expression toAssocArrayLiteral(ArrayInitializer ai)
Expression e;
//printf("ArrayInitializer::toAssocArrayInitializer()\n");
//static int i; if (++i == 2) assert(0);
- const dim = ai.value.dim;
+ const dim = ai.value.length;
auto keys = new Expressions(dim);
auto values = new Expressions(dim);
for (size_t i = 0; i < dim; i++)
@@ -249,7 +249,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
auto ie = new ExpInitializer(i.loc, sle);
return ie.initializerSemantic(sc, t, needInterpret);
}
- else if ((t.ty == Tdelegate || t.isPtrToFunction()) && i.value.dim == 0)
+ else if ((t.ty == Tdelegate || t.isPtrToFunction()) && i.value.length == 0)
{
const tok = (t.ty == Tdelegate) ? TOK.delegate_ : TOK.function_;
/* Rewrite as empty delegate literal { }
@@ -315,7 +315,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
}
i.type = t;
length = 0;
- for (size_t j = 0; j < i.index.dim; j++)
+ for (size_t j = 0; j < i.index.length; j++)
{
Expression idx = i.index[j];
if (idx)
@@ -350,7 +350,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
TupleExp te = ei.exp.isTupleExp();
i.index.remove(j);
i.value.remove(j);
- for (size_t k = 0; k < te.exps.dim; ++k)
+ for (size_t k = 0; k < te.exps.length; ++k)
{
Expression e = (*te.exps)[k];
i.index.insert(j + k, cast(Expression)null);
@@ -475,7 +475,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
{
return i; // Failed, suppress duplicate error messages
}
- if (i.exp.type.isTypeTuple() && i.exp.type.isTypeTuple().arguments.dim == 0)
+ if (i.exp.type.isTypeTuple() && i.exp.type.isTypeTuple().arguments.length == 0)
{
Type et = i.exp.type;
i.exp = new TupleExp(i.exp.loc, new Expressions());
@@ -638,7 +638,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
uinteger_t dim2 = dim1;
if (auto ale = i.exp.isArrayLiteralExp())
{
- dim2 = ale.elements ? ale.elements.dim : 0;
+ dim2 = ale.elements ? ale.elements.length : 0;
}
else if (auto se = i.exp.isSliceExp())
{
@@ -1094,9 +1094,9 @@ Initializer inferType(Initializer init, Scope* sc)
Expressions* values;
if (init.isAssociativeArray())
{
- keys = new Expressions(init.value.dim);
- values = new Expressions(init.value.dim);
- for (size_t i = 0; i < init.value.dim; i++)
+ keys = new Expressions(init.value.length);
+ values = new Expressions(init.value.length);
+ for (size_t i = 0; i < init.value.length; i++)
{
Expression e = init.index[i];
if (!e)
@@ -1119,9 +1119,9 @@ Initializer inferType(Initializer init, Scope* sc)
}
else
{
- auto elements = new Expressions(init.value.dim);
+ auto elements = new Expressions(init.value.length);
elements.zero();
- for (size_t i = 0; i < init.value.dim; i++)
+ for (size_t i = 0; i < init.value.length; i++)
{
assert(!init.index[i]); // already asserted by isAssociativeArray()
Initializer iz = init.value[i];
@@ -1300,9 +1300,9 @@ extern (C++) Expression initializerToExpression(Initializer init, Type itype = n
{
/* Calculate the length of the array literal
*/
- edim = cast(uint)init.value.dim;
+ edim = cast(uint)init.value.length;
size_t j = 0;
- foreach (i; 0 .. init.value.dim)
+ foreach (i; 0 .. init.value.length)
{
if (auto e = init.index[i])
{
@@ -1325,7 +1325,7 @@ extern (C++) Expression initializerToExpression(Initializer init, Type itype = n
auto elements = new Expressions(edim);
elements.zero();
size_t j = 0;
- foreach (i; 0 .. init.value.dim)
+ foreach (i; 0 .. init.value.length)
{
if (auto e = init.index[i])
j = cast(size_t)e.toInteger();
diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d
index a22c664..b7719d8 100644
--- a/gcc/d/dmd/json.d
+++ b/gcc/d/dmd/json.d
@@ -386,13 +386,13 @@ public:
extern(D) void property(const char[] name, Parameters* parameters)
{
- if (parameters is null || parameters.dim == 0)
+ if (parameters is null || parameters.length == 0)
return;
propertyStart(name);
arrayStart();
if (parameters)
{
- for (size_t i = 0; i < parameters.dim; i++)
+ for (size_t i = 0; i < parameters.length; i++)
{
Parameter p = (*parameters)[i];
objectStart();
@@ -491,7 +491,7 @@ public:
property("comment", s.comment.toDString);
propertyStart("members");
arrayStart();
- for (size_t i = 0; i < s.members.dim; i++)
+ for (size_t i = 0; i < s.members.length; i++)
{
(*s.members)[i].accept(this);
}
@@ -522,7 +522,7 @@ public:
property("alias", s.aliasId.toString());
bool hasRenamed = false;
bool hasSelective = false;
- for (size_t i = 0; i < s.aliases.dim; i++)
+ for (size_t i = 0; i < s.aliases.length; i++)
{
// avoid empty "renamed" and "selective" sections
if (hasRenamed && hasSelective)
@@ -537,7 +537,7 @@ public:
// import foo : alias1 = target1;
propertyStart("renamed");
objectStart();
- for (size_t i = 0; i < s.aliases.dim; i++)
+ for (size_t i = 0; i < s.aliases.length; i++)
{
const name = s.names[i];
const _alias = s.aliases[i];
@@ -566,7 +566,7 @@ public:
Dsymbols* ds = d.include(null);
if (ds)
{
- for (size_t i = 0; i < ds.dim; i++)
+ for (size_t i = 0; i < ds.length; i++)
{
Dsymbol s = (*ds)[i];
s.accept(this);
@@ -582,7 +582,7 @@ public:
return; // Don't visit the if/else bodies again below
}
Dsymbols* ds = d.decl ? d.decl : d.elsedecl;
- for (size_t i = 0; i < ds.dim; i++)
+ for (size_t i = 0; i < ds.length; i++)
{
Dsymbol s = (*ds)[i];
s.accept(this);
@@ -631,7 +631,7 @@ public:
{
propertyStart("members");
arrayStart();
- for (size_t i = 0; i < d.members.dim; i++)
+ for (size_t i = 0; i < d.members.length; i++)
{
Dsymbol s = (*d.members)[i];
s.accept(this);
@@ -649,11 +649,11 @@ public:
if (tf && tf.ty == Tfunction)
property("parameters", tf.parameterList.parameters);
property("endline", "endchar", d.endloc);
- if (d.foverrides.dim)
+ if (d.foverrides.length)
{
propertyStart("overrides");
arrayStart();
- for (size_t i = 0; i < d.foverrides.dim; i++)
+ for (size_t i = 0; i < d.foverrides.length; i++)
{
FuncDeclaration fd = d.foverrides[i];
item(fd.toPrettyChars().toDString);
@@ -681,7 +681,7 @@ public:
jsonProperties(d);
propertyStart("parameters");
arrayStart();
- for (size_t i = 0; i < d.parameters.dim; i++)
+ for (size_t i = 0; i < d.parameters.length; i++)
{
TemplateParameter s = (*d.parameters)[i];
objectStart();
@@ -732,7 +732,7 @@ public:
}
propertyStart("members");
arrayStart();
- for (size_t i = 0; i < d.members.dim; i++)
+ for (size_t i = 0; i < d.members.length; i++)
{
Dsymbol s = (*d.members)[i];
s.accept(this);
@@ -747,7 +747,7 @@ public:
{
if (d.members)
{
- for (size_t i = 0; i < d.members.dim; i++)
+ for (size_t i = 0; i < d.members.length; i++)
{
Dsymbol s = (*d.members)[i];
s.accept(this);
@@ -762,7 +762,7 @@ public:
{
propertyStart("members");
arrayStart();
- for (size_t i = 0; i < d.members.dim; i++)
+ for (size_t i = 0; i < d.members.length; i++)
{
Dsymbol s = (*d.members)[i];
s.accept(this);
@@ -963,7 +963,7 @@ public:
requiredProperty("name", m.md ? m.md.toString() : null);
requiredProperty("file", m.srcfile.toString());
propertyBool("isRoot", m.isRoot());
- if(m.contentImportedFiles.dim > 0)
+ if(m.contentImportedFiles.length > 0)
{
propertyStart("contentImports");
arrayStart();
diff --git a/gcc/d/dmd/lambdacomp.d b/gcc/d/dmd/lambdacomp.d
index 91df9cc..e1ed717 100644
--- a/gcc/d/dmd/lambdacomp.d
+++ b/gcc/d/dmd/lambdacomp.d
@@ -452,7 +452,7 @@ public:
if (ty)
{
writeMangledName(ty.sym);
- auto dim = e.elements.dim;
+ auto dim = e.elements.length;
foreach (i; 0..dim)
{
auto elem = (*e.elements)[i];
diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d
index 451e227..200d74f 100644
--- a/gcc/d/dmd/lexer.d
+++ b/gcc/d/dmd/lexer.d
@@ -126,18 +126,26 @@ class Lexer
if (p && p[0] == '#' && p[1] == '!')
{
p += 2;
- while (1)
+ for (;;p++)
{
- char c = *p++;
+ char c = *p;
switch (c)
{
+ case '\n':
+ p++;
+ goto case;
case 0:
case 0x1A:
- p--;
- goto case;
- case '\n':
break;
+
default:
+ // Note: We do allow malformed UTF-8 on shebang line.
+ // It could have a meaning if the native system
+ // encoding is not Unicode. See test compilable/test13512.d
+ // for example encoded in KOI-8.
+ // We also allow bidirectional control characters.
+ // We do not execute the shebang line, so it can't be used
+ // to conceal code. It is up to the shell to sanitize it.
continue;
}
break;
@@ -522,7 +530,7 @@ class Lexer
const u = decodeUTF();
if (isUniAlpha(u))
continue;
- error("char 0x%04x not allowed in identifier", u);
+ error(t.loc, "char 0x%04x not allowed in identifier", u);
p = s;
}
break;
@@ -620,7 +628,7 @@ class Lexer
continue;
case 0:
case 0x1A:
- error("unterminated /* */ comment");
+ error(t.loc, "unterminated /* */ comment");
p = end;
t.loc = loc();
t.value = TOK.endOfFile;
@@ -756,7 +764,7 @@ class Lexer
continue;
case 0:
case 0x1A:
- error("unterminated /+ +/ comment");
+ error(t.loc, "unterminated /+ +/ comment");
p = end;
t.loc = loc();
t.value = TOK.endOfFile;
@@ -1126,11 +1134,12 @@ class Lexer
}
}
if (c < 0x80 && isprint(c))
- error("character '%c' is not a valid token", c);
+ error(t.loc, "character '%c' is not a valid token", c);
else
- error("character 0x%02x is not a valid token", c);
+ error(t.loc, "character 0x%02x is not a valid token", c);
p++;
continue;
+ // assert(0);
}
}
}
@@ -1467,6 +1476,7 @@ class Lexer
stringbuffer.setsize(0);
while (1)
{
+ const s = p;
dchar c = *p++;
//printf("c = '%c'\n", c);
switch (c)
@@ -1526,7 +1536,7 @@ class Lexer
{
// Start of identifier; must be a heredoc
Token tok;
- p--;
+ p = s;
scan(&tok); // read in heredoc identifier
if (tok.value != TOK.identifier)
{
@@ -1574,7 +1584,7 @@ class Lexer
{
Token tok;
auto psave = p;
- p--;
+ p = s;
scan(&tok); // read in possible heredoc identifier
//printf("endid = '%s'\n", tok.ident.toChars());
if (tok.value == TOK.identifier && tok.ident is hereid)
@@ -2830,6 +2840,20 @@ class Lexer
*/
private uint decodeUTF()
{
+ string msg;
+ auto result = decodeUTFpure(msg);
+
+ if (msg)
+ error("%.*s", cast(int)msg.length, msg.ptr);
+ return result;
+ }
+
+ /********************************************
+ * Same as above, but the potential error message is stored to the
+ * msg parameter instead of being issued.
+ */
+ private pure uint decodeUTFpure(out string msg)
+ {
const s = p;
assert(*s & 0x80);
// Check length of remaining string up to 4 UTF-8 characters
@@ -2839,12 +2863,10 @@ class Lexer
}
size_t idx = 0;
dchar u;
- const msg = utf_decodeChar(s[0 .. len], idx, u);
+ msg = utf_decodeChar(s[0 .. len], idx, u);
p += idx - 1;
- if (msg)
- {
- error("%.*s", cast(int)msg.length, msg.ptr);
- }
+ if (!msg && isBidiControl(u))
+ msg = "Bidirectional control characters are disallowed for security reasons.";
return u;
}
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index 265f731..2c0a571 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -4556,7 +4556,7 @@ extern (C++) final class TypeFunction : TypeNext
Parameters* params = parameterList.parameters;
if (mod & MODFlags.wild)
params = parameterList.parameters.copy();
- for (size_t i = 0; i < params.dim; i++)
+ for (size_t i = 0; i < params.length; i++)
{
Parameter p = (*params)[i];
Type t = p.type.substWildTo(m);
@@ -4686,7 +4686,7 @@ extern (C++) final class TypeFunction : TypeNext
if (parameterList.varargs == VarArg.none && nparams > nargs && !parameterList[nargs].defaultArg)
{
OutBuffer buf;
- buf.printf("too few arguments, expected `%d`, got `%d`", cast(int)nparams, cast(int)nargs);
+ buf.printf("too few arguments, expected %d, got %d", cast(int)nparams, cast(int)nargs);
if (pMessage)
*pMessage = buf.extractChars();
return MATCH.nomatch;
@@ -5108,8 +5108,8 @@ extern (C++) abstract class TypeQualified : Type
final void syntaxCopyHelper(TypeQualified t)
{
//printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t.toChars(), toChars());
- idents.setDim(t.idents.dim);
- for (size_t i = 0; i < idents.dim; i++)
+ idents.setDim(t.idents.length);
+ for (size_t i = 0; i < idents.length; i++)
{
RootObject id = t.idents[i];
with (DYNCAST) final switch (id.dyncast())
@@ -5251,7 +5251,7 @@ extern (C++) final class TypeInstance : TypeQualified
override TypeInstance syntaxCopy()
{
- //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.dim);
+ //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.length);
auto t = new TypeInstance(loc, tempinst.syntaxCopy(null));
t.syntaxCopyHelper(this);
t.mod = mod;
@@ -5432,7 +5432,7 @@ extern (C++) final class TypeStruct : Type
auto structelems = new Expressions(sym.nonHiddenFields());
uint offset = 0;
- foreach (j; 0 .. structelems.dim)
+ foreach (j; 0 .. structelems.length)
{
VarDeclaration vd = sym.fields[j];
Expression e;
@@ -5487,7 +5487,7 @@ extern (C++) final class TypeStruct : Type
/* If any of the fields are const or immutable,
* then one cannot assign this struct.
*/
- for (size_t i = 0; i < sym.fields.dim; i++)
+ for (size_t i = 0; i < sym.fields.length; i++)
{
VarDeclaration v = sym.fields[i];
//printf("%s [%d] v = (%s) %s, v.offset = %d, v.parent = %s\n", sym.toChars(), i, v.kind(), v.toChars(), v.offset, v.parent.kind());
@@ -5541,7 +5541,7 @@ extern (C++) final class TypeStruct : Type
if (sym.isNested())
return true;
- for (size_t i = 0; i < sym.fields.dim; i++)
+ for (size_t i = 0; i < sym.fields.length; i++)
{
VarDeclaration v = sym.fields[i];
if (!v.isDataseg() && v.type.needsNested())
@@ -5599,7 +5599,7 @@ extern (C++) final class TypeStruct : Type
* allow the conversion.
*/
uint offset = ~0; // dead-store to prevent spurious warning
- for (size_t i = 0; i < sym.fields.dim; i++)
+ for (size_t i = 0; i < sym.fields.length; i++)
{
VarDeclaration v = sym.fields[i];
if (i == 0)
@@ -6072,7 +6072,7 @@ extern (C++) final class TypeTuple : Type
{
if (arguments)
{
- for (size_t i = 0; i < arguments.dim; i++)
+ for (size_t i = 0; i < arguments.length; i++)
{
Parameter arg = (*arguments)[i];
assert(arg && arg.type);
@@ -6088,10 +6088,10 @@ extern (C++) final class TypeTuple : Type
extern (D) this(Expressions* exps)
{
super(Ttuple);
- auto arguments = new Parameters(exps ? exps.dim : 0);
+ auto arguments = new Parameters(exps ? exps.length : 0);
if (exps)
{
- for (size_t i = 0; i < exps.dim; i++)
+ for (size_t i = 0; i < exps.length; i++)
{
Expression e = (*exps)[i];
if (e.type.ty == Ttuple)
@@ -6169,9 +6169,9 @@ extern (C++) final class TypeTuple : Type
return true;
if (auto tt = t.isTypeTuple())
{
- if (arguments.dim == tt.arguments.dim)
+ if (arguments.length == tt.arguments.length)
{
- for (size_t i = 0; i < tt.arguments.dim; i++)
+ for (size_t i = 0; i < tt.arguments.length; i++)
{
const Parameter arg1 = (*arguments)[i];
Parameter arg2 = (*tt.arguments)[i];
@@ -6190,10 +6190,10 @@ extern (C++) final class TypeTuple : Type
return MATCH.exact;
if (auto tt = to.isTypeTuple())
{
- if (arguments.dim == tt.arguments.dim)
+ if (arguments.length == tt.arguments.length)
{
MATCH m = MATCH.exact;
- for (size_t i = 0; i < tt.arguments.dim; i++)
+ for (size_t i = 0; i < tt.arguments.length; i++)
{
Parameter arg1 = (*arguments)[i];
Parameter arg2 = (*tt.arguments)[i];
@@ -6595,8 +6595,8 @@ extern (C++) final class Parameter : ASTNode
Parameters* params = null;
if (parameters)
{
- params = new Parameters(parameters.dim);
- for (size_t i = 0; i < params.dim; i++)
+ params = new Parameters(parameters.length);
+ for (size_t i = 0; i < params.length; i++)
(*params)[i] = (*parameters)[i].syntaxCopy();
}
return params;
diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d
index 7ddeeec..3329c14 100644
--- a/gcc/d/dmd/nogc.d
+++ b/gcc/d/dmd/nogc.d
@@ -99,7 +99,7 @@ public:
override void visit(ArrayLiteralExp e)
{
- if (e.type.ty != Tarray || !e.elements || !e.elements.dim || e.onstack)
+ if (e.type.ty != Tarray || !e.elements || !e.elements.length || e.onstack)
return;
if (f.setGC())
{
@@ -113,7 +113,7 @@ public:
override void visit(AssocArrayLiteralExp e)
{
- if (!e.keys.dim)
+ if (!e.keys.length)
return;
if (f.setGC())
{
@@ -162,16 +162,16 @@ public:
override void visit(IndexExp e)
{
Type t1b = e.e1.type.toBasetype();
- if (t1b.ty == Taarray)
+ if (e.modifiable && t1b.ty == Taarray)
{
if (f.setGC())
{
- e.error("indexing an associative array in `@nogc` %s `%s` may cause a GC allocation",
+ e.error("assigning an associative array element in `@nogc` %s `%s` may cause a GC allocation",
f.kind(), f.toPrettyChars());
err = true;
return;
}
- f.printGCUsage(e.loc, "indexing an associative array may cause a GC allocation");
+ f.printGCUsage(e.loc, "assigning an associative array element may cause a GC allocation");
}
}
diff --git a/gcc/d/dmd/ob.d b/gcc/d/dmd/ob.d
index 5ff73c9..59f34e1 100644
--- a/gcc/d/dmd/ob.d
+++ b/gcc/d/dmd/ob.d
@@ -565,7 +565,7 @@ void toObNodes(ref ObNodes obnodes, Statement s)
*/
mystate.defaultBlock = s.sdefault ? newNode() : mystate.breakBlock;
- const numcases = s.cases ? s.cases.dim : 0;
+ const numcases = s.cases ? s.cases.length : 0;
/* allocate a block for each case
*/
diff --git a/gcc/d/dmd/objc.d b/gcc/d/dmd/objc.d
index 9afedc1..2bb5eab 100644
--- a/gcc/d/dmd/objc.d
+++ b/gcc/d/dmd/objc.d
@@ -555,7 +555,7 @@ extern(C++) private final class Supported : Objc
return 1;
}
- assert(literal.elements.dim == 1);
+ assert(literal.elements.length == 1);
auto se = (*literal.elements)[0].toStringExp();
assert(se);
@@ -570,7 +570,7 @@ extern(C++) private final class Supported : Objc
if (!fd.objc.selector)
return;
TypeFunction tf = cast(TypeFunction)fd.type;
- if (fd.objc.selector.paramCount != tf.parameterList.parameters.dim)
+ if (fd.objc.selector.paramCount != tf.parameterList.parameters.length)
fd.error("number of colons in Objective-C selector must match number of parameters");
if (fd.parent && fd.parent.isTemplateInstance())
fd.error("template cannot have an Objective-C selector attached");
diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d
index ca99b8b..de41727 100644
--- a/gcc/d/dmd/opover.d
+++ b/gcc/d/dmd/opover.d
@@ -286,9 +286,9 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
ae.e1 = ae.e1.expressionSemantic(sc);
ae.e1 = resolveProperties(sc, ae.e1);
Expression ae1old = ae.e1;
- const(bool) maybeSlice = (ae.arguments.dim == 0 || ae.arguments.dim == 1 && (*ae.arguments)[0].op == EXP.interval);
+ const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
IntervalExp ie = null;
- if (maybeSlice && ae.arguments.dim)
+ if (maybeSlice && ae.arguments.length)
{
ie = (*ae.arguments)[0].isIntervalExp();
}
@@ -425,9 +425,9 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
ae.e1 = ae.e1.expressionSemantic(sc);
ae.e1 = resolveProperties(sc, ae.e1);
Expression ae1old = ae.e1;
- const(bool) maybeSlice = (ae.arguments.dim == 0 || ae.arguments.dim == 1 && (*ae.arguments)[0].op == EXP.interval);
+ const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
IntervalExp ie = null;
- if (maybeSlice && ae.arguments.dim)
+ if (maybeSlice && ae.arguments.length)
{
ie = (*ae.arguments)[0].isIntervalExp();
}
@@ -457,7 +457,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
return result;
}
// Convert to IndexExp
- if (ae.arguments.dim == 1)
+ if (ae.arguments.length == 1)
{
result = new IndexExp(ae.loc, ae.e1, (*ae.arguments)[0]);
result = result.expressionSemantic(sc);
@@ -849,7 +849,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
* the mentioned member, then alias this may be
* used since the object will be fully initialised.
* If the struct is nested, the context pointer is considered
- * one of the members, hence the `ad1.fields.dim == 2 && ad1.vthis`
+ * one of the members, hence the `ad1.fields.length == 2 && ad1.vthis`
* condition.
*/
if (result.op != EXP.assign)
@@ -864,7 +864,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
{
// i.e: Rewrote `e1 = e2` -> `e1.some.var = e2`
// Ensure that `var` is the only field member in `ad`
- if (ad.fields.dim == 1 || (ad.fields.dim == 2 && ad.vthis))
+ if (ad.fields.length == 1 || (ad.fields.length == 2 && ad.vthis))
{
if (dve.var == ad.aliasthis.sym)
return result;
@@ -1043,11 +1043,11 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
{
auto tup1 = e.e1.isTupleExp();
auto tup2 = e.e2.isTupleExp();
- size_t dim = tup1.exps.dim;
- if (dim != tup2.exps.dim)
+ size_t dim = tup1.exps.length;
+ if (dim != tup2.exps.length)
{
e.error("mismatched tuple lengths, `%d` and `%d`",
- cast(int)dim, cast(int)tup2.exps.dim);
+ cast(int)dim, cast(int)tup2.exps.length);
return ErrorExp.get();
}
@@ -1101,9 +1101,9 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
ae.e1 = ae.e1.expressionSemantic(sc);
ae.e1 = resolveProperties(sc, ae.e1);
Expression ae1old = ae.e1;
- const(bool) maybeSlice = (ae.arguments.dim == 0 || ae.arguments.dim == 1 && (*ae.arguments)[0].op == EXP.interval);
+ const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
IntervalExp ie = null;
- if (maybeSlice && ae.arguments.dim)
+ if (maybeSlice && ae.arguments.length)
{
ie = (*ae.arguments)[0].isIntervalExp();
}
@@ -1553,7 +1553,7 @@ bool inferForeachAggregate(Scope* sc, bool isForeach, ref Expression feaggr, out
*/
bool inferApplyArgTypes(ForeachStatement fes, Scope* sc, ref Dsymbol sapply)
{
- if (!fes.parameters || !fes.parameters.dim)
+ if (!fes.parameters || !fes.parameters.length)
return false;
if (sapply) // prefer opApply
{
@@ -1604,7 +1604,7 @@ bool inferApplyArgTypes(ForeachStatement fes, Scope* sc, ref Dsymbol sapply)
case Tarray:
case Tsarray:
case Ttuple:
- if (fes.parameters.dim == 2)
+ if (fes.parameters.length == 2)
{
if (!p.type)
{
@@ -1623,7 +1623,7 @@ bool inferApplyArgTypes(ForeachStatement fes, Scope* sc, ref Dsymbol sapply)
case Taarray:
{
TypeAArray taa = tab.isTypeAArray();
- if (fes.parameters.dim == 2)
+ if (fes.parameters.length == 2)
{
if (!p.type)
{
@@ -1647,7 +1647,7 @@ bool inferApplyArgTypes(ForeachStatement fes, Scope* sc, ref Dsymbol sapply)
{
AggregateDeclaration ad = (tab.ty == Tclass) ? tab.isTypeClass().sym
: tab.isTypeStruct().sym;
- if (fes.parameters.dim == 1)
+ if (fes.parameters.length == 1)
{
if (!p.type)
{
@@ -1811,7 +1811,7 @@ private bool matchParamsToOpApply(TypeFunction tf, Parameters* parameters, bool
* Fill in missing types in parameters.
*/
const nparams = tdg.parameterList.length;
- if (nparams == 0 || nparams != parameters.dim || tdg.parameterList.varargs != VarArg.none)
+ if (nparams == 0 || nparams != parameters.length || tdg.parameterList.varargs != VarArg.none)
return nomatch; // parameter mismatch
foreach (u, p; *parameters)
diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d
index be28d08..a9c5425 100644
--- a/gcc/d/dmd/optimize.d
+++ b/gcc/d/dmd/optimize.d
@@ -225,7 +225,7 @@ package void setLengthVarIfKnown(VarDeclaration lengthVar, Expression arr)
if (auto se = arr.isStringExp())
len = se.len;
else if (auto ale = arr.isArrayLiteralExp())
- len = ale.elements.dim;
+ len = ale.elements.length;
else
{
auto tsa = arr.type.toBasetype().isTypeSArray();
@@ -358,7 +358,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
void visitAssocArrayLiteral(AssocArrayLiteralExp e)
{
- assert(e.keys.dim == e.values.dim);
+ assert(e.keys.length == e.values.length);
foreach (i, ref ekey; (*e.keys)[])
{
expOptimize(ekey, result & WANTexpand);
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index 6fb542f..93c7ea0 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -425,8 +425,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
case TOK.traits:
Ldeclaration:
a = parseDeclarations(false, pAttrs, pAttrs.comment);
- if (a && a.dim)
- *pLastDecl = (*a)[a.dim - 1];
+ if (a && a.length)
+ *pLastDecl = (*a)[a.length - 1];
break;
case TOK.this_:
@@ -491,6 +491,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
*/
if (mod.isRoot() && (global.params.useUnitTests || global.params.ddoc.doOutput || global.params.dihdr.doOutput))
{
+ linkage = LINK.d; // unittests have D linkage
s = parseUnitTest(pAttrs);
if (*pLastDecl)
(*pLastDecl).ddocUnittest = cast(AST.UnitTestDeclaration)s;
@@ -698,8 +699,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
if (token.value == TOK.identifier && hasOptionalParensThen(peek(&token), TOK.assign))
{
a = parseAutoDeclarations(getStorageClass!AST(pAttrs), pAttrs.comment);
- if (a && a.dim)
- *pLastDecl = (*a)[a.dim - 1];
+ if (a && a.length)
+ *pLastDecl = (*a)[a.length - 1];
if (pAttrs.udas)
{
s = new AST.UserAttributeDeclaration(pAttrs.udas, a);
@@ -725,8 +726,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
deprecation("usage of the `body` keyword is deprecated. Use `do` instead.");
a = parseDeclarations(true, pAttrs, pAttrs.comment);
- if (a && a.dim)
- *pLastDecl = (*a)[a.dim - 1];
+ if (a && a.length)
+ *pLastDecl = (*a)[a.length - 1];
if (pAttrs.udas)
{
s = new AST.UserAttributeDeclaration(pAttrs.udas, a);
@@ -817,8 +818,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
if (res.idents)
{
assert(res.link == LINK.cpp);
- assert(res.idents.dim);
- for (size_t i = res.idents.dim; i;)
+ assert(res.idents.length);
+ for (size_t i = res.idents.length; i;)
{
Identifier id = (*res.idents)[--i];
if (s)
@@ -833,8 +834,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
else if (res.identExps)
{
assert(res.link == LINK.cpp);
- assert(res.identExps.dim);
- for (size_t i = res.identExps.dim; i;)
+ assert(res.identExps.length);
+ for (size_t i = res.identExps.length; i;)
{
AST.Expression exp = (*res.identExps)[--i];
if (s)
@@ -1059,7 +1060,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
decldefs.push(s);
addComment(s, pAttrs.comment);
}
- else if (a && a.dim)
+ else if (a && a.length)
{
decldefs.append(a);
}
@@ -3786,10 +3787,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
break;
}
}
- assert(dimStack.dim > 0);
+ assert(dimStack.length > 0);
// We're good. Replay indices in the reverse order.
tid = cast(AST.TypeQualified)t;
- while (dimStack.dim)
+ while (dimStack.length)
{
tid.addIndex(dimStack.pop());
}
@@ -4341,6 +4342,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
/* Declarations that start with `alias`
*/
bool isAliasDeclaration = false;
+ auto aliasLoc = token.loc;
if (token.value == TOK.alias_)
{
if (auto a = parseAliasDeclarations(comment))
@@ -4488,7 +4490,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
if (ident)
checkCstyleTypeSyntax(loc, t, alt, ident);
else if (!isThis && (t != AST.Type.terror))
- error("no identifier for declarator `%s`", t.toChars());
+ noIdentifierForDeclarator(t);
if (isAliasDeclaration)
{
@@ -4517,7 +4519,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
else
error("alias cannot have initializer");
}
- v = new AST.AliasDeclaration(loc, ident, t);
+ v = new AST.AliasDeclaration(aliasLoc, ident, t);
v.storage_class = storage_class;
if (pAttrs)
@@ -4706,6 +4708,19 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
return a;
}
+ /// Report an error that a declaration of type `t` is missing an identifier
+ /// The parser is expected to sit on the next token after the type.
+ private void noIdentifierForDeclarator(AST.Type t)
+ {
+ error("no identifier for declarator `%s`", t.toChars());
+ // A common mistake is to use a reserved keyword as an identifier, e.g. `in` or `out`
+ if (token.isKeyword)
+ {
+ errorSupplemental(token.loc, "`%s` is a keyword, perhaps append `_` to make it an identifier", token.toChars());
+ nextToken();
+ }
+ }
+
/********************************
* Parse AliasReassignment:
* identifier = type;
@@ -4881,7 +4896,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
// parseAttributes shouldn't have set these variables
assert(link == linkage && !setAlignment && ealign is null);
auto tpl_ = cast(AST.TemplateDeclaration) s;
- if (tpl_ is null || tpl_.members.dim != 1)
+ if (tpl_ is null || tpl_.members.length != 1)
{
error("user-defined attributes are not allowed on `alias` declarations");
}
@@ -4889,7 +4904,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
{
auto fd = cast(AST.FuncLiteralDeclaration) (*tpl_.members)[0];
auto tf = cast(AST.TypeFunction) fd.type;
- assert(tf.parameterList.parameters.dim > 0);
+ assert(tf.parameterList.parameters.length > 0);
auto as = new AST.Dsymbols();
(*tf.parameterList.parameters)[0].userAttribDecl = new AST.UserAttributeDeclaration(udas, as);
}
@@ -5489,7 +5504,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
at = parseType(&ai);
if (!ai)
- error("no identifier for declarator `%s`", at.toChars());
+ noIdentifierForDeclarator(at);
Larg:
auto p = new AST.Parameter(storageClass, at, ai, null, null);
parameters.push(p);
@@ -5513,7 +5528,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
nextToken();
AST.Expression aggr = parseExpression();
- if (token.value == TOK.slice && parameters.dim == 1)
+ if (token.value == TOK.slice && parameters.length == 1)
{
AST.Parameter p = (*parameters)[0];
nextToken();
@@ -5897,11 +5912,11 @@ LagainStc:
Ldeclaration:
{
AST.Dsymbols* a = parseDeclarations(false, null, null);
- if (a.dim > 1)
+ if (a.length > 1)
{
auto as = new AST.Statements();
- as.reserve(a.dim);
- foreach (i; 0 .. a.dim)
+ as.reserve(a.length);
+ foreach (i; 0 .. a.length)
{
AST.Dsymbol d = (*a)[i];
s = new AST.ExpStatement(loc, d);
@@ -5909,7 +5924,7 @@ LagainStc:
}
s = new AST.CompoundDeclarationStatement(loc, as);
}
- else if (a.dim == 1)
+ else if (a.length == 1)
{
AST.Dsymbol d = (*a)[0];
s = new AST.ExpStatement(loc, d);
@@ -6283,7 +6298,7 @@ LagainStc:
*/
if (token.value == TOK.slice)
{
- if (cases.dim > 1)
+ if (cases.length > 1)
error("only one `case` allowed for start of case range");
nextToken();
check(TOK.case_);
@@ -6322,7 +6337,7 @@ LagainStc:
else
{
// Keep cases in order by building the case statements backwards
- for (size_t i = cases.dim; i; i--)
+ for (size_t i = cases.length; i; i--)
{
exp = cases[i - 1];
s = new AST.CaseStatement(loc, exp, s);
@@ -6741,7 +6756,7 @@ LagainStc:
case TOK.leftBracket:
/* Scan ahead to see if it is an array initializer or
* an expression.
- * If it ends with a ';' ',' or '}', it is an array initializer.
+ * If it ends with a ';' ',' or ']', it is an array initializer.
*/
int brackets = 1;
for (auto t = peek(&token); 1; t = peek(t))
@@ -8242,6 +8257,13 @@ LagainStc:
t = AST.Type.tdchar;
goto LabelX;
LabelX:
+ const next = peekNext();
+ if (next != TOK.leftParenthesis && next != TOK.dot)
+ {
+ // defer error for better diagnostics
+ e = new AST.TypeExp(loc, parseType);
+ break;
+ }
nextToken();
if (token.value == TOK.leftParenthesis)
{
@@ -8249,7 +8271,7 @@ LagainStc:
e = new AST.CallExp(loc, e, parseArguments());
break;
}
- check(TOK.dot, t.toChars());
+ check(TOK.dot);
if (token.value != TOK.identifier)
{
error("found `%s` when expecting identifier following `%s`.", token.toChars(), t.toChars());
@@ -8477,7 +8499,7 @@ LagainStc:
while (token.value != TOK.rightBracket && token.value != TOK.endOfFile)
{
e = parseAssignExp();
- if (token.value == TOK.colon && (keys || values.dim == 0))
+ if (token.value == TOK.colon && (keys || values.length == 0))
{
nextToken();
if (!keys)
diff --git a/gcc/d/dmd/root/array.d b/gcc/d/dmd/root/array.d
index 212fe96..5c01940 100644
--- a/gcc/d/dmd/root/array.d
+++ b/gcc/d/dmd/root/array.d
@@ -352,7 +352,9 @@ public:
}
alias opDollar = length;
- alias dim = length;
+
+ deprecated("use `.length` instead")
+ extern(D) size_t dim() const @nogc nothrow pure @safe { return length; }
}
unittest
diff --git a/gcc/d/dmd/root/filename.d b/gcc/d/dmd/root/filename.d
index 226141d..f6a4515 100644
--- a/gcc/d/dmd/root/filename.d
+++ b/gcc/d/dmd/root/filename.d
@@ -55,7 +55,7 @@ alias Strings = Array!(const(char)*);
// Check whether character is a directory separator
-private bool isDirSeparator(char c) pure nothrow @nogc @safe
+bool isDirSeparator(char c) pure nothrow @nogc @safe
{
version (Windows)
{
diff --git a/gcc/d/dmd/root/utf.d b/gcc/d/dmd/root/utf.d
index eb198fc..0d230e7 100644
--- a/gcc/d/dmd/root/utf.d
+++ b/gcc/d/dmd/root/utf.d
@@ -396,6 +396,26 @@ void utf_encode(int sz, void* s, dchar c)
}
/********************************************
+ * Checks whether an Unicode code point is a bidirectional
+ * control character.
+ */
+@safe bool isBidiControl(dchar c)
+{
+ // Source: https://www.unicode.org/versions/Unicode15.0.0, table 23-3.
+ switch(c)
+ {
+ case '\u061C':
+ case '\u200E':
+ case '\u200F':
+ case '\u202A': .. case '\u202E':
+ case '\u2066': .. case '\u2069':
+ return true;
+ default:
+ return false;
+ }
+}
+
+/********************************************
* Decode a UTF-8 sequence as a single UTF-32 code point.
* Params:
* s = UTF-8 sequence
diff --git a/gcc/d/dmd/sapply.d b/gcc/d/dmd/sapply.d
index 26fba8f..adfae32 100644
--- a/gcc/d/dmd/sapply.d
+++ b/gcc/d/dmd/sapply.d
@@ -68,7 +68,7 @@ public:
override void visit(CompoundStatement s)
{
- for (size_t i = 0; i < s.statements.dim; i++)
+ for (size_t i = 0; i < s.statements.length; i++)
if (doCond((*s.statements)[i]))
return;
applyTo(s);
@@ -76,7 +76,7 @@ public:
override void visit(UnrolledLoopStatement s)
{
- for (size_t i = 0; i < s.statements.dim; i++)
+ for (size_t i = 0; i < s.statements.length; i++)
if (doCond((*s.statements)[i]))
return;
applyTo(s);
@@ -151,7 +151,7 @@ public:
{
if (doCond(s._body))
return;
- for (size_t i = 0; i < s.catches.dim; i++)
+ for (size_t i = 0; i < s.catches.length; i++)
if (doCond((*s.catches)[i].handler))
return;
applyTo(s);
diff --git a/gcc/d/dmd/scope.h b/gcc/d/dmd/scope.h
index b29c599..8b9e59e 100644
--- a/gcc/d/dmd/scope.h
+++ b/gcc/d/dmd/scope.h
@@ -28,43 +28,38 @@ class CPPNamespaceDeclaration;
#include "dsymbol.h"
-enum
+enum class CSX : uint16_t
{
- CSXthis_ctor = 1, // called this()
- CSXsuper_ctor = 2, // called super()
- CSXthis = 4, // referenced this
- CSXsuper = 8, // referenced super
- CSXlabel = 0x10, // seen a label
- CSXreturn = 0x20, // seen a return statement
- CSXany_ctor = 0x40, // either this() or super() was called
- CSXhalt = 0x80, // assert(0)
+ none = 0,
+ this_ctor = 1, // called this()
+ super_ctor = 2, // called super()
+ label = 4, // seen a label
+ return_ = 8, // seen a return statement
+ any_ctor = 0x10, // either this() or super() was called
+ halt = 0x20, // assert(0)
};
-enum
+enum class SCOPE
{
// Flags that would not be inherited beyond scope nesting
- SCOPEctor = 0x0001, // constructor type
- SCOPEcondition = 0x0004, // inside static if/assert condition
- SCOPEdebug = 0x0008, // inside debug conditional
+ ctor = 0x0001, // constructor type
+ noaccesscheck = 0x0002, // don't do access checks
+ condition = 0x0004, // inside static if/assert condition
+ debug_ = 0x0008, // inside debug conditional
// Flags that would be inherited beyond scope nesting
- SCOPEnoaccesscheck = 0x0002, // don't do access checks
- SCOPEconstraint = 0x0010, // inside template constraint
- SCOPEinvariant = 0x0020, // inside invariant code
- SCOPErequire = 0x0040, // inside in contract code
- SCOPEensure = 0x0060, // inside out contract code
- SCOPEcontract = 0x0060, // [mask] we're inside contract code
- SCOPEctfe = 0x0080, // inside a ctfe-only expression
- SCOPEcompile = 0x0100, // inside __traits(compile)
- SCOPEignoresymbolvisibility = 0x0200, // ignore symbol visibility (Bugzilla 15907)
-
- SCOPEfree = 0x8000, // is on free list
- SCOPEfullinst = 0x10000, // fully instantiate templates
- SCOPEalias = 0x20000, // inside alias declaration
-
- // The following are mutually exclusive
- SCOPEprintf = 0x40000, // printf-style function
- SCOPEscanf = 0x80000, // scanf-style function
+ constraint = 0x0010, // inside template constraint
+ invariant_ = 0x0020, // inside invariant code
+ require = 0x0040, // inside in contract code
+ ensure = 0x0060, // inside out contract code
+ contract = 0x0060, // [mask] we're inside contract code
+ ctfe = 0x0080, // inside a ctfe-only expression
+ compile = 0x0100, // inside __traits(compile)
+ ignoresymbolvisibility = 0x0200, // ignore symbol visibility (Bugzilla 15907)
+
+ Cfile = 0x0800, // C semantics apply
+ free = 0x8000, // is on free list
+ fullinst = 0x10000, // fully instantiate templates
};
struct Scope
@@ -74,6 +69,7 @@ struct Scope
Module *_module; // Root module
ScopeDsymbol *scopesym; // current symbol
FuncDeclaration *func; // function we are in
+ VarDeclaration *varDecl; // variable we are in during semantic2
Dsymbol *parent; // parent to use
LabelStatement *slabel; // enclosing labelled statement
SwitchStatement *sw; // enclosing switch statement
@@ -98,8 +94,8 @@ struct Scope
Module *minst; // root module where the instantiated templates should belong to
TemplateInstance *tinst; // enclosing template instance
- unsigned char callSuper; // primitive flow analysis for constructors
- unsigned char *fieldinit;
+ CSX callSuper; // primitive flow analysis for constructors
+ CSX *fieldinit;
size_t fieldinit_dim;
AlignDeclaration *aligndecl; // alignment for struct members
@@ -128,24 +124,6 @@ struct Scope
AliasDeclaration *aliasAsg; // if set, then aliasAsg is being assigned a new value,
// do not set wasRead for it
- Scope();
-
- Scope *copy();
-
- Scope *push();
- Scope *push(ScopeDsymbol *ss);
- Scope *pop();
-
- Scope *startCTFE();
- Scope *endCTFE();
Dsymbol *search(const Loc &loc, Identifier *ident, Dsymbol **pscopesym, int flags = IgnoreNone);
-
- ClassDeclaration *getClassScope();
- AggregateDeclaration *getStructClassScope();
-
- structalign_t alignment();
-
- bool isDeprecated() const;
- bool isFromSpeculativeSemanticContext() const;
};
diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d
index bf18a21..4795bcf 100644
--- a/gcc/d/dmd/semantic2.d
+++ b/gcc/d/dmd/semantic2.d
@@ -163,7 +163,7 @@ private extern(C++) final class Semantic2Visitor : Visitor
if (needGagging)
oldGaggedErrors = global.startGagging();
- for (size_t i = 0; i < tempinst.members.dim; i++)
+ for (size_t i = 0; i < tempinst.members.length; i++)
{
Dsymbol s = (*tempinst.members)[i];
static if (LOG)
@@ -211,7 +211,7 @@ private extern(C++) final class Semantic2Visitor : Visitor
sc = sc.push(tmix);
sc.tinst = tmix;
sc.minst = tmix.minst;
- for (size_t i = 0; i < tmix.members.dim; i++)
+ for (size_t i = 0; i < tmix.members.length; i++)
{
Dsymbol s = (*tmix.members)[i];
static if (LOG)
@@ -230,6 +230,8 @@ private extern(C++) final class Semantic2Visitor : Visitor
return;
//printf("VarDeclaration::semantic2('%s')\n", toChars());
+ sc.varDecl = vd;
+ scope(exit) sc.varDecl = null;
if (vd.aliassym) // if it's a tuple
{
@@ -333,7 +335,7 @@ private extern(C++) final class Semantic2Visitor : Visitor
if (mod.members)
{
// Pass 2 semantic routines: do initializers and function bodies
- for (size_t i = 0; i < mod.members.dim; i++)
+ for (size_t i = 0; i < mod.members.length; i++)
{
Dsymbol s = (*mod.members)[i];
s.semantic2(sc);
@@ -520,7 +522,7 @@ private extern(C++) final class Semantic2Visitor : Visitor
return;
Scope* sc2 = ad.newScope(sc);
- for (size_t i = 0; i < d.dim; i++)
+ for (size_t i = 0; i < d.length; i++)
{
Dsymbol s = (*d)[i];
s.semantic2(sc2);
@@ -559,7 +561,7 @@ private extern(C++) final class Semantic2Visitor : Visitor
override void visit(UserAttributeDeclaration uad)
{
- if (!uad.decl || !uad.atts || !uad.atts.dim || !uad._scope)
+ if (!uad.decl || !uad.atts || !uad.atts.length || !uad._scope)
return visit(cast(AttribDeclaration)uad);
Expression* lastTag;
@@ -609,7 +611,7 @@ private extern(C++) final class Semantic2Visitor : Visitor
ad.determineSize(ad.loc);
- for (size_t i = 0; i < ad.members.dim; i++)
+ for (size_t i = 0; i < ad.members.length; i++)
{
Dsymbol s = (*ad.members)[i];
//printf("\t[%d] %s\n", i, s.toChars());
diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d
index 8ea419a..cc75aa5 100644
--- a/gcc/d/dmd/semantic3.d
+++ b/gcc/d/dmd/semantic3.d
@@ -127,7 +127,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
if (needGagging)
oldGaggedErrors = global.startGagging();
- for (size_t i = 0; i < tempinst.members.dim; i++)
+ for (size_t i = 0; i < tempinst.members.length; i++)
{
Dsymbol s = (*tempinst.members)[i];
s.semantic3(sc);
@@ -170,7 +170,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
uint olderrors = global.errors;
- for (size_t i = 0; i < tmix.members.dim; i++)
+ for (size_t i = 0; i < tmix.members.length; i++)
{
Dsymbol s = (*tmix.members)[i];
s.semantic3(sc);
@@ -197,7 +197,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
if (mod.members)
{
// Pass 3 semantic routines: do initializers and function bodies
- for (size_t i = 0; i < mod.members.dim; i++)
+ for (size_t i = 0; i < mod.members.length; i++)
{
Dsymbol s = (*mod.members)[i];
//printf("Module %s: %s.semantic3()\n", toChars(), s.toChars());
@@ -586,7 +586,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
*/
if (ad2 && funcdecl.isCtorDeclaration())
{
- sc2.ctorflow.allocFieldinit(ad2.fields.dim);
+ sc2.ctorflow.allocFieldinit(ad2.fields.length);
foreach (v; ad2.fields)
{
v.ctorinit = 0;
@@ -624,7 +624,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
if (funcdecl.returns && !funcdecl.fbody.isErrorStatement())
{
- for (size_t i = 0; i < funcdecl.returns.dim;)
+ for (size_t i = 0; i < funcdecl.returns.length;)
{
Expression exp = (*funcdecl.returns)[i].exp;
if (exp.op == EXP.variable && (cast(VarExp)exp).var == funcdecl.vresult)
@@ -661,7 +661,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
* ctor consts were initialized.
*/
ScopeDsymbol pd = funcdecl.toParent().isScopeDsymbol();
- for (size_t i = 0; i < pd.members.dim; i++)
+ for (size_t i = 0; i < pd.members.length; i++)
{
Dsymbol s = (*pd.members)[i];
s.checkCtorConstInit();
@@ -829,7 +829,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
/* Cannot move this loop into NrvoWalker, because
* returns[i] may be in the nested delegate for foreach-body.
*/
- for (size_t i = 0; i < funcdecl.returns.dim; i++)
+ for (size_t i = 0; i < funcdecl.returns.length; i++)
{
ReturnStatement rs = (*funcdecl.returns)[i];
Expression exp = rs.exp;
@@ -1068,7 +1068,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
// Merge in initialization of 'out' parameters
if (funcdecl.parameters)
{
- for (size_t i = 0; i < funcdecl.parameters.dim; i++)
+ for (size_t i = 0; i < funcdecl.parameters.length; i++)
{
VarDeclaration v = (*funcdecl.parameters)[i];
if (v.storage_class & STC.out_)
@@ -1253,7 +1253,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
// Fix up forward-referenced gotos
if (funcdecl.gotos && !funcdecl.isCsymbol())
{
- for (size_t i = 0; i < funcdecl.gotos.dim; ++i)
+ for (size_t i = 0; i < funcdecl.gotos.length; ++i)
{
(*funcdecl.gotos)[i].checkLabel();
}
@@ -1526,7 +1526,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
return;
Scope* sc2 = ad.newScope(sc);
- for (size_t i = 0; i < d.dim; i++)
+ for (size_t i = 0; i < d.length; i++)
{
Dsymbol s = (*d)[i];
s.semantic3(sc2);
@@ -1551,7 +1551,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
auto sc2 = ad.newScope(sc);
- for (size_t i = 0; i < ad.members.dim; i++)
+ for (size_t i = 0; i < ad.members.length; i++)
{
Dsymbol s = (*ad.members)[i];
s.semantic3(sc2);
@@ -1612,7 +1612,7 @@ private struct FuncDeclSem3
{
if (funcdecl.frequires)
{
- for (size_t i = 0; i < funcdecl.foverrides.dim; i++)
+ for (size_t i = 0; i < funcdecl.foverrides.length; i++)
{
FuncDeclaration fdv = funcdecl.foverrides[i];
if (fdv.fbody && !fdv.frequires)
diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d
index a519f3b..91a802e 100644
--- a/gcc/d/dmd/statement.d
+++ b/gcc/d/dmd/statement.d
@@ -610,7 +610,7 @@ extern (C++) class CompoundStatement : Statement
override final inout(Statement) last() inout nothrow pure
{
Statement s = null;
- for (size_t i = statements.dim; i; --i)
+ for (size_t i = statements.length; i; --i)
{
s = cast(Statement)(*statements)[i - 1];
if (s)
@@ -640,7 +640,7 @@ extern (C++) final class CompoundDeclarationStatement : CompoundStatement
override CompoundDeclarationStatement syntaxCopy()
{
- auto a = new Statements(statements.dim);
+ auto a = new Statements(statements.length);
foreach (i, s; *statements)
{
(*a)[i] = s ? s.syntaxCopy() : null;
@@ -670,7 +670,7 @@ extern (C++) final class UnrolledLoopStatement : Statement
override UnrolledLoopStatement syntaxCopy()
{
- auto a = new Statements(statements.dim);
+ auto a = new Statements(statements.length);
foreach (i, s; *statements)
{
(*a)[i] = s ? s.syntaxCopy() : null;
@@ -1571,7 +1571,7 @@ extern (C++) final class TryCatchStatement : Statement
override TryCatchStatement syntaxCopy()
{
- auto a = new Catches(catches.dim);
+ auto a = new Catches(catches.length);
foreach (i, c; *catches)
{
(*a)[i] = c.syntaxCopy();
@@ -2019,7 +2019,7 @@ extern (C++) final class CompoundAsmStatement : CompoundStatement
override CompoundAsmStatement syntaxCopy()
{
- auto a = new Statements(statements.dim);
+ auto a = new Statements(statements.length);
foreach (i, s; *statements)
{
(*a)[i] = s ? s.syntaxCopy() : null;
@@ -2048,7 +2048,7 @@ extern (C++) final class ImportStatement : Statement
override ImportStatement syntaxCopy()
{
- auto m = new Dsymbols(imports.dim);
+ auto m = new Dsymbols(imports.length);
foreach (i, s; *imports)
{
(*m)[i] = s.syntaxCopy(null);
diff --git a/gcc/d/dmd/statement_rewrite_walker.d b/gcc/d/dmd/statement_rewrite_walker.d
index b1f659d..7b3a13b 100644
--- a/gcc/d/dmd/statement_rewrite_walker.d
+++ b/gcc/d/dmd/statement_rewrite_walker.d
@@ -48,9 +48,9 @@ public:
override void visit(CompoundStatement s)
{
- if (s.statements && s.statements.dim)
+ if (s.statements && s.statements.length)
{
- for (size_t i = 0; i < s.statements.dim; i++)
+ for (size_t i = 0; i < s.statements.length; i++)
{
if ((*s.statements)[i])
visitStmt((*s.statements)[i]);
@@ -65,9 +65,9 @@ public:
override void visit(UnrolledLoopStatement s)
{
- if (s.statements && s.statements.dim)
+ if (s.statements && s.statements.length)
{
- for (size_t i = 0; i < s.statements.dim; i++)
+ for (size_t i = 0; i < s.statements.length; i++)
{
if ((*s.statements)[i])
visitStmt((*s.statements)[i]);
@@ -161,9 +161,9 @@ public:
{
if (s._body)
visitStmt(s._body);
- if (s.catches && s.catches.dim)
+ if (s.catches && s.catches.length)
{
- for (size_t i = 0; i < s.catches.dim; i++)
+ for (size_t i = 0; i < s.catches.length; i++)
{
Catch c = (*s.catches)[i];
if (c && c.handler)
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index 4f9baf8..b372fc2 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -249,7 +249,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
}
}
- for (size_t i = 0; i < cs.statements.dim;)
+ for (size_t i = 0; i < cs.statements.length;)
{
Statement s = (*cs.statements)[i];
if (!s)
@@ -312,7 +312,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
return true;
}
- if (!sfinally && isEmpty((*cs.statements)[i + 1 .. cs.statements.dim]))
+ if (!sfinally && isEmpty((*cs.statements)[i + 1 .. cs.statements.length]))
{
}
else
@@ -358,7 +358,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
}
else if (sfinally)
{
- if (0 && i + 1 == cs.statements.dim)
+ if (0 && i + 1 == cs.statements.length)
{
cs.statements.push(sfinally);
}
@@ -645,6 +645,13 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
CommaExp.allow(fs.increment);
fs.increment = fs.increment.expressionSemantic(sc);
fs.increment = resolveProperties(sc, fs.increment);
+ // @@@DEPRECATED_2.112@@@
+ // remove gagging and deprecation() to turn deprecation into an error when
+ // deprecation cycle is over
+ const olderrors = global.startGagging();
+ discardValue(fs.increment);
+ if (global.endGagging(olderrors))
+ fs.increment.deprecation("`%s` has no effect", fs.increment.toChars());
if (checkNonAssignmentArrayOp(fs.increment))
fs.increment = ErrorExp.get();
fs.increment = fs.increment.optimize(WANTvalue);
@@ -693,7 +700,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
}
const loc = fs.loc;
- const dim = fs.parameters.dim;
+ const dim = fs.parameters.length;
fs.func = sc.func;
if (fs.func.fes)
@@ -791,7 +798,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
}
}
- //printf("dim = %d, parameters.dim = %d\n", dim, parameters.dim);
+ //printf("dim = %d, parameters.length = %d\n", dim, parameters.length);
if (foundMismatch && dim != foreachParamCount)
{
const(char)* plural = foreachParamCount > 1 ? "s" : "";
@@ -854,7 +861,6 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
result = s;
}
- TypeAArray taa = null;
Type tn = null;
Type tnv = null;
Statement apply()
@@ -865,26 +871,25 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
TypeFunction tfld = null;
if (sapply)
{
- FuncDeclaration fdapply = sapply.isFuncDeclaration();
- if (fdapply)
+ if (auto fdapply = sapply.isFuncDeclaration())
{
- assert(fdapply.type && fdapply.type.ty == Tfunction);
- tfld = cast(TypeFunction)fdapply.type.typeSemantic(loc, sc2);
+ assert(fdapply.type && fdapply.type.isTypeFunction());
+ tfld = fdapply.type.typeSemantic(loc, sc2).isTypeFunction();
goto Lget;
}
- else if (tab.ty == Tdelegate)
+ else if (tab.isTypeDelegate())
{
- tfld = cast(TypeFunction)tab.nextOf();
+ tfld = tab.nextOf().isTypeFunction();
Lget:
//printf("tfld = %s\n", tfld.toChars());
- if (tfld.parameterList.parameters.dim == 1)
+ if (tfld.parameterList.parameters.length == 1)
{
Parameter p = tfld.parameterList[0];
- if (p.type && p.type.ty == Tdelegate)
+ if (p.type && p.type.isTypeDelegate())
{
auto t = p.type.typeSemantic(loc, sc2);
assert(t.ty == Tdelegate);
- tfld = cast(TypeFunction)t.nextOf();
+ tfld = t.nextOf().isTypeFunction();
}
}
}
@@ -902,12 +907,11 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
{
// 'Promote' it to this scope, and replace with a return
fs.cases.push(gs);
- ss.statement = new ReturnStatement(Loc.initial, new IntegerExp(fs.cases.dim + 1));
+ ss.statement = new ReturnStatement(Loc.initial, new IntegerExp(fs.cases.length + 1));
}
}
Expression e = null;
- Expression ec;
if (vinit)
{
e = new DeclarationExp(loc, vinit);
@@ -916,19 +920,22 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
return null;
}
- if (taa)
- ec = applyAssocArray(fs, flde, taa);
- else if (tab.ty == Tarray || tab.ty == Tsarray)
- ec = applyArray(fs, flde, sc2, tn, tnv, tab.ty);
- else if (tab.ty == Tdelegate)
- ec = applyDelegate(fs, flde, sc2, tab);
- else
- ec = applyOpApply(fs, tab, sapply, sc2, flde);
+ Expression ec;
+ switch (tab.ty)
+ {
+ case Tarray:
+ case Tsarray: ec = applyArray (fs, flde, tab, sc2, tn, tnv); break;
+ case Tdelegate: ec = applyDelegate (fs, flde, tab, sc2); break;
+ case Taarray: ec = applyAssocArray(fs, flde, tab); break;
+ default: ec = applyOpApply (fs, flde, tab, sc2, sapply); break;
+ }
if (!ec)
return null;
+
e = Expression.combine(e, ec);
return loopReturn(e, fs.cases, loc);
}
+
switch (tab.ty)
{
case Tarray:
@@ -966,7 +973,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
* 2. foreach body is lowered to _aApply (see special case below).
*/
Type tv = (*fs.parameters)[1].type.toBasetype();
- if ((tab.ty == Tarray ||
+ if ((tab.isTypeDArray() ||
(tn.ty != tv.ty && tn.ty.isSomeChar && tv.ty.isSomeChar)) &&
!Type.tsize_t.implicitConvTo(tindex))
{
@@ -1021,9 +1028,8 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
return retError();
}
}
- if (tab.ty == Tsarray)
+ if (auto ta = tab.isTypeSArray())
{
- TypeSArray ta = cast(TypeSArray)tab;
IntRange dimrange = getIntRange(ta.dim);
// https://issues.dlang.org/show_bug.cgi?id=12504
dimrange.imax = SignExtendedNumber(dimrange.imax.value-1);
@@ -1072,10 +1078,10 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
auto ie = new ExpInitializer(loc, new SliceExp(loc, fs.aggr, null, null));
const valueIsRef = (*fs.parameters)[$ - 1].isReference();
VarDeclaration tmp;
- if (fs.aggr.op == EXP.arrayLiteral && !valueIsRef)
+ if (fs.aggr.isArrayLiteralExp() && !valueIsRef)
{
- auto ale = cast(ArrayLiteralExp)fs.aggr;
- size_t edim = ale.elements ? ale.elements.dim : 0;
+ auto ale = fs.aggr.isArrayLiteralExp();
+ size_t edim = ale.elements ? ale.elements.length : 0;
auto telem = (*fs.parameters)[dim - 1].type;
// https://issues.dlang.org/show_bug.cgi?id=12936
@@ -1182,7 +1188,6 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
if (checkForArgTypes(fs))
return retError();
- taa = cast(TypeAArray)tab;
if (dim < 1 || dim > 2)
{
fs.error("only one or two arguments for associative array `foreach`");
@@ -1207,8 +1212,8 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
* }
*/
auto ad = (tab.ty == Tclass) ?
- cast(AggregateDeclaration)(cast(TypeClass)tab).sym :
- cast(AggregateDeclaration)(cast(TypeStruct)tab).sym;
+ cast(AggregateDeclaration)tab.isTypeClass().sym :
+ cast(AggregateDeclaration)tab.isTypeStruct().sym;
Identifier idfront;
Identifier idpopFront;
if (fs.op == TOK.foreach_)
@@ -1229,7 +1234,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
*/
VarDeclaration r;
Statement _init;
- if (vinit && fs.aggr.op == EXP.variable && (cast(VarExp)fs.aggr).var == vinit)
+ if (vinit && fs.aggr.isVarExp() && fs.aggr.isVarExp().var == vinit)
{
r = vinit;
_init = new ExpStatement(loc, vinit);
@@ -1279,9 +1284,8 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
}
if (!tfront || tfront.ty == Terror)
return rangeError();
- if (tfront.toBasetype().ty == Tfunction)
+ if (auto ftt = tfront.toBasetype().isTypeFunction())
{
- auto ftt = cast(TypeFunction)tfront.toBasetype();
tfront = tfront.toBasetype().nextOf();
if (!ftt.isref)
{
@@ -1323,17 +1327,17 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
auto exps = new Expressions();
exps.push(ve);
int pos = 0;
- while (exps.dim < dim)
+ while (exps.length < dim)
{
pos = expandAliasThisTuples(exps, pos);
if (pos == -1)
break;
}
- if (exps.dim != dim)
+ if (exps.length != dim)
{
- const(char)* plural = exps.dim > 1 ? "s" : "";
+ const(char)* plural = exps.length > 1 ? "s" : "";
fs.error("cannot infer argument types, expected %llu argument%s, not %llu",
- cast(ulong) exps.dim, plural, cast(ulong) dim);
+ cast(ulong) exps.length, plural, cast(ulong) dim);
return retError();
}
@@ -1389,8 +1393,8 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
}
}
- private static extern(D) Expression applyOpApply(ForeachStatement fs, Type tab, Dsymbol sapply,
- Scope* sc2, Expression flde)
+ private static extern(D) Expression applyOpApply(ForeachStatement fs, Expression flde,
+ Type tab, Scope* sc2, Dsymbol sapply)
{
version (none)
{
@@ -1425,7 +1429,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
}
private static extern(D) Expression applyDelegate(ForeachStatement fs, Expression flde,
- Scope* sc2, Type tab)
+ Type tab, Scope* sc2)
{
Expression ec;
/* Call:
@@ -1450,10 +1454,10 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
}
private static extern(D) Expression applyArray(ForeachStatement fs, Expression flde,
- Scope* sc2, Type tn, Type tnv, TY tabty)
+ Type tab, Scope* sc2, Type tn, Type tnv)
{
Expression ec;
- const dim = fs.parameters.dim;
+ const dim = fs.parameters.length;
const loc = fs.loc;
/* Call:
* _aApply(aggr, flde)
@@ -1501,7 +1505,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
params.push(new Parameter(0, dgty, null, null, null));
fdapply = FuncDeclaration.genCfunc(params, Type.tint32, fdname.ptr);
- if (tabty == Tsarray)
+ if (tab.isTypeSArray())
fs.aggr = fs.aggr.castTo(sc2, tn.arrayOf());
// paint delegate argument to the type runtime expects
Expression fexp = flde;
@@ -1516,10 +1520,11 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
return ec;
}
- private static extern(D) Expression applyAssocArray(ForeachStatement fs, Expression flde, TypeAArray taa)
+ private static extern(D) Expression applyAssocArray(ForeachStatement fs, Expression flde, Type tab)
{
+ auto taa = tab.isTypeAArray();
Expression ec;
- const dim = fs.parameters.dim;
+ const dim = fs.parameters.length;
// Check types
Parameter p = (*fs.parameters)[0];
bool isRef = (p.storageClass & STC.ref_) != 0;
@@ -1593,7 +1598,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
private static extern(D) Statement loopReturn(Expression e, Statements* cases, const ref Loc loc)
{
- if (!cases.dim)
+ if (!cases.length)
{
// Easy case, a clean exit from the loop
e = new CastExp(loc, e, Type.tvoid); // https://issues.dlang.org/show_bug.cgi?id=13899
@@ -2024,7 +2029,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
}
else
{
- if (!ps.args || ps.args.dim != 1)
+ if (!ps.args || ps.args.length != 1)
{
ps.error("`string` expected for library name");
return setError();
@@ -2338,7 +2343,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
size_t numcases = 0;
if (ss.cases)
- numcases = ss.cases.dim;
+ numcases = ss.cases.length;
for (size_t i = 0; i < numcases; i++)
{
@@ -2501,7 +2506,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
sw.cases.push(cs);
// Resolve any goto case's with no exp to this case statement
- for (size_t i = 0; i < sw.gotoCases.dim;)
+ for (size_t i = 0; i < sw.gotoCases.length;)
{
GotoCaseStatement gcs = sw.gotoCases[i];
if (!gcs.exp)
@@ -2735,7 +2740,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
{
assert(rs.caseDim == 0);
sc.fes.cases.push(rs);
- result = new ReturnStatement(Loc.initial, new IntegerExp(sc.fes.cases.dim + 1));
+ result = new ReturnStatement(Loc.initial, new IntegerExp(sc.fes.cases.length + 1));
return;
}
if (fd.returnLabel)
@@ -3053,8 +3058,8 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
sc.fes.cases.push(s);
// Immediately rewrite "this" return statement as:
- // return cases.dim+1;
- rs.exp = new IntegerExp(sc.fes.cases.dim + 1);
+ // return cases.length+1;
+ rs.exp = new IntegerExp(sc.fes.cases.length + 1);
if (e0)
{
result = new CompoundStatement(rs.loc, new ExpStatement(rs.loc, e0), rs);
@@ -3078,7 +3083,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
// return exp;
// to:
// vresult = exp; retrun caseDim;
- rs.caseDim = sc.fes.cases.dim + 1;
+ rs.caseDim = sc.fes.cases.length + 1;
}
}
if (rs.exp)
@@ -3136,7 +3141,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
* and 1 is break.
*/
sc.fes.cases.push(bs);
- result = new ReturnStatement(Loc.initial, new IntegerExp(sc.fes.cases.dim + 1));
+ result = new ReturnStatement(Loc.initial, new IntegerExp(sc.fes.cases.length + 1));
return;
}
break; // can't break to it
@@ -3224,7 +3229,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
* and 1 is break.
*/
sc.fes.cases.push(cs);
- result = new ReturnStatement(Loc.initial, new IntegerExp(sc.fes.cases.dim + 1));
+ result = new ReturnStatement(Loc.initial, new IntegerExp(sc.fes.cases.length + 1));
return;
}
break; // can't continue to it
@@ -3589,7 +3594,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
*/
if (!(tcs._body.blockExit(sc.func, false) & BE.throw_) && ClassDeclaration.exception)
{
- foreach_reverse (i; 0 .. tcs.catches.dim)
+ foreach_reverse (i; 0 .. tcs.catches.length)
{
Catch c = (*tcs.catches)[i];
@@ -3604,7 +3609,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
}
}
- if (tcs.catches.dim == 0)
+ if (tcs.catches.length == 0)
{
result = tcs._body.hasCode() ? tcs._body : null;
return;
@@ -3909,10 +3914,10 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
/* https://dlang.org/spec/module.html#ImportDeclaration
*/
- foreach (i; 0 .. imps.imports.dim)
+ foreach (i; 0 .. imps.imports.length)
{
Import s = (*imps.imports)[i].isImport();
- assert(!s.aliasdecls.dim);
+ assert(!s.aliasdecls.length);
foreach (j, name; s.names)
{
Identifier _alias = s.aliases[j];
@@ -4217,7 +4222,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
}
auto loc = fs.loc;
- size_t dim = fs.parameters.dim;
+ size_t dim = fs.parameters.length;
const bool skipCheck = isStatic && needExpansion;
if (!skipCheck && (dim < 1 || dim > 2))
{
@@ -4251,7 +4256,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
if (fs.aggr.op == EXP.tuple) // expression tuple
{
te = cast(TupleExp)fs.aggr;
- n = te.exps.dim;
+ n = te.exps.length;
}
else if (fs.aggr.op == EXP.type) // type tuple
{
@@ -4632,7 +4637,7 @@ private Statements* flatten(Statement statement, Scope* sc)
{
return a;
}
- auto b = new Statements(a.dim);
+ auto b = new Statements(a.length);
foreach (i, s; *a)
{
(*b)[i] = s ? new ForwardingStatement(s.loc, fs.sym, s) : null;
@@ -4702,7 +4707,7 @@ private Statements* flatten(Statement statement, Scope* sc)
if (!a)
return null;
- if (!a.dim)
+ if (!a.length)
{
a.push(new ExpStatement(ls.loc, cast(Expression)null));
}
@@ -4892,7 +4897,7 @@ bool pragmaMsgSemantic(Loc loc, Scope* sc, Expressions* args)
*/
bool pragmaStartAddressSemantic(Loc loc, Scope* sc, Expressions* args)
{
- if (!args || args.dim != 1)
+ if (!args || args.length != 1)
{
.error(loc, "function name expected for start address");
return false;
diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d
index 367c56b..a6d2304 100644
--- a/gcc/d/dmd/traits.d
+++ b/gcc/d/dmd/traits.d
@@ -394,7 +394,7 @@ ulong getTypePointerBitmap(Loc loc, Type t, Array!(ulong)* data)
*/
private Expression pointerBitmap(TraitsExp e)
{
- if (!e.args || e.args.dim != 1)
+ if (!e.args || e.args.length != 1)
{
error(e.loc, "a single type expected for trait pointerBitmap");
return ErrorExp.get();
@@ -412,12 +412,12 @@ private Expression pointerBitmap(TraitsExp e)
if (sz == ulong.max)
return ErrorExp.get();
- auto exps = new Expressions(data.dim + 1);
+ auto exps = new Expressions(data.length + 1);
(*exps)[0] = new IntegerExp(e.loc, sz, Type.tsize_t);
- foreach (size_t i; 1 .. exps.dim)
+ foreach (size_t i; 1 .. exps.length)
(*exps)[i] = new IntegerExp(e.loc, data[cast(size_t) (i - 1)], Type.tsize_t);
- auto ale = new ArrayLiteralExp(e.loc, Type.tsize_t.sarrayOf(data.dim + 1), exps);
+ auto ale = new ArrayLiteralExp(e.loc, Type.tsize_t.sarrayOf(data.length + 1), exps);
return ale;
}
@@ -446,7 +446,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
}
sc.stc = save;
}
- size_t dim = e.args ? e.args.dim : 0;
+ size_t dim = e.args ? e.args.length : 0;
Expression dimError(int expected)
{
@@ -1276,6 +1276,25 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
}
else if (s)
{
+ // @@@DEPRECATION 2.100.2
+ if (auto fd = s.isFuncDeclaration())
+ {
+ if (fd.overnext)
+ {
+ deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `%s`", fd.toChars());
+ deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from");
+ }
+ }
+
+ // @@@DEPRECATION 2.100.2
+ if (auto td = s.isTemplateDeclaration())
+ {
+ if (td.overnext || td.funcroot)
+ {
+ deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `%s`", td.ident.toChars());
+ deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from");
+ }
+ }
if (s.isImport())
{
s = s.isImport().mod;
@@ -1689,12 +1708,12 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
void pushBaseMembersDg(ClassDeclaration cd)
{
- for (size_t i = 0; i < cd.baseclasses.dim; i++)
+ for (size_t i = 0; i < cd.baseclasses.length; i++)
{
auto cb = (*cd.baseclasses)[i].sym;
assert(cb);
ScopeDsymbol._foreach(null, cb.members, &pushIdentsDg);
- if (cb.baseclasses.dim)
+ if (cb.baseclasses.length)
pushBaseMembersDg(cb);
}
}
@@ -1801,9 +1820,9 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
return ErrorExp.get();
if (!TemplateInstance.semanticTiargs(e.loc, sc, &ob2, 0))
return ErrorExp.get();
- if (ob1.dim != ob2.dim)
+ if (ob1.length != ob2.length)
return False();
- foreach (immutable i; 0 .. ob1.dim)
+ foreach (immutable i; 0 .. ob1.length)
if (!ob1[i].isSame(ob2[i], sc))
return False();
return True();
@@ -1924,7 +1943,12 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
return ErrorExp.get();
}
- Type tb = t.baseElemOf();
+ // https://issues.dlang.org/show_bug.cgi?id=23534
+ //
+ // For enums, we need to get the enum initializer
+ // (the first enum member), not the initializer of the
+ // type of the enum members.
+ Type tb = t.isTypeEnum ? t : t.baseElemOf();
return tb.isZeroInit(e.loc) ? True() : False();
}
if (e.ident == Id.getTargetInfo)
@@ -2041,7 +2065,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
if (prependNamespaces(outer, pp.cppnamespace)) return ErrorExp.get();
size_t i = 0;
- while(i < outer.dim && ((*inner)[i]) == (*outer)[i])
+ while(i < outer.length && ((*inner)[i]) == (*outer)[i])
i++;
foreach_reverse (ns; (*inner)[][i .. $])
@@ -2124,7 +2148,7 @@ private bool isSame(RootObject o1, RootObject o2, Scope* sc)
{
if (auto td = t.isTemplateDeclaration())
{
- if (td.members && td.members.dim == 1)
+ if (td.members && td.members.length == 1)
{
if (auto fd = (*td.members)[0].isFuncLiteralDeclaration())
return fd;
@@ -2221,7 +2245,7 @@ private bool isSame(RootObject o1, RootObject o2, Scope* sc)
if (!overSet2)
return false;
- if (overSet1.a.dim != overSet2.a.dim)
+ if (overSet1.a.length != overSet2.a.length)
return false;
// OverloadSets contain array of Dsymbols => O(n*n)
diff --git a/gcc/d/dmd/transitivevisitor.d b/gcc/d/dmd/transitivevisitor.d
index cbe6daa..7aaf0b8 100644
--- a/gcc/d/dmd/transitivevisitor.d
+++ b/gcc/d/dmd/transitivevisitor.d
@@ -617,7 +617,7 @@ package mixin template ParseVisitMethods(AST)
void visitBaseClasses(AST.ClassDeclaration d)
{
//printf("Visiting ClassDeclaration\n");
- if (!d || !d.baseclasses.dim)
+ if (!d || !d.baseclasses.length)
return;
foreach (b; *d.baseclasses)
visitType(b.type);
@@ -626,7 +626,7 @@ package mixin template ParseVisitMethods(AST)
bool visitEponymousMember(AST.TemplateDeclaration d)
{
//printf("Visiting EponymousMember\n");
- if (!d.members || d.members.dim != 1)
+ if (!d.members || d.members.length != 1)
return false;
AST.Dsymbol onemember = (*d.members)[0];
if (onemember.ident != d.ident)
@@ -688,7 +688,7 @@ package mixin template ParseVisitMethods(AST)
void visitTemplateParameters(AST.TemplateParameters* parameters)
{
- if (!parameters || !parameters.dim)
+ if (!parameters || !parameters.length)
return;
foreach (p; *parameters)
p.accept(this);
@@ -1042,7 +1042,7 @@ package mixin template ParseVisitMethods(AST)
visitType(e.targ);
if (e.tspec)
visitType(e.tspec);
- if (e.parameters && e.parameters.dim)
+ if (e.parameters && e.parameters.length)
visitTemplateParameters(e.parameters);
}
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index 0ef7705..a75b416 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -117,9 +117,9 @@ private void resolveTupleIndex(const ref Loc loc, Scope* sc, Dsymbol s, out Expr
return;
}
const(uinteger_t) d = eindex.toUInteger();
- if (d >= tup.objects.dim)
+ if (d >= tup.objects.length)
{
- .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", d, cast(ulong)tup.objects.dim);
+ .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", d, cast(ulong)tup.objects.length);
pt = Type.terror;
return;
}
@@ -194,7 +194,7 @@ private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymb
}
s = s.toAlias();
//printf("\t2: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind());
- for (size_t i = 0; i < mt.idents.dim; i++)
+ for (size_t i = 0; i < mt.idents.length; i++)
{
RootObject id = mt.idents[i];
switch (id.dyncast()) with (DYNCAST)
@@ -552,9 +552,9 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
return error();
uinteger_t d = mtype.dim.toUInteger();
- if (d >= tup.objects.dim)
+ if (d >= tup.objects.length)
{
- .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", cast(ulong)d, cast(ulong)tup.objects.dim);
+ .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", cast(ulong)d, cast(ulong)tup.objects.length);
return error();
}
@@ -647,9 +647,9 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
assert(mtype.dim);
TypeTuple tt = tbn.isTypeTuple();
uinteger_t d = mtype.dim.toUInteger();
- if (d >= tt.arguments.dim)
+ if (d >= tt.arguments.length)
{
- .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", cast(ulong)d, cast(ulong)tt.arguments.dim);
+ .error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", cast(ulong)d, cast(ulong)tt.arguments.length);
return error();
}
Type telem = (*tt.arguments)[cast(size_t)d].type;
@@ -875,11 +875,11 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
fhash = search_function(ClassDeclaration.object, Id.tohash).isFuncDeclaration();
assert(fcmp && feq && fhash);
- if (feq.vtblIndex < cd.vtbl.dim && cd.vtbl[feq.vtblIndex] == feq)
+ if (feq.vtblIndex < cd.vtbl.length && cd.vtbl[feq.vtblIndex] == feq)
{
version (all)
{
- if (fcmp.vtblIndex < cd.vtbl.dim && cd.vtbl[fcmp.vtblIndex] != fcmp)
+ if (fcmp.vtblIndex < cd.vtbl.length && cd.vtbl[fcmp.vtblIndex] != fcmp)
{
const(char)* s = (mtype.index.toBasetype().ty != Tclass) ? "bottom of " : "";
.error(loc, "%sAA key type `%s` now requires equality rather than comparison", s, cd.toChars());
@@ -993,7 +993,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
if (mtype.parameterList.parameters)
{
tf.parameterList.parameters = mtype.parameterList.parameters.copy();
- for (size_t i = 0; i < mtype.parameterList.parameters.dim; i++)
+ for (size_t i = 0; i < mtype.parameterList.parameters.length; i++)
{
Parameter p = cast(Parameter)mem.xmalloc(__traits(classInstanceSize, Parameter));
memcpy(cast(void*)p, cast(void*)(*mtype.parameterList.parameters)[i], __traits(classInstanceSize, Parameter));
@@ -1180,13 +1180,13 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
* the elements of TypeTuple::arguments to avoid unintended
* sharing of Parameter object among other functions.
*/
- if (tt.arguments && tt.arguments.dim)
+ if (tt.arguments && tt.arguments.length)
{
/* Propagate additional storage class from tuple parameters to their
* element-parameters.
* Make a copy, as original may be referenced elsewhere.
*/
- size_t tdim = tt.arguments.dim;
+ size_t tdim = tt.arguments.length;
auto newparams = new Parameters(tdim);
for (size_t j = 0; j < tdim; j++)
{
@@ -1437,7 +1437,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
*/
if (eparam.storageClass & STC.auto_)
{
- Expression farg = mtype.fargs && eidx < mtype.fargs.dim ?
+ Expression farg = mtype.fargs && eidx < mtype.fargs.length ?
(*mtype.fargs)[eidx] : eparam.defaultArg;
if (farg && (eparam.storageClass & STC.ref_))
{
@@ -1756,10 +1756,10 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
uinteger_t i1 = mtype.lwr.toUInteger();
uinteger_t i2 = mtype.upr.toUInteger();
- if (!(i1 <= i2 && i2 <= tt.arguments.dim))
+ if (!(i1 <= i2 && i2 <= tt.arguments.length))
{
.error(loc, "slice `[%llu..%llu]` is out of range of `[0..%llu]`",
- cast(ulong)i1, cast(ulong)i2, cast(ulong)tt.arguments.dim);
+ cast(ulong)i1, cast(ulong)i2, cast(ulong)tt.arguments.length);
return error();
}
@@ -2477,7 +2477,7 @@ Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier iden
}
if (ident == Id.length)
{
- e = new IntegerExp(loc, mt.arguments.dim, Type.tsize_t);
+ e = new IntegerExp(loc, mt.arguments.length, Type.tsize_t);
}
else if (ident == Id._init)
{
@@ -2614,9 +2614,9 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
return returnError();
const d = mt.dim.toUInteger();
- if (d >= tup.objects.dim)
+ if (d >= tup.objects.length)
{
- error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", d, cast(ulong) tup.objects.dim);
+ error(loc, "tuple index `%llu` out of bounds `[0 .. %llu]`", d, cast(ulong) tup.objects.length);
return returnError();
}
@@ -2897,7 +2897,7 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
error(loc, "forward reference to `%s`", mt.toChars());
goto Lerr;
}
- if (mt.idents.dim == 0)
+ if (mt.idents.length == 0)
{
returnType(t.addMod(mt.mod));
}
@@ -2937,7 +2937,7 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
return returnError();
}
}
- if (mt.idents.dim == 0)
+ if (mt.idents.length == 0)
{
return returnType(t.addMod(mt.mod));
}
@@ -2987,13 +2987,13 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
mt.upr = mt.upr.ctfeInterpret();
const i1 = mt.lwr.toUInteger();
const i2 = mt.upr.toUInteger();
- if (!(i1 <= i2 && i2 <= td.objects.dim))
+ if (!(i1 <= i2 && i2 <= td.objects.length))
{
- error(loc, "slice `[%llu..%llu]` is out of range of [0..%llu]", i1, i2, cast(ulong) td.objects.dim);
+ error(loc, "slice `[%llu..%llu]` is out of range of [0..%llu]", i1, i2, cast(ulong) td.objects.length);
return returnError();
}
- if (i1 == 0 && i2 == td.objects.dim)
+ if (i1 == 0 && i2 == td.objects.length)
{
return returnSymbol(td);
}
@@ -3002,7 +3002,7 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
* is a slice [i1..i2] out of the old one.
*/
auto objects = new Objects(cast(size_t)(i2 - i1));
- for (size_t i = 0; i < objects.dim; i++)
+ for (size_t i = 0; i < objects.length; i++)
{
(*objects)[i] = (*td.objects)[cast(size_t)i1 + i];
}
@@ -3096,8 +3096,8 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
break;
case EXP.tuple:
TupleExp te = e.isTupleExp();
- Objects* elems = new Objects(te.exps.dim);
- foreach (i; 0 .. elems.dim)
+ Objects* elems = new Objects(te.exps.length);
+ foreach (i; 0 .. elems.length)
{
auto src = (*te.exps)[i];
switch (src.op)
@@ -3757,8 +3757,8 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag)
ev = extractSideEffect(sc, "__tup", e0, ev);
auto exps = new Expressions();
- exps.reserve(mt.sym.fields.dim);
- for (size_t i = 0; i < mt.sym.fields.dim; i++)
+ exps.reserve(mt.sym.fields.length);
+ for (size_t i = 0; i < mt.sym.fields.length; i++)
{
VarDeclaration v = mt.sym.fields[i];
Expression ex;
@@ -4015,8 +4015,8 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag)
ev = extractSideEffect(sc, "__tup", e0, ev);
auto exps = new Expressions();
- exps.reserve(mt.sym.fields.dim);
- for (size_t i = 0; i < mt.sym.fields.dim; i++)
+ exps.reserve(mt.sym.fields.length);
+ for (size_t i = 0; i < mt.sym.fields.length; i++)
{
VarDeclaration v = mt.sym.fields[i];
// Don't include hidden 'this' pointer
@@ -4589,8 +4589,8 @@ extern (C++) Expression defaultInit(Type mt, const ref Loc loc, const bool isCfi
{
printf("TypeTuple::defaultInit() '%s'\n", mt.toChars());
}
- auto exps = new Expressions(mt.arguments.dim);
- for (size_t i = 0; i < mt.arguments.dim; i++)
+ auto exps = new Expressions(mt.arguments.length);
+ for (size_t i = 0; i < mt.arguments.length; i++)
{
Parameter p = (*mt.arguments)[i];
assert(p.type);
@@ -4655,7 +4655,7 @@ private:
Expression typeToExpressionHelper(TypeQualified t, Expression e, size_t i = 0)
{
//printf("toExpressionHelper(e = %s %s)\n", EXPtoString(e.op).ptr, e.toChars());
- foreach (id; t.idents[i .. t.idents.dim])
+ foreach (id; t.idents[i .. t.idents.length])
{
//printf("\t[%d] e: '%s', id: '%s'\n", i, e.toChars(), id.toChars());
@@ -4770,7 +4770,7 @@ Type stripDefaultArgs(Type t)
if (ps)
{
// Replace params with a copy we can modify
- Parameters* nparams = new Parameters(parameters.dim);
+ Parameters* nparams = new Parameters(parameters.length);
foreach (j, ref np; *nparams)
{
@@ -4898,7 +4898,7 @@ Expression getMaxMinValue(EnumDeclaration ed, const ref Loc loc, Identifier id)
}
bool first = true;
- for (size_t i = 0; i < ed.members.dim; i++)
+ for (size_t i = 0; i < ed.members.length; i++)
{
EnumMember em = (*ed.members)[i].isEnumMember();
if (!em)
diff --git a/gcc/d/gdc.texi b/gcc/d/gdc.texi
index d3bf75c..c99c365 100644
--- a/gcc/d/gdc.texi
+++ b/gcc/d/gdc.texi
@@ -2,6 +2,8 @@
@setfilename gdc.info
@settitle The GNU D Compiler
+@c Create a separate index for command line options
+@defcodeindex op
@c Merge the standard indexes into a single one.
@syncodeindex fn cp
@syncodeindex vr cp
@@ -63,25 +65,22 @@ Boston, MA 02110-1301, USA@*
@top Introduction
This manual describes how to use @command{gdc}, the GNU compiler for
-the D programming language. This manual is specifically about
-@command{gdc}. For more information about the D programming
-language in general, including language specifications and standard
-package documentation, see @uref{https://dlang.org/}.
+the D programming language. This manual is specifically about how to
+invoke @command{gdc}, as well as its features and incompatibilities.
+For more information about the D programming language in general,
+including language specifications and standard package documentation,
+see @uref{https://dlang.org/}.
@menu
+* Invoking gdc:: How to run gdc.
+* D Implementation:: User-visible implementation details.
* Copying:: The GNU General Public License.
* GNU Free Documentation License::
How you can share and copy this manual.
-* Invoking gdc:: How to run gdc.
-* Index:: Index.
+* Option Index:: Index of command line options.
+* Keyword Index:: Index of concepts.
@end menu
-
-@include gpl_v3.texi
-
-@include fdl.texi
-
-
@node Invoking gdc
@chapter Invoking gdc
@@ -173,21 +172,21 @@ These options affect the runtime behavior of programs compiled with
@table @gcctabopt
@item -fall-instantiations
-@cindex @option{-fall-instantiations}
-@cindex @option{-fno-all-instantiations}
+@opindex fall-instantiations
+@opindex fno-all-instantiations
Generate code for all template instantiations. The default template emission
strategy is to not generate code for declarations that were either
instantiated speculatively, such as from @code{__traits(compiles, ...)}, or
that come from an imported module not being compiled.
@item -fno-assert
-@cindex @option{-fassert}
-@cindex @option{-fno-assert}
+@opindex fassert
+@opindex fno-assert
Turn off code generation for @code{assert} contracts.
@item -fno-bounds-check
-@cindex @option{-fbounds-check}
-@cindex @option{-fno-bounds-check}
+@opindex fbounds-check
+@opindex fno-bounds-check
Turns off array bounds checking for all functions, which can improve
performance for code that uses arrays extensively. Note that this
can result in unpredictable behavior if the code in question actually
@@ -195,7 +194,7 @@ does violate array bounds constraints. It is safe to use this option
if you are sure that your code never throws a @code{RangeError}.
@item -fbounds-check=@var{value}
-@cindex @option{-fbounds-check=}
+@opindex fbounds-check=
An alternative to @option{-fbounds-check} that allows more control
as to where bounds checking is turned on or off. The following values
are supported:
@@ -210,14 +209,14 @@ Turns off array bounds checking completely.
@end table
@item -fno-builtin
-@cindex @option{-fbuiltin}
-@cindex @option{-fno-builtin}
+@opindex fbuiltin
+@opindex fno-builtin
Don't recognize built-in functions unless they begin with the prefix
@samp{__builtin_}. By default, the compiler will recognize when a
function in the @code{core.stdc} package is a built-in function.
@item -fcheckaction=@var{value}
-@cindex @option{-fcheckaction}
+@opindex fcheckaction
This option controls what code is generated on an assertion, bounds check, or
final switch failure. The following values are supported:
@@ -232,24 +231,21 @@ Throw an @code{AssertError} (the default).
@item -fdebug
@item -fdebug=@var{value}
-@cindex @option{-fdebug}
-@cindex @option{-fno-debug}
+@opindex fdebug
+@opindex fno-debug
Turn on compilation of conditional @code{debug} code into the program.
The @option{-fdebug} option itself sets the debug level to @code{1},
while @option{-fdebug=} enables @code{debug} code that are identified
by any of the following values:
@table @samp
-@item level
-Sets the debug level to @var{level}, any @code{debug} code <= @var{level}
-is compiled into the program.
@item ident
Turns on compilation of any @code{debug} code identified by @var{ident}.
@end table
@item -fno-druntime
-@cindex @option{-fdruntime}
-@cindex @option{-fno-druntime}
+@opindex fdruntime
+@opindex fno-druntime
Implements @uref{https://dlang.org/spec/betterc.html}. Assumes that
compilation targets an environment without a D runtime library.
@@ -260,7 +256,7 @@ gdc -nophoboslib -fno-exceptions -fno-moduleinfo -fno-rtti
@end example
@item -fextern-std=@var{standard}
-@cindex @option{-fextern-std}
+@opindex fextern-std
Sets the C++ name mangling compatibility to the version identified by
@var{standard}. The following values are supported:
@@ -280,20 +276,20 @@ Sets @code{__traits(getTargetInfo, "cppStd")} to @code{202002}.
@end table
@item -fno-invariants
-@cindex @option{-finvariants}
-@cindex @option{-fno-invariants}
+@opindex finvariants
+@opindex fno-invariants
Turns off code generation for class @code{invariant} contracts.
@item -fmain
-@cindex @option{-fmain}
+@opindex fmain
Generates a default @code{main()} function when compiling. This is useful when
unittesting a library, as it enables running the unittests in a library without
having to manually define an entry-point function. This option does nothing
when @code{main} is already defined in user code.
@item -fno-moduleinfo
-@cindex @option{-fmoduleinfo}
-@cindex @option{-fno-moduleinfo}
+@opindex fmoduleinfo
+@opindex fno-moduleinfo
Turns off generation of the @code{ModuleInfo} and related functions
that would become unreferenced without it, which may allow linking
to programs not written in D. Functions that are not be generated
@@ -302,29 +298,31 @@ include module constructors and destructors (@code{static this} and
functions for dynamically linked code.
@item -fonly=@var{filename}
-@cindex @option{-fonly}
+@opindex fonly
Tells the compiler to parse and run semantic analysis on all modules
on the command line, but only generate code for the module specified
by @var{filename}.
@item -fno-postconditions
-@cindex @option{-fpostconditions}
-@cindex @option{-fno-postconditions}
+@opindex fpostconditions
+@opindex fno-postconditions
Turns off code generation for postcondition @code{out} contracts.
@item -fno-preconditions
-@cindex @option{-fpreconditions}
-@cindex @option{-fno-preconditions}
+@opindex fpreconditions
+@opindex fno-preconditions
Turns off code generation for precondition @code{in} contracts.
@item -fpreview=@var{id}
-@cindex @option{-fpreview}
+@opindex fpreview
Turns on an upcoming D language change identified by @var{id}. The following
values are supported:
@table @samp
@item all
Turns on all upcoming D language features.
+@item bitfields
+Implements bit-fields in D.
@item dip1000
Implements @uref{https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1000.md}
(Scoped pointers).
@@ -353,9 +351,6 @@ rvalues.
@item inclusiveincontracts
Implements @code{in} contracts of overridden methods to be a superset of parent
contract.
-@item intpromote
-Implements C-style integral promotion for unary @code{+}, @code{-} and @code{~}
-expressions.
@item nosharedaccess
Turns off and disallows all access to shared memory objects.
@item rvaluerefparam
@@ -365,8 +360,8 @@ Disables access to variables marked @code{@@system} from @code{@@safe} code.
@end table
@item -frelease
-@cindex @option{-frelease}
-@cindex @option{-fno-release}
+@opindex frelease
+@opindex fno-release
Turns on compiling in release mode, which means not emitting runtime
checks for contracts and asserts. Array bounds checking is not done
for @code{@@system} and @code{@@trusted} functions, and assertion
@@ -380,59 +375,60 @@ gdc -fno-assert -fbounds-check=safe -fno-invariants \
@end example
@item -frevert=
-@cindex @option{-frevert}
+@opindex frevert
Turns off a D language feature identified by @var{id}. The following values
are supported:
@table @samp
@item all
Turns off all revertable D language features.
+@item dip1000
+Reverts @uref{https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1000.md}
+(Scoped pointers).
@item dip25
Reverts @uref{https://github.com/dlang/DIPs/blob/master/DIPs/archive/DIP25.md}
(Sealed references).
@item dtorfields
Turns off generation for destructing fields of partially constructed objects.
-@item markdown
-Turns off Markdown replacements in Ddoc comments.
+@item intpromote
+Turns off C-style integral promotion for unary @code{+}, @code{-} and @code{~}
+expressions.
@end table
@item -fno-rtti
-@cindex @option{-frtti}
-@cindex @option{-fno-rtti}
+@opindex frtti
+@opindex fno-rtti
Turns off generation of run-time type information for all user defined types.
Any code that uses features of the language that require access to this
information will result in an error.
@item -fno-switch-errors
-@cindex @option{-fswitch-errors}
-@cindex @option{-fno-switch-errors}
+@opindex fswitch-errors
+@opindex fno-switch-errors
This option controls what code is generated when no case is matched
in a @code{final switch} statement. The default run time behavior
is to throw a @code{SwitchError}. Turning off @option{-fswitch-errors}
means that instead the execution of the program is immediately halted.
@item -funittest
-@cindex @option{-funittest}
-@cindex @option{-fno-unittest}
+@opindex funittest
+@opindex fno-unittest
Turns on compilation of @code{unittest} code, and turns on the
@code{version(unittest)} identifier. This implies @option{-fassert}.
@item -fversion=@var{value}
-@cindex @option{-fversion}
+@opindex fversion
Turns on compilation of conditional @code{version} code into the program
identified by any of the following values:
@table @samp
-@item level
-Sets the version level to @var{level}, any @code{version} code >= @var{level}
-is compiled into the program.
@item ident
Turns on compilation of @code{version} code identified by @var{ident}.
@end table
@item -fno-weak-templates
-@cindex @option{-fweak-templates}
-@cindex @option{-fno-weak-templates}
+@opindex fweak-templates
+@opindex fno-weak-templates
Turns off emission of declarations that can be defined in multiple objects as
weak symbols. The default is to emit all public symbols as weak, unless the
target lacks support for weak symbols. Disabling this option means that common
@@ -452,29 +448,29 @@ other parts of the compiler:
@table @gcctabopt
@item -I@var{dir}
-@cindex @option{-I}
+@opindex I
Specify a directory to use when searching for imported modules at
compile time. Multiple @option{-I} options can be used, and the
paths are searched in the same order.
@item -J@var{dir}
-@cindex @option{-J}
+@opindex J
Specify a directory to use when searching for files in string imports
at compile time. This switch is required in order to use
@code{import(file)} expressions. Multiple @option{-J} options can be
used, and the paths are searched in the same order.
@item -L@var{dir}
-@cindex @option{-L}
+@opindex L
When linking, specify a library search directory, as with @command{gcc}.
@item -B@var{dir}
-@cindex @option{-B}
+@opindex B
This option specifies where to find the executables, libraries,
source files, and data files of the compiler itself, as with @command{gcc}.
@item -fmodule-file=@var{module}=@var{spec}
-@cindex @option{-fmodule-file}
+@opindex fmodule-file
This option manipulates file paths of imported modules, such that if an
imported module matches all or the leftmost part of @var{module}, the file
path in @var{spec} is used as the location to search for D sources.
@@ -497,18 +493,18 @@ import A.B.C; // No match, searches for A/B/C.d
@end example
@item -imultilib @var{dir}
-@cindex @option{-imultilib}
+@opindex imultilib
Use @var{dir} as a subdirectory of the gcc directory containing
target-specific D sources and interfaces.
@item -iprefix @var{prefix}
-@cindex @option{-iprefix}
+@opindex iprefix
Specify @var{prefix} as the prefix for the gcc directory containing
target-specific D sources and interfaces. If the @var{prefix} represents
a directory, you should include the final @code{'/'}.
@item -nostdinc
-@cindex @option{-nostdinc}
+@opindex nostdinc
Do not search the standard system directories for D source and interface
files. Only the directories that have been specified with @option{-I} options
(and the directory of the current file, if appropriate) are searched.
@@ -525,106 +521,106 @@ In addition to the many @command{gcc} options controlling code generation,
@table @gcctabopt
@item -H
-@cindex @option{-H}
+@opindex H
Generates D interface files for all modules being compiled. The compiler
determines the output file based on the name of the input file, removes
any directory components and suffix, and applies the @file{.di} suffix.
@item -Hd @var{dir}
-@cindex @option{-Hd}
+@opindex Hd
Same as @option{-H}, but writes interface files to directory @var{dir}.
This option can be used with @option{-Hf @var{file}} to independently set the
output file and directory path.
@item -Hf @var{file}
-@cindex @option{-Hf}
+@opindex Hf
Same as @option{-H} but writes interface files to @var{file}. This option can
be used with @option{-Hd @var{dir}} to independently set the output file and
directory path.
@item -M
-@cindex @option{-M}
+@opindex M
Output the module dependencies of all source files being compiled in a
format suitable for @command{make}. The compiler outputs one
@command{make} rule containing the object file name for that source file,
a colon, and the names of all imported files.
@item -MM
-@cindex @option{-MM}
+@opindex MM
Like @option{-M} but does not mention imported modules from the D standard
library package directories.
@item -MF @var{file}
-@cindex @option{-MF}
+@opindex MF
When used with @option{-M} or @option{-MM}, specifies a @var{file} to write
the dependencies to. When used with the driver options @option{-MD} or
@option{-MMD}, @option{-MF} overrides the default dependency output file.
@item -MG
-@cindex @option{-MG}
+@opindex MG
This option is for compatibility with @command{gcc}, and is ignored by the
compiler.
@item -MP
-@cindex @option{-MP}
+@opindex MP
Outputs a phony target for each dependency other than the modules being
compiled, causing each to depend on nothing.
@item -MT @var{target}
-@cindex @option{-MT}
+@opindex MT
Change the @var{target} of the rule emitted by dependency generation
to be exactly the string you specify. If you want multiple targets,
you can specify them as a single argument to @option{-MT}, or use
multiple @option{-MT} options.
@item -MQ @var{target}
-@cindex @option{-MQ}
+@opindex MQ
Same as @option{-MT}, but it quotes any characters which are special to
@command{make}.
@item -MD
-@cindex @option{-MD}
+@opindex MD
This option is equivalent to @option{-M -MF @var{file}}. The driver
determines @var{file} by removing any directory components and suffix
from the input file, and then adding a @file{.deps} suffix.
@item -MMD
-@cindex @option{-MMD}
+@opindex MMD
Like @option{-MD} but does not mention imported modules from the D standard
library package directories.
@item -X
-@cindex @option{-X}
+@opindex X
Output information describing the contents of all source files being
compiled in JSON format to a file. The driver determines @var{file} by
removing any directory components and suffix from the input file, and then
adding a @file{.json} suffix.
@item -Xf @var{file}
-@cindex @option{-Xf}
+@opindex Xf
Same as @option{-X}, but writes all JSON contents to the specified
@var{file}.
@item -fdoc
-@cindex @option{-fdoc}
+@opindex fdoc
Generates @code{Ddoc} documentation and writes it to a file. The compiler
determines @var{file} by removing any directory components and suffix
from the input file, and then adding a @file{.html} suffix.
@item -fdoc-dir=@var{dir}
-@cindex @option{-fdoc-dir}
+@opindex fdoc-dir
Same as @option{-fdoc}, but writes documentation to directory @var{dir}.
This option can be used with @option{-fdoc-file=@var{file}} to
independently set the output file and directory path.
@item -fdoc-file=@var{file}
-@cindex @option{-fdoc-file}
+@opindex fdoc-file
Same as @option{-fdoc}, but writes documentation to @var{file}. This
option can be used with @option{-fdoc-dir=@var{dir}} to independently
set the output file and directory path.
@item -fdoc-inc=@var{file}
-@cindex @option{-fdoc-inc}
+@opindex fdoc-inc
Specify @var{file} as a @var{Ddoc} macro file to be read. Multiple
@option{-fdoc-inc} options can be used, and files are read and processed
in the same order.
@@ -637,7 +633,7 @@ In conjunction with @option{-fdump-c++-spec=} above, add comments for ignored
declarations in the generated C++ header.
@item -fsave-mixins=@var{file}
-@cindex @option{-fsave-mixins}
+@opindex fsave-mixins
Generates code expanded from D @code{mixin} statements and writes the
processed sources to @var{file}. This is useful to debug errors in compilation
and provides source for debuggers to show when requested.
@@ -646,8 +642,10 @@ and provides source for debuggers to show when requested.
@node Warnings
@section Warnings
-@cindex options to control warnings
-@cindex warning messages
+@cindex options, warnings
+@cindex options, errors
+@cindex warnings, suppressing
+@cindex messages, error
@cindex messages, warning
@cindex suppressing warnings
@@ -659,93 +657,92 @@ specified, they do not prevent compilation of the program.
@table @gcctabopt
@item -Wall
-@cindex @option{-Wall}
-@cindex @option{-Wno-all}
+@opindex Wall
+@opindex Wno-all
Turns on all warnings messages. Warnings are not a defined part of
the D language, and all constructs for which this may generate a
warning message are valid code.
@item -Walloca
-@cindex @option{-Walloca}
+@opindex Walloca
This option warns on all uses of "alloca" in the source.
@item -Walloca-larger-than=@var{n}
-@cindex @option{-Walloca-larger-than}
-@cindex @option{-Wno-alloca-larger-than}
+@opindex Walloca-larger-than
+@opindex Wno-alloca-larger-than
Warn on unbounded uses of alloca, and on bounded uses of alloca
whose bound can be larger than @var{n} bytes.
@option{-Wno-alloca-larger-than} disables
@option{-Walloca-larger-than} warning and is equivalent to
@option{-Walloca-larger-than=@var{SIZE_MAX}} or larger.
+@item -Wno-builtin-declaration-mismatch
+@opindex Wno-builtin-declaration-mismatch
+@opindex Wbuiltin-declaration-mismatch
+Warn if a built-in function is declared with an incompatible signature.
+
@item -Wcast-result
-@cindex @option{-Wcast-result}
-@cindex @option{-Wno-cast-result}
+@opindex Wcast-result
+@opindex Wno-cast-result
Warn about casts that will produce a null or zero result. Currently
this is only done for casting between an imaginary and non-imaginary
data type, or casting between a D and C++ class.
@item -Wno-deprecated
-@cindex @option{-Wdeprecated}
-@cindex @option{-Wno-deprecated}
+@opindex Wdeprecated
+@opindex Wno-deprecated
Do not warn about usage of deprecated features and symbols with
@code{deprecated} attributes.
@item -Werror
-@cindex @option{-Werror}
-@cindex @option{-Wno-error}
+@opindex Werror
+@opindex Wno-error
Turns all warnings into errors.
@item -Wspeculative
-@cindex @option{-Wspeculative}
-@cindex @option{-Wno-speculative}
+@opindex Wspeculative
+@opindex Wno-speculative
List all error messages from speculative compiles, such as
@code{__traits(compiles, ...)}. This option does not report
messages as warnings, and these messages therefore never become
errors when the @option{-Werror} option is also used.
-@item -Wtemplates
-@cindex @option{-Wtemplates}
-@cindex @option{-Wno-templates}
-Warn when a template instantiation is encountered. Some coding
-rules disallow templates, and this may be used to enforce that rule.
-
@item -Wunknown-pragmas
-@cindex @option{-Wunknown-pragmas}
-@cindex @option{-Wno-unknown-pragmas}
+@opindex Wunknown-pragmas
+@opindex Wno-unknown-pragmas
Warn when a @code{pragma()} is encountered that is not understood by
@command{gdc}. This differs from @option{-fignore-unknown-pragmas}
where a pragma that is part of the D language, but not implemented by
the compiler, won't get reported.
@item -Wno-varargs
-@cindex Wvarargs
-@cindex Wno-varargs
+@opindex Wvarargs
+@opindex Wno-varargs
Do not warn upon questionable usage of the macros used to handle variable
arguments like @code{va_start}.
@item -fignore-unknown-pragmas
-@cindex @option{-fignore-unknown-pragmas}
-@cindex @option{-fno-ignore-unknown-pragmas}
+@opindex fignore-unknown-pragmas
+@opindex fno-ignore-unknown-pragmas
Turns off errors for unsupported pragmas.
@item -fmax-errors=@var{n}
-@cindex @option{-fmax-errors}
+@opindex fmax-errors
Limits the maximum number of error messages to @var{n}, at which point
@command{gdc} bails out rather than attempting to continue processing the
source code. If @var{n} is 0 (the default), there is no limit on the
number of error messages produced.
@item -fsyntax-only
-@cindex @option{-fsyntax-only}
-@cindex @option{-fno-syntax-only}
+@opindex fsyntax-only
+@opindex fno-syntax-only
Check the code for syntax errors, but do not actually compile it. This
can be used in conjunction with @option{-fdoc} or @option{-H} to generate
files for each module present on the command-line, but no other output
file.
@item -ftransition=@var{id}
-@cindex @option{-ftransition}
+@opindex ftransition
Report additional information about D language changes identified by
@var{id}. The following values are supported:
@@ -764,8 +761,6 @@ List all hidden GC allocations.
List statistics on template instantiations.
@item tls
List all variables going into thread local storage.
-@item vmarkdown
-List instances of Markdown replacements in Ddoc.
@end table
@end table
@@ -782,34 +777,34 @@ a link step.
@table @gcctabopt
@item -defaultlib=@var{libname}
-@cindex @option{-defaultlib=}
+@opindex defaultlib=
Specify the library to use instead of libphobos when linking. Options
specifying the linkage of libphobos, such as @option{-static-libphobos}
or @option{-shared-libphobos}, are ignored.
@item -debuglib=@var{libname}
-@cindex @option{-debuglib=}
+@opindex debuglib=
Specify the debug library to use instead of libphobos when linking.
This option has no effect unless the @option{-g} option was also given
on the command line. Options specifying the linkage of libphobos, such
as @option{-static-libphobos} or @option{-shared-libphobos}, are ignored.
@item -nophoboslib
-@cindex @option{-nophoboslib}
+@opindex nophoboslib
Do not use the Phobos or D runtime library when linking. Options specifying
the linkage of libphobos, such as @option{-static-libphobos} or
@option{-shared-libphobos}, are ignored. The standard system libraries are
used normally, unless @option{-nostdlib} or @option{-nodefaultlibs} is used.
@item -shared-libphobos
-@cindex @option{-shared-libphobos}
+@opindex shared-libphobos
On systems that provide @file{libgphobos} and @file{libgdruntime} as a
shared and a static library, this option forces the use of the shared
version. If no shared version was built when the compiler was configured,
this option has no effect.
@item -static-libphobos
-@cindex @option{-static-libphobos}
+@opindex static-libphobos
On systems that provide @file{libgphobos} and @file{libgdruntime} as a
shared and a static library, this option forces the use of the static
version. If no static version was built when the compiler was configured,
@@ -829,12 +824,12 @@ interest to developers or language tooling.
@table @gcctabopt
@item -fdump-d-original
-@cindex @option{-fdump-d-original}
+@opindex fdump-d-original
Output the internal front-end AST after the @code{semantic3} stage.
This option is only useful for debugging the GNU D compiler itself.
@item -v
-@cindex @option{-v}
+@opindex v
Dump information about the compiler language processing stages as the source
program is being compiled. This includes listing all modules that are
processed through the @code{parse}, @code{semantic}, @code{semantic2}, and
@@ -845,8 +840,24 @@ and all @code{function} bodies that are being compiled.
@c man end
-@node Index
-@unnumbered Index
+@include implement-d.texi
+
+@include gpl_v3.texi
+@include fdl.texi
+
+@node Option Index
+@unnumbered Option Index
+
+@command{gdc}'s command line options are indexed here without any initial
+@samp{-} or @samp{--}. Where an option has both positive and negative forms
+(such as @option{-f@var{option}} and @option{-fno-@var{option}}), relevant
+entries in the manual are indexed under the most appropriate form; it may
+sometimes be useful to look up both forms.
+
+@printindex op
+
+@node Keyword Index
+@unnumbered Keyword Index
@printindex cp
diff --git a/gcc/d/implement-d.texi b/gcc/d/implement-d.texi
new file mode 100644
index 0000000..8f3f825
--- /dev/null
+++ b/gcc/d/implement-d.texi
@@ -0,0 +1,2514 @@
+@ignore
+Copyright (C) 2022 Free Software Foundation, Inc.
+This is part of the GNU D manual.
+For copying conditions, see the file gdc.texi.
+@end ignore
+
+@node D Implementation
+@chapter Language Reference
+@cindex language reference, D language
+
+The implementation of the D programming language used by the GNU D compiler is
+shared with parts of the front-end for the Digital Mars D compiler, hosted at
+@uref{https://github.com/dlang/dmd/}. This common front-end covers lexical
+analysis, parsing, and semantic analysis of the D programming language defined
+in the documents at @uref{https://dlang.org/}.
+
+The implementation details described in this manual are GNU D extensions to the
+D programming language. If you want to write code that checks whether these
+features are available, you can test for the predefined version @code{GNU}, or
+you can check whether a specific feature is compilable using
+@code{__traits(compiles)}.
+
+@smallexample
+version (GNU)
+@{
+ import gcc.builtins;
+ return __builtin_atan2(x, y);
+@}
+
+static if (__traits(compiles, @{ asm @{"";@} @}))
+@{
+ asm @{ "magic instruction"; @}
+@}
+@end smallexample
+
+@menu
+* Attributes:: Implementation-defined attributes.
+* Builtin Functions:: GCC built-ins module.
+* ImportC:: Importing C sources into D.
+* Inline Assembly:: Interfacing D with assembler.
+* Intrinsics:: Intrinsic functions supported by GDC.
+* Predefined Pragmas:: Pragmas accepted by GDC.
+* Predefined Versions:: List of versions for conditional compilation.
+* Special Enums:: Intrinsic type interoperability with C and C++.
+* Traits:: Compile-time reflection extensions.
+* Vector Extensions:: Using vector types and supported operations.
+* Vector Intrinsics:: Vector instructions through intrinsics.
+* Missing Features:: Deviations from the D2 specification in GDC.
+@end menu
+
+
+@c --------------------------------------------------------
+
+@node Attributes
+@section Attributes
+@cindex attributes
+
+User-Defined Attributes (UDA) are compile-time expressions introduced by the
+@code{@@} token that can be attached to a declaration. These attributes can
+then be queried, extracted, and manipulated at compile time.
+
+GNU D provides a number of extra special attributes to control specific
+compiler behavior that may help the compiler optimize or check code more
+carefully for correctness. The attributes are defined in the
+@code{gcc.attributes} module.
+
+There is some overlap between the purposes of attributes and pragmas. It has
+been found more convenient to use @code{@@attribute} to achieve a natural
+attachment of attributes to their corresponding declarations, whereas
+@code{pragma} is of use for compatibility with other compilers or constructs
+that do not naturally form part of the grammar.
+
+@menu
+* Attribute Syntax::
+* Common Attributes::
+* Other Attributes::
+* Target Attributes::
+@end menu
+
+@c --------------------------------------------------------
+
+@node Attribute Syntax
+@subsection Attribute Syntax
+
+@code{@@(gcc.attributes.attribute)} is the generic entrypoint for applying GCC
+attributes to a function, variable, or type. There is no type checking done,
+as well as no deprecation path for attributes removed from the compiler. So
+the recommendation is to use any of the other UDAs available as described in
+@ref{Common Attributes} unless it is a target-specific attribute
+(@xref{Target Attributes}).
+
+Function attributes introduced by the @code{@@attribute} UDA are used in the
+declaration of a function, followed by an attribute name string and any
+arguments separated by commas enclosed in parentheses.
+
+@smallexample
+import gcc.attributes;
+@@attribute("regparm", 1) int func(int size);
+@end smallexample
+
+@noindent
+Multiple attributes can be applied to a single declaration either with multiple
+@code{@@attribute} attributes, or passing all attributes as a comma-separated
+list enclosed by parentheses.
+
+@smallexample
+// Both func1 and func2 have the same attributes applied.
+@@attribute("noinline") @@attribute("noclone") void func1();
+@@(attribute("noinline"), attribute("noclone")) void func2();
+@end smallexample
+
+@noindent
+There are some problems with the semantics of such attributes in D. For
+example, there are no manglings for attributes, although they may affect code
+generation, so problems may arise when attributed types are used in conjunction
+with templates or overloading. Similarly, @code{typeid} does not distinguish
+between types with different attributes. Support for attributes in D are
+restricted to declarations only.
+
+@c --------------------------------------------------------
+
+@node Common Attributes
+@subsection Common Attributes
+
+The following attributes are supported on most targets.
+
+@table @code
+
+@item @@(gcc.attributes.alloc_size (@var{sizeArgIdx}))
+@itemx @@(gcc.attributes.alloc_size (@var{sizeArgIdx}, @var{numArgIdx}))
+@itemx @@(gcc.attributes.alloc_size (@var{sizeArgIdx}, @var{numArgIdx}, @var{zeroBasedNumbering}))
+@cindex @code{alloc_size} function attribute
+@cindex @code{alloc_size} variable attribute
+
+The @code{@@alloc_size} attribute may be applied to a function - or a function
+pointer variable - that returns a pointer and takes at least one argument of
+an integer or enumerated type. It indicates that the returned pointer points
+to memory whose size is given by the function argument at @code{sizeArgIdx}, or
+by the product of the arguments at @code{sizeArgIdx} and @code{numArgIdx}.
+Meaningful sizes are positive values less than @code{ptrdiff_t.max}. Unless
+@code{zeroBasedNumbering} is true, argument numbering starts at one for
+ordinary functions, and at two for non-static member functions.
+
+If @code{numArgIdx} is less than @code{0}, it is taken to mean there is no
+argument specifying the element count.
+
+@smallexample
+@@alloc_size(1) void* malloc(size_t);
+@@alloc_size(3,2) void* reallocarray(void *, size_t, size_t);
+@@alloc_size(1,2) void* my_calloc(size_t, size_t, bool);
+void malloc_cb(@@alloc_size(1) void* function(size_t) ptr) @{ @}
+@end smallexample
+
+@item @@(gcc.attributes.always_inline)
+@cindex @code{always_inline} function attribute
+
+The @code{@@always_inline} attribute inlines the function independent of any
+restrictions that otherwise apply to inlining. Failure to inline such a
+function is diagnosed as an error.
+
+@smallexample
+@@always_inline int func();
+@end smallexample
+
+@item @@(gcc.attributes.cold)
+@cindex @code{cold} function attribute
+
+The @code{@@cold} attribute on functions is used to inform the compiler that the
+function is unlikely to be executed. The function is optimized for size
+rather than speed and on many targets it is placed into a special subsection
+of the text section so all cold functions appear close together, improving
+code locality of non-cold parts of program. The paths leading to calls of
+cold functions within code are considered to be cold too.
+
+@smallexample
+@@cold int func();
+@end smallexample
+
+@item @@(gcc.attributes.flatten)
+@cindex @code{flatten} function attribute
+
+The @code{@@flatten} attribute is used to inform the compiler that every call
+inside this function should be inlined, if possible. Functions declared with
+attribute @code{@@noinline} and similar are not inlined.
+
+@smallexample
+@@flatten int func();
+@end smallexample
+
+@item @@(gcc.attributes.no_icf)
+@cindex @code{no_icf} function attribute
+
+The @code{@@no_icf} attribute prevents a function from being merged with
+another semantically equivalent function.
+
+@smallexample
+@@no_icf int func();
+@end smallexample
+
+@item @@(gcc.attributes.no_sanitize ("@var{sanitize_option}"))
+@cindex @code{no_sanitize} function attribute
+
+The @code{@@no_sanitize} attribute on functions is used to inform the compiler
+that it should not do sanitization of any option mentioned in
+@var{sanitize_option}. A list of values acceptable by the @option{-fsanitize}
+option can be provided.
+
+@smallexample
+@@no_sanitize("alignment", "object-size") void func1() @{ @}
+@@no_sanitize("alignment,object-size") void func2() @{ @}
+@end smallexample
+
+@item @@(gcc.attributes.noclone)
+@cindex @code{noclone} function attribute
+
+The @code{@@noclone} attribute prevents a function from being considered for
+cloning - a mechanism that produces specialized copies of functions and which
+is (currently) performed by interprocedural constant propagation.
+
+@smallexample
+@@noclone int func();
+@end smallexample
+
+@item @@(gcc.attributes.noinline)
+@cindex @code{noinline} function attribute
+
+The @code{@@noinline} attribute prevents a function from being considered for
+inlining. If the function does not have side effects, there are optimizations
+other than inlining that cause function calls to be optimized away, although
+the function call is live. To keep such calls from being optimized away, put
+@code{asm @{ ""; @}} in the called function, to serve as a special side effect.
+
+@smallexample
+@@noinline int func();
+@end smallexample
+
+@item @@(gcc.attributes.noipa)
+@cindex @code{noipa} function attribute
+
+The @code{@@noipa} attribute disables interprocedural optimizations between the
+function with this attribute and its callers, as if the body of the function is
+not available when optimizing callers and the callers are unavailable when
+optimizing the body. This attribute implies @code{@@noinline},
+@code{@@noclone}, and @code{@@no_icf} attributes. However, this attribute is
+not equivalent to a combination of other attributes, because its purpose is to
+suppress existing and future optimizations employing interprocedural analysis,
+including those that do not have an attribute suitable for disabling them
+individually.
+
+This attribute is supported mainly for the purpose of testing the compiler.
+
+@smallexample
+@@noipa int func();
+@end smallexample
+
+@item @@(gcc.attributes.noplt)
+@cindex @code{noplt} function attribute
+
+The @code{@@noplt} attribute is the counterpart to option @option{-fno-plt}.
+Calls to functions marked with this attribute in position-independent code do
+not use the PLT in position-independent code.
+
+In position-dependant code, a few targets also convert call to functions that
+are marked to not use the PLT to use the GOT instead.
+
+@smallexample
+@@noplt int func();
+@end smallexample
+
+@item @@(gcc.attributes.optimize (@var{arguments}))
+@cindex @code{optimize} function attribute
+
+The @code{@@optimize} attribute is used to specify that a function is to be
+compiled with different optimization options than specified on the command
+line. Valid @var{arguments} are constant non-negative integers and strings.
+Multiple arguments can be provided, separated by commas to specify multiple
+options. Each numeric argument specifies an optimization level. Each string
+argument that begins with the letter @code{O} refers to an optimization option
+such as @option{-O0} or @option{-Os}. Other options are taken as suffixes to
+the @code{-f} prefix jointly forming the name of an optimization option.
+
+Not every optimization option that starts with the @code{-f} prefix
+specified by the attribute necessarily has an effect on the function.
+The @code{@@optimize} attribute should be used for debugging purposes only.
+It is not suitable in production code.
+
+@smallexample
+@@optimize(2) double fn0(double x);
+@@optimize("2") double fn1(double x);
+@@optimize("s") double fn2(double x);
+@@optimize("Ofast") double fn3(double x);
+@@optimize("-O2") double fn4(double x);
+@@optimize("tree-vectorize") double fn5(double x);
+@@optimize("-ftree-vectorize") double fn6(double x);
+@@optimize("no-finite-math-only", 3) double fn7(double x);
+@end smallexample
+
+@item @@(gcc.attributes.register ("@var{registerName}"))
+@cindex @code{register} variable attribute
+
+The @code{@@register} attribute specifies that a local or @code{__gshared}
+variable is to be given a register storage-class in the C99 sense of the term,
+and will be placed into a register named @var{registerName}.
+
+The variable needs to boiled down to a data type that fits the target register.
+It also cannot have either thread-local or @code{extern} storage. It is an
+error to take the address of a register variable.
+
+@smallexample
+@@register("ebx") __gshared int ebx = void;
+void func() @{ @@register("r10") long r10 = 0x2a; @}
+@end smallexample
+
+@item @@(gcc.attributes.restrict)
+@cindex @code{restrict} parameter attribute
+
+The @code{@@restrict} attribute specifies that a function parameter is to be
+restrict-qualified in the C99 sense of the term. The parameter needs to boil
+down to either a pointer or reference type, such as a D pointer, class
+reference, or a @code{ref} parameter.
+
+@smallexample
+void func(@@restrict ref const float[16] array);
+@end smallexample
+
+@item @@(gcc.attributes.section ("@var{sectionName}"))
+@cindex @code{section} function attribute
+@cindex @code{section} variable attribute
+
+The @code{@@section} attribute specifies that a function or variable lives in a
+particular section. For when you need certain particular functions to appear
+in special sections.
+
+Some file formats do not support arbitrary sections so the section attribute is
+not available on all platforms. If you need to map the entire contents of a
+module to a particular section, consider using the facilities of the linker
+instead.
+
+@smallexample
+@@section("bar") extern void func();
+@@section("stack") ubyte[10000] stack;
+@end smallexample
+
+@item @@(gcc.attributes.simd)
+@cindex @code{simd} function attribute
+
+The @code{@@simd} attribute enables creation of one or more function versions
+that can process multiple arguments using SIMD instructions from a single
+invocation. Specifying this attribute allows compiler to assume that such
+versions are available at link time (provided in the same or another module).
+Generated versions are target-dependent and described in the corresponding
+Vector ABI document.
+
+@smallexample
+@@simd double sqrt(double x);
+@end smallexample
+
+@item @@(gcc.attributes.simd_clones ("@var{mask}"))
+@cindex @code{simd_clones} function attribute
+
+The @code{@@simd_clones} attribute is the same as @code{@@simd}, but also
+includes a @var{mask} argument. Valid masks values are @code{notinbranch} or
+@code{inbranch}, and instructs the compiler to generate non-masked or masked
+clones correspondingly.
+
+@smallexample
+@@simd_clones("notinbranch") double atan2(double y, double x);
+@end smallexample
+
+@item @@(gcc.attributes.symver ("@var{arguments}"))
+@cindex @code{symver} function attribute
+
+The @code{@@symver} attribute creates a symbol version on ELF targets.
+The syntax of the string parameter is @code{"@var{name}@@@var{nodename}"}.
+The @var{name} part of the parameter is the actual name of the symbol by which
+it will be externally referenced. The @var{nodename} portion should be the
+name of a node specified in the version script supplied to the linker when
+building a shared library. Versioned symbol must be defined and must be
+exported with default visibility.
+
+Finally if the parameter is @code{"@var{name}@@@@@var{nodename}"} then in
+addition to creating a symbol version (as if
+@code{"@var{name}@@@var{nodename}"} was used) the version will be also used to
+resolve @var{name} by the linker.
+
+@smallexample
+@@symver("foo@@VERS_1") int foo_v1();
+@end smallexample
+
+@item @@(gcc.attributes.target ("@var{options}"))
+@cindex @code{target} function attribute
+
+The @code{@@target} attribute is used to specify that a function is to be
+compiled with different target options than specified on the command line. One
+or more strings can be provided as arguments, separated by commas to specify
+multiple options. Each string consists of one or more comma-separated suffixes
+to the @option{-m} prefix jointly forming the name of a machine-dependent
+option.
+
+The target attribute can be used for instance to have a function compiled with
+a different ISA (instruction set architecture) than the default.
+
+The options supported are specific to each target.
+
+@smallexample
+@@target("arch=core2") void core2_func();
+@@target("sse3") void sse3_func();
+@end smallexample
+
+@item @@(gcc.attributes.target_clones ("@var{options}"))
+@cindex @code{target_clones} function attribute
+
+The @code{@@target_clones} attribute is used to specify that a function be
+cloned into multiple versions compiled with different target @var{options} than
+specified on the command line. The supported options and restrictions are the
+same as for @code{@@target} attribute.
+
+It also creates a resolver function that dynamically selects a clone suitable
+for current architecture. The resolver is created only if there is a usage of
+a function with @code{@@target_clones} attribute.
+
+@smallexample
+@@target_clones("sse4.1,avx,default") double func(double x);
+@end smallexample
+
+@item @@(gcc.attributes.used)
+@cindex @code{used} function attribute
+@cindex @code{used} variable attribute
+
+The @code{@@used} attribute, annotated to a function or variable, means that
+code must be emitted for the function even if it appears that the function is
+not referenced. This is useful, for example, when the function is referenced
+only in inline assembly.
+
+@smallexample
+@@used __gshared int var = 0x1000;
+@end smallexample
+
+@item @@(gcc.attributes.visibility ("@var{visibilityName}"))
+@cindex @code{visibility} function attribute
+@cindex @code{visibility} variable attribute
+
+The @code{@@visibility} attribute affects the linkage of the declaration to
+which it is attached. It can be applied to variables, types, and functions.
+
+There are four supported visibility_type values: @code{default}, @code{hidden},
+@code{protected}, or @code{internal} visibility.
+
+@smallexample
+@@visibility("protected") void func() @{ @}
+@end smallexample
+
+@item @@(gcc.attributes.weak)
+@cindex @code{weak} function attribute
+@cindex @code{weak} variable attribute
+
+The @code{@@weak} attribute causes a declaration of an external symbol to be
+emitted as a weak symbol rather than a global. This is primarily useful in
+defining library functions that can be overridden in user code, though it can
+also be used with non-function declarations. The overriding symbol must have
+the same type as the weak symbol. In addition, if it designates a variable it
+must also have the same size and alignment as the weak symbol.
+
+Weak symbols are supported for ELF targets, and also for a.out targets when
+using the GNU assembler and linker.
+
+@smallexample
+@@weak int func() @{ return 1; @}
+@end smallexample
+
+@end table
+
+@c --------------------------------------------------------
+
+@node Other Attributes
+@subsection Other Attributes
+
+The following attributes are defined for compatibility with other compilers.
+
+@table @code
+
+@item @@(gcc.attributes.allocSize (@var{sizeArgIdx}))
+@itemx @@(gcc.attributes.allocSize (@var{sizeArgIdx}, @var{numArgIdx}))
+@item @@(gcc.attributes.allocSize (@var{sizeArgIdx}))
+@cindex @code{allocSize} function attribute
+
+These attributes are a synonym for
+@code{@@alloc_size(@var{sizeArgIdx}, @var{numArgIdx}, true)}.
+Unlike @code{@@alloc_size}, it uses 0-based index of the function arguments.
+
+@item @@(gcc.attributes.assumeUsed)
+@cindex @code{assumeUsed} function attribute
+@cindex @code{assumeUsed} variable attribute
+
+This attribute is a synonym for @code{@@used}.
+
+@item @@(gcc.attributes.dynamicCompile)
+@itemx @@(gcc.attributes.dynamicCompileConst)
+@itemx @@(gcc.attributes.dynamicCompileEmit)
+@cindex @code{dynamicCompile} function attribute
+
+These attributes are accepted, but have no effect.
+
+@item @@(gcc.attributes.fastmath)
+@cindex @code{fastmath} function attribute
+
+This attribute is a synonym for @code{@@optimize("Ofast")}. Explicitly sets
+"fast-math" for a function, enabling aggressive math optimizations.
+
+@item @@(gcc.attributes.hidden)
+@cindex @code{hidden} function attribute
+@cindex @code{hidden} variable attribute
+
+This attribute is a synonym for @code{@@visibility("hidden")}. Sets the
+visibility of a function or global variable to "hidden".
+
+@item @@(gcc.attributes.naked)
+@cindex @code{naked} function attribute
+
+This attribute is a synonym for @code{@@attribute("naked")}. Adds GCC's
+"naked" attribute to a function, disabling function prologue / epilogue
+emission. Intended to be used in combination with basic @code{asm} statements.
+While using extended @code{asm} or a mixture of basic @code{asm} and D code may
+appear to work, they cannot be depended upon to work reliably and are not
+supported.
+
+@item @@(gcc.attributes.noSanitize ("@var{sanitize_option}"))
+@cindex @code{noSanitize} function attribute
+
+This attribute is a synonym for @code{@@no_sanitize("sanitize_option")}.
+
+
+@item @@(gcc.attributes.optStrategy ("@var{strategy}"))
+@cindex @code{optStrategy} function attribute
+
+This attribute is a synonym for @code{@@optimize("O0")} and
+@code{@@optimize("Os")}. Sets the optimization strategy for a function. Valid
+strategies are "none", "optsize", "minsize". The strategies are mutually
+exclusive.
+
+@item @@(gcc.attributes.polly)
+
+This attribute is a synonym for
+@code{@@optimize("loop-parallelize-all", "loop-nest-optimize")}.
+Only effective when GDC was built with ISL included.
+
+@end table
+
+@c --------------------------------------------------------
+
+@node Target Attributes
+@subsection Target-specific Attributes
+
+Many targets have their own target-specific attributes. These are also exposed
+via the @code{gcc.attributes} module with use of the generic
+@code{@@(gcc.attributes.attribute)} UDA function.
+
+@xref{Attribute Syntax}, for details of the exact syntax for using attributes.
+
+See the function and variable attribute documentation in the GCC manual for
+more information about what attributes are available on each target.
+
+Examples of using x86-specific target attributes are shown as follows:
+
+@smallexample
+import gcc.attributes;
+
+@@attribute("cdecl")
+@@attribute("fastcall")
+@@attribute("ms_abi")
+@@attribute("sysv_abi")
+@@attribute("callee_pop_aggregate_return", 1)
+@@attribute("ms_hook_prologue")
+@@attribute("naked")
+@@attribute("regparm", 2)
+@@attribute("sseregparm")
+@@attribute("force_align_arg_pointer")
+@@attribute("stdcall")
+@@attribute("no_caller_saved_registers")
+@@attribute("interrupt")
+@@attribute("indirect_branch", "thunk")
+@@attribute("function_return", "keep"))
+@@attribute("nocf_check")
+@@attribute("cf_check")
+@@attribute("indirect_return")
+@@attribute("fentry_name", "nop")
+@@attribute("fentry_section", "__entry_loc")
+@@attribute("nodirect_extern_access")
+
+@end smallexample
+
+
+@c --------------------------------------------------------
+
+@node Builtin Functions
+@section Built-in Functions
+@cindex built-in functions
+
+GCC provides a large number of built-in functions that are made available in
+GNU D by importing the @code{gcc.builtins} module. Declarations in this module
+are automatically created by the compiler. All declarations start with
+@code{__builtin_}. Refer to the built-in function documentation in the GCC
+manual for a full list of functions that are available.
+
+@menu
+* Builtin Types::
+* Query Builtins::
+* Other Builtins::
+@end menu
+
+@c --------------------------------------------------------
+
+@node Builtin Types
+@subsection Built-in Types
+@cindex built-in types
+
+In addition to built-in functions, the following types are defined in the
+@code{gcc.builtins} module.
+
+@table @code
+@item ___builtin_clong
+The D equivalent of the target's C @code{long} type.
+
+@item ___builtin_clonglong
+The D equivalent of the target's C @code{long long} type.
+
+@item ___builtin_culong
+The D equivalent of the target's C @code{unsigned long} type.
+
+@item ___builtin_culonglong
+The D equivalent of the target's C @code{unsigned long long} type.
+
+@item ___builtin_machine_byte
+Signed unit-sized integer type.
+
+@item ___builtin_machine_int
+Signed word-sized integer type.
+
+@item ___builtin_machine_ubyte
+Unsigned unit-sized integer type.
+
+@item ___builtin_machine_uint
+Unsigned word-sized integer type.
+
+@item ___builtin_pointer_int
+Signed pointer-sized integer type.
+
+@item ___builtin_pointer_uint
+Unsigned pointer-sized integer type.
+
+@item ___builtin_unwind_int
+The D equivalent of the target's C @code{_Unwind_Sword} type.
+
+@item ___builtin_unwind_uint
+The D equivalent of the target's C @code{_Unwind_Word} type.
+
+@item ___builtin_va_list
+The target's @code{va_list} type.
+@end table
+
+@c --------------------------------------------------------
+
+@node Query Builtins
+@subsection Querying Available Built-ins
+@cindex built-in functions
+
+Not all of the functions are supported, and some target-specific functions may
+only be available when compiling for a particular ISA. One way of finding out
+what is exposed by the built-ins module is by generating a D interface file.
+Assuming you have no file @file{builtins.d}, the command
+@smallexample
+ echo "module gcc.builtins;" > builtins.d; gdc -H -fsyntax-only builtins.d
+@end smallexample
+@noindent
+will save all built-in declarations to the file @file{builtins.di}.
+
+Another way to determine whether a specific built-in is available is by using
+compile-time reflection.
+@smallexample
+enum X86_HAVE_SSE3 = __traits(compiles, __builtin_ia32_haddps);
+enum X86_HAVE_SSSE3 = __traits(compiles, __builtin_ia32_pmulhrsw128);
+enum X86_HAVE_SSE41 = __traits(compiles, __builtin_ia32_dpps);
+enum X86_HAVE_SSE42 = __traits(compiles, __builtin_ia32_pcmpgtq);
+enum X86_HAVE_AVX = __traits(compiles, __builtin_ia32_vbroadcastf128_pd256);
+enum X86_HAVE_AVX2 = __traits(compiles, __builtin_ia32_gathersiv2df);
+enum X86_HAVE_BMI2 = __traits(compiles, __builtin_ia32_pext_si);
+@end smallexample
+
+@c --------------------------------------------------------
+
+@node Other Builtins
+@subsection Other Built-in Functions
+@cindex built-in functions
+@opindex fno-builtin
+
+As well as built-ins being available from the @code{gcc.builtins} module, GNU D
+will also recognize when an @code{extern(C)} library function is a GCC
+built-in. Many of these functions are only optimized in certain cases; if they
+are not optimized in a particular case, a call to the library function is
+emitted. This optimization can be disabled with the @option{-fno-builtin}
+option (@pxref{Runtime Options}).
+
+In the @code{core.stdc.complex} module, the functions
+@code{cabs}, @code{cabsf}, @code{cabsl}, @code{cacos}, @code{cacosf},
+@code{cacosh}, @code{cacoshf}, @code{cacoshl}, @code{cacosl}, @code{carg},
+@code{cargf}, @code{cargl}, @code{casin}, @code{casinf}, @code{casinh},
+@code{casinhf}, @code{casinhl}, @code{casinl}, @code{catan}, @code{catanf},
+@code{catanh}, @code{catanhf}, @code{catanhl}, @code{catanl}, @code{ccos},
+@code{ccosf}, @code{ccosh}, @code{ccoshf}, @code{ccoshl}, @code{ccosl},
+@code{cexp}, @code{cexpf}, @code{cexpl}, @code{clog}, @code{clogf},
+@code{clogl}, @code{conj}, @code{conjf}, @code{conjl}, @code{cpow},
+@code{cpowf}, @code{cpowl}, @code{cproj}, @code{cprojf}, @code{cprojl},
+@code{csin}, @code{csinf}, @code{csinh}, @code{csinhf}, @code{csinhl},
+@code{csinl}, @code{csqrt}, @code{csqrtf}, @code{csqrtl}, @code{ctan},
+@code{ctanf}, @code{ctanh}, @code{ctanhf}, @code{ctanhl}, @code{ctanl}
+may be handled as built-in functions. All these functions have corresponding
+versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module.
+
+In the @code{core.stdc.ctype} module, the functions
+@code{isalnum}, @code{isalpha}, @code{isblank}, @code{iscntrl}, @code{isdigit},
+@code{isgraph}, @code{islower}, @code{isprint}, @code{ispunct}, @code{isspace},
+@code{isupper}, @code{isxdigit}, @code{tolower}, @code{toupper}
+may be handled as built-in functions. All these functions have corresponding
+versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module.
+
+In the @code{core.stdc.fenv} module, the functions
+@code{feclearexcept}, @code{fegetenv}, @code{fegetexceptflag},
+@code{fegetround}, @code{feholdexcept}, @code{feraiseexcept}, @code{fesetenv},
+@code{fesetexceptflag}, @code{fesetround}, @code{fetestexcept},
+@code{feupdateenv}
+may be handled as built-in functions. All these functions have corresponding
+versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module.
+
+In the @code{core.stdc.inttypes} module, the function @code{imaxabs} may be
+handled as a built-in function. All these functions have corresponding
+versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module.
+
+In the @code{core.stdc.math} module, the functions
+@code{acos}, @code{acosf}, @code{acosh}, @code{acoshf}, @code{acoshl},
+@code{acosl}, @code{asin}, @code{asinf}, @code{asinh}, @code{asinhf},
+@code{asinhl}, @code{asinl}, @code{atan}, @code{atan2}, @code{atan2f},
+@code{atan2l}, @code{atanf}, @code{atanh}, @code{atanhf}, @code{atanhl},
+@code{atanl}, @code{cbrt}, @code{cbrtf}, @code{cbrtl}, @code{ceil},
+@code{ceilf}, @code{ceill}, @code{copysign}, @code{copysignf},
+@code{copysignl}, @code{cos}, @code{cosf}, @code{cosh}, @code{coshf},
+@code{coshl}, @code{cosl}, @code{erf}, @code{erfc}, @code{erfcf}, @code{erfcl},
+@code{erff}, @code{erfl}, @code{exp}, @code{exp2}, @code{exp2f}, @code{exp2l},
+@code{expf}, @code{expl}, @code{expm1}, @code{expm1f}, @code{expm1l},
+@code{fabs}, @code{fabsf}, @code{fabsl}, @code{fdim}, @code{fdimf},
+@code{fdiml}, @code{floor}, @code{floorf}, @code{floorl}, @code{fma},
+@code{fmaf}, @code{fmal}, @code{fmax}, @code{fmaxf}, @code{fmaxl}, @code{fmin},
+@code{fminf}, @code{fminl}, @code{fmod}, @code{fmodf}, @code{fmodl},
+@code{frexp}, @code{frexpf}, @code{frexpl}, @code{hypot}, @code{hypotf},
+@code{hypotl}, @code{ilogb}, @code{ilogbf}, @code{ilogbl}, @code{isinf},
+@code{isnan}, @code{ldexp}, @code{ldexpf}, @code{ldexpl}, @code{lgamma},
+@code{lgammaf}, @code{lgammal}, @code{llrint}, @code{llrintf}, @code{llrintl},
+@code{llround}, @code{llroundf}, @code{llroundl}, @code{log}, @code{log10},
+@code{log10f}, @code{log10l}, @code{log1p}, @code{log1pf}, @code{log1pl},
+@code{log2}, @code{log2f}, @code{log2l}, @code{logb}, @code{logbf},
+@code{logbl}, @code{logf}, @code{logl}, @code{lrint}, @code{lrintf},
+@code{lrintl}, @code{lround}, @code{lroundf}, @code{lroundl}, @code{modf},
+@code{modff}, @code{modfl}, @code{nan}, @code{nanf}, @code{nanl},
+@code{nearbyint}, @code{nearbyintf}, @code{nearbyintl}, @code{nextafter},
+@code{nextafterf}, @code{nextafterl}, @code{nexttoward}, @code{nexttowardf},
+@code{nexttowardl}, @code{pow}, @code{powf}, @code{powl}, @code{remainder},
+@code{remainderf}, @code{remainderl}, @code{remquo}, @code{remquof},
+@code{remquol}, @code{rint}, @code{rintf}, @code{rintl}, @code{round},
+@code{roundf}, @code{roundl}, @code{scalbln}, @code{scalblnf}, @code{scalblnl},
+@code{scalbn}, @code{scalbnf}, @code{scalbnl}, @code{signbit}, @code{sin},
+@code{sinf}, @code{sinh}, @code{sinhf}, @code{sinhl}, @code{sinl}, @code{sqrt},
+@code{sqrtf}, @code{sqrtl}, @code{tan}, @code{tanf}, @code{tanh}, @code{tanhf},
+@code{tanhl}, @code{tanl}, @code{tgamma}, @code{tgammaf}, @code{tgammal},
+@code{trunc}, @code{truncf}, @code{truncl}
+may be handled as built-in functions. All these functions have corresponding
+versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module.
+
+In the @code{core.stdc.stdio} module, the functions
+@code{fprintf}, @code{fputc}, @code{fputc_unlocked}, @code{fputs},
+@code{fwrite}, @code{printf}, @code{puts}, @code{snprintf}, @code{sprintf},
+@code{vfprintf}, @code{vprintf}, @code{vsnprintf}, @code{vsprintf}
+may be handled as built-in functions. All these functions have corresponding
+versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module.
+
+In the @code{core.stdc.stdlib} module, the functions
+@code{abort}, @code{abs}, @code{aligned_alloc}, @code{alloca}, @code{calloc},
+@code{exit}, @code{_Exit}, @code{free}, @code{labs}, @code{llabs},
+@code{malloc}, @code{realloc}
+may be handled as built-in functions. All these functions have corresponding
+versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module.
+
+In the @code{core.stdc.string} module, the functions
+@code{memchr}, @code{memcmp}, @code{memcpy}, @code{memmove}, @code{memset},
+@code{strcat}, @code{strchr}, @code{strcmp}, @code{strcpy}, @code{strcspn},
+@code{strdup}, @code{strlen}, @code{strncat}, @code{strncmp}, @code{strncpy},
+@code{strpbrk}, @code{strrchr}, @code{strspn}, @code{strstr}
+may be handled as built-in functions. All these functions have corresponding
+versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module.
+
+In the @code{core.stdc.time} module, the function @code{strftime} may be
+handled as a built-in function. All these functions have corresponding
+versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module.
+
+In the @code{core.stdc.wctype} module, the functions
+@code{iswalnum}, @code{iswalpha}, @code{iswblank}, @code{iswcntrl},
+@code{iswdigit}, @code{iswgraph}, @code{iswlower}, @code{iswprint},
+@code{iswpunct}, @code{iswspace}, @code{iswupper}, @code{iswxdigit},
+@code{towlower}, @code{towupper}
+may be handled as built-in functions. All these functions have corresponding
+versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module.
+
+Within the @code{core.sys} package for POSIX and platform definitions, the
+functions
+@code{putchar_unlocked}, @code{putc_unlocked}, @code{posix_memalign},
+@code{ffs}, @code{strcasecmp}, @code{strncasecmp}, @code{stpcpy},
+@code{stpncpy}, @code{strndup}, @code{strnlen}, @code{execl}, @code{execle},
+@code{execlp}, @code{execv}, @code{execve}, @code{execvp}, @code{_exit},
+@code{fork}
+may be handled as built-in functions. All these functions have corresponding
+versions prefixed with @code{__builtin_} in the @code{gcc.builtins} module.
+
+
+@c --------------------------------------------------------
+
+@node ImportC
+@section Importing C Sources into D
+@cindex importC
+
+ImportC is a C preprocessor and parser embedded into the GNU D implementation.
+It enables direct importation of C files, without needing to manually prepare a
+D file corresponding to the declarations in the C file.
+
+ImportC is an implementation of ISO/IEC 9899:2011, which will be referred to as
+C11. Prior versions, such as C99, C89, and K+R C, are not supported.
+
+Assuming you have no file @file{cstdio.c} or @file{main.d}, the commands
+@smallexample
+ cat > cstdio.c << @@EOC
+ int printf(const char*, ...);
+ @@EOC
+ cat > main.d << @@EOD
+ import cstdio;
+ void main() @{ printf("Hello ImportC\n"); @}
+ @@EOD
+ gdc main.d -o main; ./main
+@end smallexample
+will generate a program which will print @samp{Hello ImportC}.
+
+ImportC does not have a preprocessor. It is designed to compile C files after
+they have been first run through the C preprocessor. If the C file has a
+@samp{.i} extension, the file is presumed to be already preprocessed.
+Preprocessing can be run manually:
+@smallexample
+ gcc -E file.c > file.i
+@end smallexample
+
+@noindent
+ImportC collects all the @code{#define} macros from the preprocessor run when
+it is run automatically. The macros that look like manifest constants, such as:
+@smallexample
+#define COLOR 0x123456
+@end smallexample
+are interpreted as D manifest constant declarations of the form:
+@smallexample
+enum COLOR = 0x123456;
+@end smallexample
+
+@noindent
+The variety of macros that can be interpreted as D declarations may be
+expanded, but will never encompass all the metaprogramming uses of C macros.
+
+GNU D does not directly compile C files into modules that can be linked in with
+D code to form an executable. When given a source file with the suffix
+@samp{.c}, the compiler driver program @command{gdc} instead runs the
+subprogram @command{cc1}.
+
+@smallexample
+gdc file1.d file2.c // d21 file1.d -o file1.s
+ // cc1 file2.c -o file2.s
+ // as file1.s -o file1.o
+ // as file2.s -o file2.o
+ // ld file1.o file2.o
+@end smallexample
+
+
+@c --------------------------------------------------------
+
+@node Inline Assembly
+@section Inline Assembly
+@cindex assembly language in D
+
+The @code{asm} keyword allows you to embed assembler instructions within D
+code. GNU D provides two forms of inline @code{asm} statements. A @dfn{basic
+@code{asm}} statement is one with no operands, while an @dfn{extended
+@code{asm}} statement includes one or more operands.
+
+@example
+asm @var{FunctionAttributes} @{
+ @var{AssemblerInstruction} ;
+@}
+
+asm @var{FunctionAttributes} @{
+ @var{AssemblerTemplate}
+ : @var{OutputOperands}
+ @r{[} : @var{InputOperands}
+ @r{[} : @var{Clobbers}
+ @r{[} : @var{GotoLabels} @r{]} @r{]} @r{]} ;
+@}
+@end example
+
+@noindent
+The extended form is preferred for mixing D and assembly language within a
+function, but to include assembly language in a function declared with the
+@code{naked} attribute you must use basic @code{asm}.
+
+@smallexample
+uint incr (uint value)
+@{
+ uint result;
+ asm @{ "incl %0"
+ : "=a" (result)
+ : "a" (value);
+ @}
+ return result;
+@}
+@end smallexample
+
+@noindent
+Multiple assembler instructions can appear within an @code{asm} block, or the
+instruction template can be a multi-line or concatenated string. In both
+cases, GCC's optimizers won't discard or move any instruction within the
+statement block.
+@smallexample
+bool hasCPUID()
+@{
+ uint flags = void;
+ asm nothrow @@nogc @{
+ "pushfl";
+ "pushfl";
+ "xorl %0, (%%esp)" :: "i" (0x00200000);
+ "popfl";
+ "pushfl";
+ "popl %0" : "=a" (flags);
+ "xorl (%%esp), %0" : "=a" (flags);
+ "popfl";
+ @}
+ return (flags & 0x0020_0000) != 0;
+@}
+@end smallexample
+
+@noindent
+The instruction templates for both basic and extended @code{asm} can be any
+expression that can be evaluated at compile-time to a string, not just string
+literals.
+
+@smallexample
+uint invert(uint v)
+@{
+ uint result;
+ asm @@safe @@nogc nothrow pure @{
+ genAsmInsn(`invert`)
+ : [res] `=r` (result)
+ : [arg1] `r` (v);
+ @}
+ return result;
+
+@}
+@end smallexample
+
+@noindent
+The total number of input + output + goto operands is limited to 30.
+
+
+@c --------------------------------------------------------
+
+@node Intrinsics
+@section Intrinsics
+@cindex intrinsics
+
+The D language specification itself does not define any intrinsics that a
+compatible compiler must implement. Rather, within the D core library there
+are a number of modules that define primitives with generic implementations.
+While the generic versions of these functions are computationally expensive
+relative to the cost of the operation itself, compiler implementations are free
+to recognize them and generate equivalent and faster code.
+
+The following are the kinds of intrinsics recognized by GNU D.
+
+@menu
+* Bit Operation Intrinsics::
+* Integer Overflow Intrinsics::
+* Math Intrinsics::
+* Variadic Intrinsics::
+* Volatile Intrinsics::
+* CTFE Intrinsics::
+@end menu
+
+@c --------------------------------------------------------
+
+@node Bit Operation Intrinsics
+@subsection Bit Operation Intrinsics
+@cindex intrinsics, bitop
+
+The following functions are a collection of intrinsics that do bit-level
+operations, available by importing the @code{core.bitop} module.
+
+Although most are named after x86 hardware instructions, it is not guaranteed
+that they will result in generating equivalent assembly on x86. If the
+compiler determines there is a better way to get the same result in hardware,
+then that will be used instead.
+
+@deftypefn {Function} {int} core.bitop.bsf (uint @var{v})
+@deftypefnx {Function} {int} core.bitop.bsf (ulong @var{v})
+
+Scans the bits in @var{v} starting with bit @code{0}, looking for the first set
+bit. Returns the bit number of the first bit set. The return value is
+undefined if @var{v} is zero.
+
+This intrinsic is the same as the GCC built-in function @code{__builtin_ctz}.
+@end deftypefn
+
+@deftypefn {Function} {int} core.bitop.bsr (uint @var{v})
+@deftypefnx {Function} {int} core.bitop.bsr (ulong @var{v})
+
+Scans the bits in @var{v} from the most significant bit to the least
+significant bit, looking for the first set bit. Returns the bit number of the
+first bit set. The return value is undefined if @var{v} is zero.
+
+This intrinsic is equivalent to writing the following:
+@smallexample
+result = __builtin_clz(v) ^ (v.sizeof * 8 - 1)
+@end smallexample
+@end deftypefn
+
+@deftypefn {Function} {int} core.bitop.bt (scope const(uint*) @var{p}, uint @var{bitnum})
+@deftypefnx {Function} {int} core.bitop.bt (scope const(uint*) @var{p}, uint @var{bitnum})
+
+Tests the bit @var{bitnum} in the input parameter @var{p}. Returns a non-zero
+value if the bit was set, and a zero if it was clear.
+
+This intrinsic is equivalent to writing the following:
+@smallexample
+immutable bits_per_unit = (*p).sizeof * 8;
+immutable bit_mask = size_t(1) << (bitnum % bits_per_unit);
+
+result = (p[bitnum / bits_per_unit] & bit_mask) != 0;
+@end smallexample
+@end deftypefn
+
+@deftypefn {Function} {int} core.bitop.btc (uint* @var{p}, uint @var{bitnum})
+@deftypefnx {Function} {int} core.bitop.btc (ulong* @var{p}, ulong @var{bitnum})
+
+Tests and complements the bit @var{bitnum} in the input parameter @var{p}.
+Returns a non-zero value if the bit was set, and a zero if it was clear.
+
+This intrinsic is equivalent to writing the following:
+@smallexample
+immutable bits_per_unit = (*p).sizeof * 8;
+immutable bit_mask = size_t(1) << (bitnum % bits_per_unit);
+
+result = (p[bitnum / bits_per_unit] & bit_mask) != 0;
+
+p[bitnum / bits_per_unit] ^= bit_mask;
+@end smallexample
+@end deftypefn
+
+@deftypefn {Function} {int} core.bitop.btr (uint* @var{p}, uint @var{bitnum})
+@deftypefnx {Function} {int} core.bitop.btr (ulong* @var{p}, ulong @var{bitnum})
+
+Tests and resets (sets to 0) the bit @var{bitnum} in the input parameter
+@var{p}. Returns a non-zero value if the bit was set, and a zero if it was
+clear.
+
+This intrinsic is equivalent to writing the following:
+@smallexample
+immutable bits_per_unit = (*p).sizeof * 8;
+immutable bit_mask = size_t(1) << (bitnum % bits_per_unit);
+
+result = (p[bitnum / bits_per_unit] & bit_mask) != 0;
+
+p[bitnum / bits_per_unit] &= ~bit_mask;
+@end smallexample
+@end deftypefn
+
+@deftypefn {Function} {int} core.bitop.bts (uint* @var{p}, uint @var{bitnum})
+@deftypefnx {Function} {int} core.bitop.bts (ulong* @var{p}, ulong @var{bitnum})
+
+Tests and sets the bit @var{bitnum} in the input parameter @var{p}. Returns a
+non-zero value if the bit was set, and a zero if it was clear.
+
+This intrinsic is equivalent to writing the following:
+@smallexample
+immutable bits_per_unit = (*p).sizeof * 8;
+immutable bit_mask = size_t(1) << (bitnum % bits_per_unit);
+
+result = (p[bitnum / bits_per_unit] & bit_mask) != 0;
+
+p[bitnum / bits_per_unit] |= bit_mask;
+@end smallexample
+@end deftypefn
+
+
+@deftypefn {Function} {ushort} core.bitop.byteswap (ushort @var{x})
+@deftypefnx {Function} {uint} core.bitop.bswap (uint @var{x})
+@deftypefnx {Function} {ulong} core.bitop.bswap (ulong @var{x})
+
+Swaps the bytes in @var{x} end-to-end; for example, in a 4-byte @code{uint},
+byte @code{0} becomes byte @code{3}, byte @code{1} becomes byte @code{2}, etc.
+
+This intrinsic is the same as the GCC built-in function @code{__builtin_bswap}.
+@end deftypefn
+
+@deftypefn {Function} {int} core.bitop.popcnt (uint @var{x})
+@deftypefnx {Function} {int} core.bitop.popcnt (ulong @var{x})
+
+Calculates the number of set bits in @var{x}.
+
+This intrinsic is the same as the GCC built-in function
+@code{__builtin_popcount}.
+@end deftypefn
+
+@deftypefn {Template} {T} core.bitop.rol (T)(const T @var{value}, const uint @var{count})
+@deftypefnx {Template} {T} core.bitop.rol (uint @var{count}, T)(const T @var{value})
+
+Bitwise rotate @var{value} left by @var{count} bit positions.
+
+This intrinsic is equivalent to writing the following:
+@smallexample
+result = cast(T) ((value << count) | (value >> (T.sizeof * 8 - count)));
+@end smallexample
+@end deftypefn
+
+@deftypefn {Template} {T} core.bitop.ror (T)(const T @var{value}, const uint @var{count})
+@deftypefnx {Template} {T} core.bitop.ror (uint @var{count}, T)(const T @var{value})
+
+Bitwise rotate @var{value} right by @var{count} bit positions.
+
+This intrinsic is equivalent to writing the following:
+@smallexample
+result = cast(T) ((value >> count) | (value << (T.sizeof * 8 - count)));
+@end smallexample
+@end deftypefn
+
+@c --------------------------------------------------------
+
+@node Integer Overflow Intrinsics
+@subsection Integer Overflow Intrinsics
+@cindex intrinsics, checkedint
+
+The following functions are a collection of intrinsics that implement integral
+arithmetic primitives that check for out-of-range results, available by
+importing the @code{core.checkedint} module.
+
+In all intrinsics, the overflow is sticky, meaning a sequence of operations can
+be done and overflow need only be checked at the end.
+
+@deftypefn {Function} {int} core.checkedint.adds (int @var{x}, int @var{y}, @
+ ref bool @var{overflow})
+@deftypefnx {Function} {long} core.checkedint.adds (long @var{x}, long @var{y}, @
+ ref bool @var{overflow})
+
+Add two signed integers, checking for overflow.
+
+This intrinsic is the same as the GCC built-in function
+@code{__builtin_sadd_overflow}.
+@end deftypefn
+
+@deftypefn {Function} {int} core.checkedint.addu (int @var{x}, int @var{y}, @
+ ref bool @var{overflow})
+@deftypefnx {Function} {long} core.checkedint.addu (long @var{x}, long @var{y}, @
+ ref bool @var{overflow})
+
+Add two unsigned integers, checking for overflow.
+
+This intrinsic is the same as the GCC built-in function
+@code{__builtin_uadd_overflow}.
+@end deftypefn
+
+@deftypefn {Function} {int} core.checkedint.muls (int @var{x}, int @var{y}, @
+ ref bool @var{overflow})
+@deftypefnx {Function} {long} core.checkedint.muls (long @var{x}, long @var{y}, @
+ ref bool @var{overflow})
+
+Multiply two signed integers, checking for overflow.
+
+This intrinsic is the same as the GCC built-in function
+@code{__builtin_smul_overflow}.
+@end deftypefn
+
+@deftypefn {Function} {int} core.checkedint.mulu (int @var{x}, int @var{y}, @
+ ref bool @var{overflow})
+@deftypefnx {Function} {long} core.checkedint.mulu (long @var{x}, long @var{y}, @
+ ref bool @var{overflow})
+
+Multiply two unsigned integers, checking for overflow.
+
+This intrinsic is the same as the GCC built-in function
+@code{__builtin_umul_overflow}.
+@end deftypefn
+
+@deftypefn {Function} {int} core.checkedint.negs (int @var{x}, @
+ ref bool @var{overflow})
+@deftypefnx {Function} {long} core.checkedint.negs (long @var{x}, @
+ ref bool @var{overflow})
+
+Negates an integer.
+
+This intrinsic is equivalent to writing the following:
+@smallexample
+result = __builtin_ssub (0, x, overflow);
+@end smallexample
+@end deftypefn
+
+@deftypefn {Function} {int} core.checkedint.subs (int @var{x}, int @var{y}, @
+ ref bool @var{overflow})
+@deftypefnx {Function} {long} core.checkedint.subs (long @var{x}, long @var{y}, @
+ ref bool @var{overflow})
+
+Substract two signed integers, checking for overflow.
+
+This intrinsic is the same as the GCC built-in function
+@code{__builtin_ssub_overflow}.
+@end deftypefn
+
+@deftypefn {Function} {int} core.checkedint.subu (int @var{x}, int @var{y}, @
+ ref bool @var{overflow})
+@deftypefnx {Function} {long} core.checkedint.subu (long @var{x}, long @var{y}, @
+ ref bool @var{overflow})
+
+Substract two unsigned integers, checking for overflow.
+
+This intrinsic is the same as the GCC built-in function
+@code{__builtin_usub_overflow}.
+@end deftypefn
+
+@c --------------------------------------------------------
+
+@node Math Intrinsics
+@subsection Math Intrinsics
+@cindex intrinsics, math
+
+The following functions are a collection of mathematical intrinsics, available
+by importing the @code{core.math} module.
+
+@deftypefn {Function} {float} core.math.cos (float x)
+@deftypefnx {Function} {double} core.math.cos (double x)
+@deftypefnx {Function} {real} core.math.cos (real x)
+
+Returns cosine of @var{x}, where @var{x} is in radians. The return value is
+undefined if @var{x} is greater than @math{2^{64}}.
+
+This intrinsic is the same as the GCC built-in function @code{__builtin_cos}.
+@end deftypefn
+
+@deftypefn {Function} {float} core.math.fabs (float x)
+@deftypefnx {Function} {double} core.math.fabs (double x)
+@deftypefnx {Function} {real} core.math.fabs (real x)
+
+Compute the absolute value of @var{x}.
+
+This intrinsic is the same as the GCC built-in function @code{__builtin_fabs}.
+@end deftypefn
+
+@deftypefn {Function} {float} core.math.ldexp (float n, int exp)
+@deftypefnx {Function} {double} core.math.ldexp (double n, int exp)
+@deftypefnx {Function} {real} core.math.ldexp (real n, int exp)
+
+Compute @math{n * 2^{exp}}.
+
+This intrinsic is the same as the GCC built-in function @code{__builtin_ldexp}.
+@end deftypefn
+
+@deftypefn {Function} {float} core.math.rint (float x)
+@deftypefnx {Function} {double} core.math.rint (double x)
+@deftypefnx {Function} {real} core.math.rint (real x)
+
+Rounds @var{x} to the nearest integer value, using the current rounding mode.
+If the return value is not equal to @var{x}, the @code{FE_INEXACT} exception is
+raised. @code{nearbyint} performs the same operation, but does not set the
+@code{FE_INEXACT} exception.
+
+This intrinsic is the same as the GCC built-in function @code{__builtin_rint}.
+@end deftypefn
+
+@deftypefn {Function} {float} core.math.rndtol (float x)
+@deftypefnx {Function} {double} core.math.rndtol (double x)
+@deftypefnx {Function} {real} core.math.rndtol (real x)
+
+Returns @var{x} rounded to a long value using the current rounding mode.
+If the integer value of @var{x} is greater than @code{long.max}, the result
+is indeterminate.
+
+This intrinsic is the same as the GCC built-in function
+@code{__builtin_llround}.
+@end deftypefn
+
+@deftypefn {Function} {float} core.math.sin (float x)
+@deftypefnx {Function} {double} core.math.sin (double x)
+@deftypefnx {Function} {real} core.math.sin (real x)
+
+Returns sine of @var{x}, where @var{x} is in radians. The return value is
+undefined if @var{x} is greater than @math{2^{64}}.
+
+This intrinsic is the same as the GCC built-in function @code{__builtin_sin}.
+@end deftypefn
+
+@deftypefn {Function} {float} core.math.sqrt (float x)
+@deftypefnx {Function} {double} core.math.sqrt (double x)
+@deftypefnx {Function} {real} core.math.sqrt (real x)
+
+Compute the sqrt of @var{x}.
+
+This intrinsic is the same as the GCC built-in function @code{__builtin_sqrt}.
+@end deftypefn
+
+@deftypefn {Template} {T} core.math.toPrec (T)(float f)
+@deftypefnx {Template} {T} core.math.toPrec (T)(double f)
+@deftypefnx {Template} {T} core.math.toPrec (T)(real f)
+
+Round @var{f} to a specific precision.
+
+In floating-point operations, D language types specify only a minimum
+precision, not a maximum. The @code{toPrec} function forces rounding of the
+argument @var{f} to the precision of the specified floating point type
+@code{T}. The rounding mode used is inevitably target-dependent, but will be
+done in a way to maximize accuracy. In most cases, the default is
+round-to-nearest.
+@end deftypefn
+
+@c --------------------------------------------------------
+
+@node Variadic Intrinsics
+@subsection Variadic Intrinsics
+@cindex intrinsics, stdarg
+
+The following functions are a collection of variadic intrinsics, available by
+importing the @code{core.stdc.stdarg} module.
+
+@deftypefn {Template} {void} core.stdc.stdarg.va_arg (T)(ref va_list ap, ref T parmn)
+
+Retrieve and store in @var{parmn} the next value from the @code{va_list}
+@var{ap} that is of type @code{T}.
+
+This intrinsic is equivalent to writing the following:
+@smallexample
+parmn = __builtin_va_arg (ap, T);
+@end smallexample
+@end deftypefn
+
+@deftypefn {Template} {T} core.stdc.stdarg.va_arg (T)(ref va_list ap)
+
+Retrieve and return the next value from the @code{va_list} @var{ap} that is of
+type @code{T}.
+
+This intrinsic is equivalent to writing the following:
+@smallexample
+result = __builtin_va_arg (ap, T);
+@end smallexample
+@end deftypefn
+
+@deftypefn {Function} {void} core.stdc.stdarg.va_copy (out va_list dest, va_list src)
+
+Make a copy of @var{src} in its current state and store to @var{dest}.
+
+This intrinsic is the same as the GCC built-in function @code{__builtin_va_copy}.
+@end deftypefn
+
+@deftypefn {Function} {void} core.stdc.stdarg.va_end (va_list ap)
+
+Destroy @var{ap} so that it is no longer useable.
+
+This intrinsic is the same as the GCC built-in function @code{__builtin_va_end}.
+@end deftypefn
+
+@deftypefn {Template} {void} core.stdc.stdarg.va_start (T)(out va_list ap, ref T parmn)
+
+Initialize @var{ap} so that it can be used to access the variable arguments
+that follow the named argument @var{parmn}.
+
+This intrinsic is the same as the GCC built-in function @code{__builtin_va_start}.
+@end deftypefn
+
+@c --------------------------------------------------------
+
+@node Volatile Intrinsics
+@subsection Volatile Intrinsics
+@cindex intrinsics, volatile
+
+The following functions are a collection of intrinsics for volatile operations,
+available by importing the @code{core.volatile} module.
+
+Calls to them are guaranteed to not be removed (as dead assignment elimination
+or presumed to have no effect) or reordered in the same thread.
+
+These reordering guarantees are only made with regards to other operations done
+through these functions; the compiler is free to reorder regular loads/stores
+with regards to loads/stores done through these functions.
+
+This is useful when dealing with memory-mapped I/O (MMIO) where a store can
+have an effect other than just writing a value, or where sequential loads with
+no intervening stores can retrieve different values from the same location due
+to external stores to the location.
+
+These functions will, when possible, do the load/store as a single operation.
+In general, this is possible when the size of the operation is less than or
+equal to @code{(void*).sizeof}, although some targets may support larger
+operations. If the load/store cannot be done as a single operation, multiple
+smaller operations will be used.
+
+These are not to be conflated with atomic operations. They do not guarantee
+any atomicity. This may be provided by coincidence as a result of the
+instructions used on the target, but this should not be relied on for portable
+programs. Further, no memory fences are implied by these functions. They
+should not be used for communication between threads. They may be used to
+guarantee a write or read cycle occurs at a specified address.
+
+@deftypefn {Function} {ubyte} core.volatile.volatileLoad (ubyte* ptr)
+@deftypefnx {Function} {ushort} core.volatile.volatileLoad (ushort* ptr)
+@deftypefnx {Function} {uint} core.volatile.volatileLoad (uint* ptr)
+@deftypefnx {Function} {ulong} core.volatile.volatileLoad (ulong* ptr)
+
+Read value from the memory location indicated by @var{ptr}.
+@end deftypefn
+
+@deftypefn {Function} {ubyte} core.volatile.volatileStore (ubyte* ptr, ubyte value)
+@deftypefnx {Function} {ushort} core.volatile.volatileStore (ushort* ptr, ushort value)
+@deftypefnx {Function} {uint} core.volatile.volatileStore (uint* ptr, uint value)
+@deftypefnx {Function} {ulong} core.volatile.volatileStore (ulong* ptr, ulong value)
+
+Write @var{value} to the memory location indicated by @var{ptr}.
+@end deftypefn
+
+@c --------------------------------------------------------
+
+@node CTFE Intrinsics
+@subsection CTFE Intrinsics
+@cindex intrinsics, ctfe
+
+The following functions are only treated as intrinsics during compile-time
+function execution (CTFE) phase of compilation to allow more functions to be
+computable at compile-time, either because their generic implementations are
+too complex, or do some low-level bit manipulation of floating point types.
+
+Calls to these functions that exist after CTFE has finished will get standard
+code-generation without any special compiler intrinsic suppport.
+
+@deftypefn {Function} {float} std.math.exponential.exp (float x)
+@deftypefnx {Function} {double} std.math.exponential.exp (double x)
+@deftypefnx {Function} {real} std.math.exponential.exp (real x)
+
+Calculates @math{e^x}.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_exp}.
+@end deftypefn
+
+@deftypefn {Function} {float} std.math.exponential.expm1 (float x)
+@deftypefnx {Function} {double} std.math.exponential.expm1 (double x)
+@deftypefnx {Function} {real} std.math.exponential.expm1 (real x)
+
+Calculates @math{e^x-1.0}.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_expm1}.
+@end deftypefn
+
+@deftypefn {Function} {float} std.math.exponential.exp2 (float x)
+@deftypefnx {Function} {double} std.math.exponential.exp2 (double x)
+@deftypefnx {Function} {real} std.math.exponential.exp2 (real x)
+
+Calculates @math{2^x}.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_exp2}.
+@end deftypefn
+
+@deftypefn {Function} {float} std.math.exponential.log (float x)
+@deftypefnx {Function} {double} std.math.exponential.log (double x)
+@deftypefnx {Function} {real} std.math.exponential.log (real x)
+
+Calculate the natural logarithm of @var{x}.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_log}.
+@end deftypefn
+
+@deftypefn {Function} {float} std.math.exponential.log10 (float x)
+@deftypefnx {Function} {double} std.math.exponential.log10 (double x)
+@deftypefnx {Function} {real} std.math.exponential.log10 (real x)
+
+Calculates the base-10 logarithm of @var{x}.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_log10}.
+@end deftypefn
+
+@deftypefn {Function} {float} std.math.exponential.log2 (float x)
+@deftypefnx {Function} {double} std.math.exponential.log2 (double x)
+@deftypefnx {Function} {real} std.math.exponential.log2 (real x)
+
+Calculates the base-2 logarithm of @var{x}.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_log2}.
+@end deftypefn
+
+@deftypefn {Template} {Largest!(F, G)} std.math.exponential.pow (F, G) (F x, G y)
+@deftypefnx {Template} {real} std.math.exponential.pow (I, F)(I x, F y)
+
+Calculates @math{x^y}, where @var{y} is a float.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_pow}.
+@end deftypefn
+
+@deftypefn {Template} {F} std.math.exponential.pow (F, G) (F x, G n)
+
+Calculates @math{x^n}, where @var{n} is an integer.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_powi}.
+@end deftypefn
+
+@deftypefn {Function} {real} std.math.operations.fma (real x, real y, real z)
+
+Returns @code{(x * y) + z}, rounding only once according to the current
+rounding mode.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_fma}.
+@end deftypefn
+
+@deftypefn {Template} {F} std.math.operations.fmax (F)(const F x, const F y)
+
+Returns the larger of @var{x} and @var{y}.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_fmax}.
+@end deftypefn
+
+@deftypefn {Template} {F} std.math.operations.fmin (F)(const F x, const F y)
+
+Returns the smaller of @var{x} and @var{y}.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_fmin}.
+@end deftypefn
+
+@deftypefn {Function} {float} std.math.rounding.ceil (float x)
+@deftypefnx {Function} {double} std.math.rounding.ceil (double x)
+@deftypefnx {Function} {real} std.math.rounding.ceil (real x)
+
+Returns the value of @var{x} rounded upward to the next integer (toward
+positive infinity).
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_ceil}.
+@end deftypefn
+
+@deftypefn {Function} {float} std.math.rounding.floor (float x)
+@deftypefnx {Function} {double} std.math.rounding.floor (double x)
+@deftypefnx {Function} {real} std.math.rounding.floor (real x)
+
+Returns the value of @var{x} rounded downward to the next integer (toward
+negative infinity).
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_floor}.
+@end deftypefn
+
+@deftypefn {Function} {real} std.math.rounding.round (real x)
+
+Return the value of @var{x} rounded to the nearest integer. If the fractional
+part of @var{x} is exactly 0.5, the return value is rounded away from zero.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_round}.
+@end deftypefn
+
+@deftypefn {Function} {real} std.math.rounding.trunc (real x)
+
+Returns the integer portion of @var{x}, dropping the fractional portion.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_trunc}.
+@end deftypefn
+
+@deftypefn {Template} {R} std.math.traits.copysign (R, X)(R to, X from)
+
+Returns a value composed of @var{to} with @var{from}'s sign bit.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_copysign}.
+@end deftypefn
+
+@deftypefn {Template} {bool} std.math.traits.isFinite (X)(X x)
+
+Returns true if @var{x} is finite.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_isfinite}.
+@end deftypefn
+
+@deftypefn {Template} {bool} std.math.traits.isInfinity (X)(X x)
+
+Returns true if @var{x} is infinite.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_isinf}.
+@end deftypefn
+
+@deftypefn {Template} {bool} std.math.traits.isNaN (X)(X x)
+
+Returns true if @var{x} is NaN.
+
+This function is evaluated during CTFE as the GCC built-in function
+@code{__builtin_isnan}.
+@end deftypefn
+
+@deftypefn {Function} {float} std.math.trigoometry.tan (float x)
+@deftypefnx {Function} {double} std.math.trigoometry.tan (double x)
+@deftypefnx {Function} {real} std.math.trigonometry.tan (real x)
+
+Returns tangent of @var{x}, where @var{x} is in radians.
+
+This intrinsic is the same as the GCC built-in function @code{__builtin_tan}.
+@end deftypefn
+
+
+@c --------------------------------------------------------
+
+@node Predefined Pragmas
+@section Predefined Pragmas
+@cindex predefined pragmas
+@cindex @code{pragma}
+
+The @code{@w{pragma}} operator is used as a way to pass special information to the
+implementation and allow the addition of vendor specific extensions. The
+standard predefined pragmas are documented by the D language specification
+hosted at @uref{https://dlang.org/spec/pragma.html#predefined-pragmas}. A D
+compiler must recognize, but is free to ignore any pragma in this list.
+
+Where a pragma is ignored, the GNU D compiler will emit a warning when the
+@option{-Wunknown-pragmas} option is seen on the command-line.
+
+@table @code
+@item pragma(crt_constructor)
+@code{pragma(crt_constructor)} annotates a function so it is run after the C
+runtime library is initialized and before the D runtime library is initialized.
+Functions with this pragma must return @code{void}.
+@smallexample
+pragma(crt_constructor) void init() @{ @}
+@end smallexample
+
+@item pragma(crt_destructor)
+@code{pragma(crt_destructor)} annotates a function so it is run after the D
+runtime library is terminated and before the C runtime library is terminated.
+Calling @code{exit} function also causes the annotated functions to run.
+Functions with this pragma must return @code{void}.
+@smallexample
+pragma(crt_destructor) void init() @{ @}
+@end smallexample
+
+@item pragma(inline)
+@itemx pragma(inline, false)
+@itemx pragma(inline, true)
+@code{pragma(inline)} affects whether functions are declared inlined or not.
+The pragma takes two forms. In the first form, inlining is controlled by the
+command-line options for inlining.
+
+Functions annotated with @code{pragma(inline, false)} are marked uninlinable.
+Functions annotated with @code{pragma(inline, true)} are always inlined.
+
+@item pragma(lib)
+This pragma is accepted, but has no effect.
+@smallexample
+pragma(lib, "advapi32");
+@end smallexample
+
+@item pragma(linkerDirective)
+This pragma is accepted, but has no effect.
+@smallexample
+pragma(linkerDirective, "/FAILIFMISMATCH:_ITERATOR_DEBUG_LEVEL=2");
+@end smallexample
+
+@item pragma(mangle)
+@code{pragma(mangle, "symbol_name")} overrides the default mangling for a
+function or variable symbol. The symbol name can be any expression that must
+evaluate at compile time to a string literal. This enables linking to a symbol
+which is a D keyword, since an identifier cannot be a keyword.
+
+Targets are free to apply a prefix to the user label of the symbol name in
+assembly. For example, on @code{x86_64-apple-darwin}, @samp{symbol_name} would
+produce @samp{_symbol_name}. If the mangle string begins with @samp{*}, then
+@code{pragma(mangle)} will output the rest of the string unchanged.
+
+@smallexample
+pragma(mangle, "body")
+extern(C) void body_func();
+
+pragma(mangle, "function")
+extern(C++) struct _function @{@}
+@end smallexample
+
+@item pragma(msg)
+@code{pragma(msg, "message")} causes the compiler to print an informational
+message with the text @samp{message}. The pragma accepts multiple arguments,
+each to which is evaluated at compile time and then all are combined into one
+concatenated message.
+@smallexample
+pragma(msg, "compiling...", 6, 1.0); // prints "compiling...61.0"
+@end smallexample
+
+@item pragma(printf)
+@itemx pragma(scanf)
+
+@code{pragma(printf)} and @code{pragma(scanf)} specifies that a function
+declaration with @code{printf} or @code{scanf} style arguments that should be
+type-checked against a format string.
+
+A printf-like or scanf-like function can either be an @code{extern(C)} or
+@code{extern(C++)} function with a @var{format} parameter accepting a pointer
+to a 0-terminated @code{char} string, immediately followed by either a
+@code{...} variadic argument list or a parameter of type @code{va_list} as the
+last parameter.
+
+@smallexample
+extern(C):
+pragma(printf)
+int printf(scope const char* format, scope const ...);
+
+pragma(scanf)
+int vscanf(scope const char* format, va_list arg);
+@end smallexample
+
+@item pragma(startaddress)
+This pragma is accepted, but has no effect.
+@smallexample
+void foo() @{ @}
+pragma(startaddress, foo);
+@end smallexample
+
+@end table
+
+
+@c --------------------------------------------------------
+
+@node Predefined Versions
+@section Predefined Versions
+@cindex predefined versions
+@cindex @code{version}
+
+Several conditional version identifiers are predefined; you use them without
+supplying their definitions. They fall into three classes: standard, common,
+and target-specific.
+
+Predefined version identifiers from this list cannot be set from the command
+line or from version statements. This prevents things like both @code{Windows}
+and @code{linux} being simultaneously set.
+
+@menu
+* Standard Predefined Versions::
+* Common Predefined Versions::
+* Target Predefined Versions::
+@end menu
+
+@c --------------------------------------------------------
+
+@node Standard Predefined Versions
+@subsection Standard Predefined Versions
+@cindex standard predefined versions
+
+The standard predefined versions are documented by the D language specification
+hosted at @uref{https://dlang.org/spec/version.html#predefined-versions}.
+
+@table @code
+@item all
+@itemx none
+Version @code{none} is never defined; used to just disable a section of code.
+Version @code{all} is always defined; used as the opposite of @code{none}.
+
+@item BigEndian
+@itemx LittleEndian
+These versions reflect the byte order of multi-byte data in memory.
+@code{LittleEndian} is set when the least significant byte is first.
+@code{BigEndian} is set when the most significant byte is first.
+
+@item CRuntime_Bionic
+@itemx CRuntime_Glibc
+@itemx CRuntime_Microsoft
+@itemx CRuntime_Musl
+@itemx CRuntime_Newlib
+@itemx CRuntime_UClibc
+
+These versions reflect which standard C library is being linked in.
+@code{CRuntime_Bionic} is set when Bionic is the default C library.
+@code{CRuntime_Glibc} is set when GLIBC is the default C library.
+@code{CRuntime_Microsoft} is set when MSVCRT is the default C library.
+@code{CRuntime_Musl} is set when musl is the default C library.
+@code{CRuntime_Newlib} is set when Newlib is the default C library.
+@code{CRuntime_UClibc} is set when uClibc is the default C library.
+
+@item CppRuntime_Gcc
+This version is defined when the standard C++ library being linked in is @file{libstdc++}.
+
+@item D_BetterC
+This version is defined when the standard D libraries are not being implicitly
+linked in. This also implies that features of the D language that rely on
+exceptions, module information, or run-time type information are disabled as
+well. Enabled by @option{-fno-druntime}.
+
+@item D_Coverage
+This version is defined when code coverage analysis instrumentation is being
+generated. Enabled by @option{-ftest-coverage}.
+
+@item D_Ddoc
+This version is defined when Ddoc documentation is being generated. Enabled by
+@option{-fdoc}.
+
+@item D_Exceptions
+This version is defined when exception handling is supported. Disabled by
+@option{-fno-exceptions}.
+
+@item D_HardFloat
+@itemx D_SoftFloat
+These versions reflect the floating-point ABI in use by the target.
+@code{D_HardFloat} is set when the target hardware has a floating-point unit.
+@code{D_SoftFloat} is set when the target hardware does not have a
+floating-point unit.
+
+@item D_Invariants
+This version is defined when checks are being emitted for class invariants and
+struct invariants. Enabled by @option{-finvariants}.
+
+@item D_LP64
+This version is defined when pointers are 64-bits. Not to be confused with
+with C's @code{__LP64__} model.
+
+@item D_ModuleInfo
+This version is defined when run-time module information (also known as
+@code{ModuleInfo}) is supported. Disabled by @option{-fno-moduleinfo}.
+
+@item D_NoBoundsChecks
+This version is defined when array bounds checks are disabled. Enabled by
+@option{-fno-bounds-checks}.
+
+@item D_Optimized
+This version is defined in all optimizing compilations.
+
+@item D_PIC
+This version is defined when position-independent code is being generated.
+Enabled by @option{-fPIC}.
+
+@item D_PIE
+This version is defined when position-independent code that can be only linked
+into executables is being generated. Enabled by @option{-fPIE}.
+
+@item D_PreConditions
+This version is defined when checks are being emitted for @code{in} contracts.
+Disabled by @option{-fno-preconditions}.
+
+@item D_PostConditions
+This version is defined when checks are being emitted for @code{out} contracts.
+Disabled by @option{-fno-postconditions}.
+
+@item D_TypeInfo
+This version is defined when run-time type information (also known as
+@code{TypeInfo}) is supported. Disabled by @option{-fno-rtti}.
+
+@item D_Version2
+This version defined when this is a D version 2 compiler.
+
+@item unittest
+This version is defined when the @code{unittest} code is being compiled in.
+Enabled by @option{-funittest}.
+
+@end table
+
+@c --------------------------------------------------------
+
+@node Common Predefined Versions
+@subsection Common Predefined Versions
+@cindex common predefined versions
+
+The common predefined macros are GNU D extensions. They are available
+with the same meanings regardless of the machine or operating system on
+which you are using GNU D. Their names all start with @code{GNU}.
+
+@table @code
+
+@item GNU
+This version is defined by the GNU D compiler. If all you need to know is
+whether or not your D program is being compiled by GDC, or a non-GDC compiler,
+you can simply test @code{version(GNU)}.
+
+@item GNU_DWARF2_Exceptions
+@itemx GNU_SEH_Exceptions
+@itemx GNU_SjLj_Exceptions
+These versions reflect the mechanism that will be used for exception handling
+by the target. @code{GNU_DWARF2_Exceptions} is defined when the target uses
+DWARF 2 exceptions. @code{GNU_SEH_Exceptions} is defined when the target uses
+SEH exceptions. @code{GNU_SjLj_Exceptions} is defined when the target uses the
+@code{setjmp}/@code{longjmp}-based exception handling scheme.
+
+@item GNU_EMUTLS
+This version is defined if the target does not support thread-local storage,
+and an emulation layer is used instead.
+
+@item GNU_InlineAsm
+This version is defined when @code{asm} statements use GNU D style syntax.
+(@pxref{Inline Assembly})
+
+@item GNU_StackGrowsDown
+This version is defined if pushing a word onto the stack moves the stack
+pointer to a smaller address, and is undefined otherwise.
+
+@end table
+
+@c --------------------------------------------------------
+
+@node Target Predefined Versions
+@subsection Target-specific Predefined Versions
+@cindex target-specific predefined versions
+
+The D compiler normally predefines several versions that indicate what type of
+system and machine is in use. They are obviously different on each target
+supported by GCC.
+
+@table @code
+@item AArch64
+Version relating to the AArch64 family of processors.
+
+@item Android
+Version relating to the Android platform.
+
+@item ARM
+@itemx ARM_HardFloat
+@itemx ARM_SoftFloat
+@itemx ARM_SoftFP
+@itemx ARM_Thumb
+Versions relating to the ARM family of processors.
+
+@item Cygwin
+Version relating to the Cygwin environment.
+
+@item darwin
+Deprecated; use @code{OSX} instead.
+
+@item DragonFlyBSD
+Versions relating to DragonFlyBSD systems.
+
+@item FreeBSD
+@item FreeBSD_9
+@item FreeBSD_10
+@item FreeBSD_11
+@item FreeBSD_...
+Versions relating to FreeBSD systems. The FreeBSD major version number is
+inferred from the target triplet.
+
+@item HPPA
+@itemx HPPA64
+Versions relating to the HPPA family of processors.
+
+@item Hurd
+Version relating to GNU Hurd systems.
+
+@item linux
+Version relating to Linux systems.
+
+@item MinGW
+Version relating to the MinGW environment.
+
+@item MIPS32
+@itemx MIPS64
+@itemx MIPS_EABI
+@itemx MIPS_HardFloat
+@itemx MIPS_N32
+@itemx MIPS_N64
+@itemx MIPS_O32
+@itemx MIPS_O64
+@itemx MIPS_SoftFloat
+Versions relating to the MIPS family of processors.
+
+@item NetBSD
+Version relating to NetBSD systems.
+
+@item OpenBSD
+Version relating to OpenBSD systems.
+
+@item OSX
+Version relating to OSX systems.
+
+@item Posix
+Version relating to POSIX systems (includes Linux, FreeBSD, OSX, Solaris, etc).
+
+@item PPC
+@itemx PPC64
+@itemx PPC_HardFloat
+@itemx PPC_SoftFloat
+Versions relating to the PowerPC family of processors.
+
+@item RISCV32
+@itemx RISCV64
+Versions relating to the RISC-V family of processors.
+
+@item S390
+@itemx SystemZ
+Versions relating to the S/390 and System Z family of processors.
+
+@item S390X
+Deprecated; use @code{SystemZ} instead.
+
+@item Solaris
+Versions relating to Solaris systems.
+
+@item SPARC
+@itemx SPARC64
+@itemx SPARC_HardFloat
+@itemx SPARC_SoftFloat
+@itemx SPARC_V8Plus
+Versions relating to the SPARC family of processors.
+
+@item Thumb
+Deprecated; use @code{ARM_Thumb} instead.
+
+@item D_X32
+@itemx X86
+@itemx X86_64
+Versions relating to the x86-32 and x86-64 family of processors.
+
+@item Windows
+@itemx Win32
+@itemx Win64
+Versions relating to Microsoft Windows systems.
+
+@end table
+
+
+@c --------------------------------------------------------
+
+@node Special Enums
+@section Special Enums
+@cindex special enums
+
+Special @code{enum} names are used to represent types that do not have an
+equivalent basic D type. For example, C++ types used by the C++ name mangler.
+
+Special enums are declared opaque, with a base type explicitly set. Unlike
+regular opaque enums, special enums can be used as any other value type. They
+have a default @code{.init} value, as well as other enum properties available
+(@code{.min}, @code{.max}). Special enums can be declared in any module, and
+will be recognized by the compiler.
+
+@smallexample
+import gcc.builtins;
+enum __c_long : __builtin_clong;
+__c_long var = 0x800A;
+@end smallexample
+
+@noindent
+The following identifiers are recognized by GNU D.
+
+@table @code
+@item __c_complex_double
+C @code{_Complex double} type.
+@item __c_complex_float
+C @code{_Complex float} type.
+@item __c_complex_real
+C @code{_Complex long double} type.
+@item __c_long
+C++ @code{long} type.
+@item __c_longlong
+C++ @code{long long} type.
+@item __c_long_double
+C @code{long double} type.
+@item __c_ulong
+C++ @code{unsigned long} type.
+@item __c_ulonglong
+C++ @code{unsigned long long} type.
+@item __c_wchar_t
+C++ @code{wchar_t} type.
+@end table
+
+The @code{core.stdc.config} module declares the following shorthand alias types
+for convenience: @code{c_complex_double}, @code{c_complex_float},
+@code{c_complex_real}, @code{cpp_long}, @code{cpp_longlong},
+@code{c_long_double}, @code{cpp_ulong}, @code{cpp_ulonglong}.
+
+
+@c --------------------------------------------------------
+
+@node Traits
+@section Traits
+@cindex traits
+
+Traits are extensions to the D programming language to enable programs, at
+compile time, to get at information internal to the compiler. This is also
+known as compile time reflection.
+
+GNU D implements a @code{__traits(getTargetInfo)} trait that receives a string
+key as its argument. The result is an expression describing the requested
+target information.
+
+@smallexample
+version (OSX)
+@{
+ static assert(__traits(getTargetInfo, "objectFormat") == "macho");
+@}
+@end smallexample
+
+@noindent
+Keys for the trait are implementation defined, allowing target-specific data
+for exotic targets. A reliable subset exists which a D compiler must
+recognize. These are documented by the D language specification hosted at
+@uref{https://dlang.org/spec/traits.html#getTargetInfo}.
+
+The following keys are recognized by GNU D.
+
+@table @code
+@item cppRuntimeLibrary
+The C++ runtime library affinity for this toolchain.
+
+@item cppStd
+The version of the C++ standard supported by @code{extern(C++)} code,
+equivalent to the @code{__cplusplus} macro in a C++ compiler.
+
+@item floatAbi
+Floating point ABI; may be @samp{hard}, @samp{soft}, or @samp{softfp}.
+
+@item objectFormat
+Target object format.
+
+@end table
+
+
+@c --------------------------------------------------------
+
+@node Vector Extensions
+@section Vector Extensions
+@cindex vector extensions
+@cindex simd
+
+CPUs often support specialized vector types and vector operations (aka media
+instructions). Vector types are a fixed array of floating or integer types,
+and vector operations operate simultaneously on them.
+
+@smallexample
+alias int4 = __vector(int[4]);
+@end smallexample
+
+@noindent
+All the basic integer types can be used as base types, both as signed and as
+unsigned: @code{byte}, @code{short}, @code{int}, @code{long}. In addition,
+@code{float} and @code{double} can be used to build floating-point vector
+types, and @code{void} to build vectors of untyped data. Only sizes that are
+positive power-of-two multiples of the base type size are currently allowed.
+
+@noindent
+The @code{core.simd} module has the following shorthand aliases for commonly
+supported vector types:
+@code{byte8}, @code{byte16}, @code{byte32}, @code{byte64},
+@code{double1}, @code{double2}, @code{double4}, @code{double8},
+@code{float2}, @code{float4}, @code{float8}, @code{float16},
+@code{int2}, @code{int4}, @code{int8}, @code{int16},
+@code{long1}, @code{long2}, @code{long4}, @code{long8},
+@code{short4}, @code{short8}, @code{short16}, @code{short32},
+@code{ubyte8}, @code{ubyte16}, @code{ubyte32}, @code{ubyte64},
+@code{uint2}, @code{uint4}, @code{uint8}, @code{uint16},
+@code{ulong1}, @code{ulong2}, @code{ulong4}, @code{ulong8},
+@code{ushort4}, @code{ushort8}, @code{ushort16}, @code{ushort32},
+@code{void8}, @code{void16}, @code{void32}, @code{void64}.
+All these aliases correspond to @code{__vector(type[N])}.
+
+Which vector types are supported depends on the target. Only vector types that
+are implemented for the current architecture are supported at compile-time.
+Vector operations that are not supported in hardware cause GNU D to synthesize
+the instructions using a narrower mode.
+
+@smallexample
+alias v4i = __vector(int[4]);
+alias v128f = __vector(float[128]); // Error: not supported on this platform
+
+int4 a, b, c;
+
+c = a * b; // Natively supported on x86 with SSE4
+c = a / b; // Always synthesized
+@end smallexample
+
+@noindent
+Vector types can be used with a subset of normal D operations. Currently, GNU
+D allows using the following operators on these types: @code{+, -, *, /,
+unary+, unary-}@.
+
+@smallexample
+alias int4 = __vector(int[4]);
+
+int4 a, b, c;
+
+c = a + b;
+@end smallexample
+
+@noindent
+It is also possible to use shifting operators @code{<<}, @code{>>}, the modulus
+operator @code{%}, logical operations @code{&, |, ^}, and the complement
+operator @code{unary~} on integer-type vectors.
+
+For convenience, it is allowed to use a binary vector operation where one
+operand is a scalar. In that case the compiler transforms the scalar operand
+into a vector where each element is the scalar from the operation. The
+transformation happens only if the scalar could be safely converted to the
+vector-element type. Consider the following code.
+
+@smallexample
+alias int4 = __vector(int[4]);
+
+int4 a, b;
+long l;
+
+a = b + 1; // a = b + [1,1,1,1];
+a = 2 * b; // a = [2,2,2,2] * b;
+
+a = l + a; // Error, incompatible types.
+@end smallexample
+
+@noindent
+Vector comparison is supported with standard comparison operators:
+@code{==, !=, <, <=, >, >=}. Comparison operands can be vector expressions of
+integer-type or real-type. Comparison between integer-type vectors and
+real-type vectors are not supported. The result of the comparison is a vector
+of the same width and number of elements as the comparison operands with a
+signed integral element type.
+
+Vectors are compared element-wise producing 0 when comparison is false
+and -1 (constant of the appropriate type where all bits are set)
+otherwise. Consider the following example.
+
+@smallexample
+alias int4 = __vector(int[4]);
+
+int4 a = [1,2,3,4];
+int4 b = [3,2,1,4];
+int4 c;
+
+c = a > b; // The result would be [0, 0,-1, 0]
+c = a == b; // The result would be [0,-1, 0,-1]
+@end smallexample
+
+
+@c --------------------------------------------------------
+
+@node Vector Intrinsics
+@section Vector Intrinsics
+@cindex intrinsics, vector
+
+The following functions are a collection of vector operation intrinsics,
+available by importing the @code{gcc.simd} module.
+
+@deftypefn {Template} {void} gcc.simd.prefetch (bool @var{rw}, @
+ ubyte @var{locality}) @
+ (const(void)* @var{addr})
+
+Emit the prefetch instruction. The value of @var{addr} is the address of the
+memory to prefetch. The value of @var{rw} is a compile-time constant one or
+zero; one means that the prefetch is preparing for a write to the memory
+address and zero, the default, means that the prefetch is preparing for a read.
+The value @var{locality} must be a compile-time constant integer between zero
+and three.
+
+This intrinsic is the same as the GCC built-in function
+@code{__builtin_prefetch}.
+
+@smallexample
+for (i = 0; i < n; i++)
+@{
+ import gcc.simd : prefetch;
+ a[i] = a[i] + b[i];
+ prefetch!(true, 1)(&a[i+j]);
+ prefetch!(false, 1)(&b[i+j]);
+ // @r{@dots{}}
+@}
+@end smallexample
+@end deftypefn
+
+@deftypefn {Template} {V} gcc.simd.loadUnaligned (V)(const V* @var{p})
+
+Load unaligned vector from the address @var{p}.
+
+@smallexample
+float4 v;
+ubyte[16] arr;
+
+v = loadUnaligned(cast(float4*)arr.ptr);
+@end smallexample
+@end deftypefn
+
+@deftypefn {Template} {V} gcc.simd.storeUnaligned (V)(V* @var{p}, V @var{value})
+
+Store vector @var{value} to unaligned address @var{p}.
+
+@smallexample
+float4 v;
+ubyte[16] arr;
+
+storeUnaligned(cast(float4*)arr.ptr, v);
+@end smallexample
+@end deftypefn
+
+@deftypefn {Template} {V0} gcc.simd.shuffle (V0, V1, M)(V0 @var{op1}, @
+ V1 @var{op2}, @
+ M @var{mask})
+@deftypefnx {Template} {V} gcc.simd.shuffle (V, M)(V @var{op1}, M @var{mask})
+
+Construct a permutation of elements from one or two vectors, returning a vector
+of the same type as the input vector(s). The @var{mask} is an integral vector
+with the same width and element count as the output vector.
+
+This intrinsic is the same as the GCC built-in function
+@code{__builtin_shuffle}.
+
+@smallexample
+int4 a = [1, 2, 3, 4];
+int4 b = [5, 6, 7, 8];
+int4 mask1 = [0, 1, 1, 3];
+int4 mask2 = [0, 4, 2, 5];
+int4 res;
+
+res = shuffle(a, mask1); // res is [1,2,2,4]
+res = shuffle(a, b, mask2); // res is [1,5,3,6]
+@end smallexample
+@end deftypefn
+
+@deftypefn {Template} {V} gcc.simd.shufflevector (V1, V2, M...)(V1 @var{op1}, @
+ V2 @var{op2}, M @var{mask})
+@deftypefnx {Template} {V} gcc.simd.shufflevector (V, @var{mask}...)(V @
+ @var{op1}, V @var{op2})
+
+Construct a permutation of elements from two vectors, returning a vector with
+the same element type as the input vector(s), and same length as the
+@var{mask}.
+
+This intrinsic is the same as the GCC built-in function
+@code{__builtin_shufflevector}.
+
+@smallexample
+int8 a = [1, -2, 3, -4, 5, -6, 7, -8];
+int4 b = shufflevector(a, a, 0, 2, 4, 6); // b is [1,3,5,7]
+int4 c = [-2, -4, -6, -8];
+int8 d = shufflevector!(int8, 4, 0, 5, 1, 6, 2, 7, 3)(c, b); // d is a
+@end smallexample
+@end deftypefn
+
+@deftypefn {Template} {E} gcc.simd.extractelement (V, int idx)(V @var{val})
+Extracts a single scalar element from a vector @var{val} at a specified index
+@var{idx}.
+
+@smallexample
+int4 a = [0, 10, 20, 30];
+int k = extractelement!(int4, 2)(a); // a is 20
+@end smallexample
+@end deftypefn
+
+@deftypefn {Template} {V} gcc.simd.insertelement (V, int idx)(V val, B @var{e})
+Inserts a scalar element @var{e} into a vector @var{val} at a specified index
+@var{idx}.
+
+@smallexample
+int4 a = [0, 10, 20, 30];
+int4 b = insertelement!(int4, 2)(a, 50); // b is [0,10,50,30]
+@end smallexample
+@end deftypefn
+
+@deftypefn {Template} {V} gcc.simd.convertvector (V, T)(T val)
+Convert a vector @var{val} from one integral or floating vector type to
+another. The result is an integral or floating vector that has had every
+element cast to the element type of the return type.
+
+This intrinsic is the same as the GCC built-in function
+@code{__builtin_convertvector}.
+
+@smallexample
+int4 a = [1, -2, 3, -4];
+float4 b = [1.5, -2.5, 3, 7];
+float4 c = convertvector!float4(a); // c is [1,-2,3,-4]
+double4 d = convertvector!double4(a); // d is [1,-2,3,-4]
+double4 e = convertvector!double4(b); // e is [1.5,-2.5,3,7]
+int4 f = convertvector!int4(b); // f is [1,-2,3,7]
+@end smallexample
+@end deftypefn
+
+@deftypefn {Template} {V0} gcc.simd.blendvector (V0, V1, M)(V0 @var{op0}, @
+ V1 @var{op1}, @
+ M @var{mask})
+
+Construct a conditional merge of elements from two vectors, returning a vector
+of the same type as the input vector(s). The @var{mask} is an integral vector
+with the same width and element count as the output vector.
+
+@smallexample
+int4 a = [1, 2, 3, 4];
+int4 b = [3, 2, 1, 4];
+auto c = blendvector(a, b, a > b); // c is [3,2,3,4]
+auto d = blendvector(a, b, a < b); // d is [1,2,1,4]
+@end smallexample
+@end deftypefn
+
+
+@c --------------------------------------------------------
+
+@node Missing Features
+@section Missing Features and Deviations
+@cindex missing features
+@cindex D spec deviations
+
+Some parts of the D specification are hard or impossible to implement with
+GCC, they should be listed here.
+
+@table @asis
+@item Bit Operation Intrinsics
+The Digital Mars D compiler implements the @code{core.bitop} intrinsics
+@code{inp}, @code{inpw}, @code{inpl}, @code{outp}, @code{outpw}, and
+@code{outpl}. These are not recognized by GNU D. On most targets, equivalent
+intrinsics that have the same effect would be @code{core.volatile.loadVolatile}
+and @code{core.volatile.storeVolatile} respectively
+(@pxref{Volatile Intrinsics}).
+
+On x86 targets, if an @code{in} or @code{out} instruction is specifically
+required, that can be achieved using assembler statements instead.
+@smallexample
+ubyte inp(uint port)
+@{
+ ubyte value;
+ asm @{ "inb %w1, %b0" : "=a" (value) : "Nd" (port); @}
+ return value;
+@}
+
+void outp(uint port, ushort value)
+@{
+ asm @{ "outb %b0, %w1" : : "a" (value), "Nd" (port); @}
+@}
+@end smallexample
+
+@item Floating-Point Intermediate Values
+
+GNU D uses a software compile-time floating-point type that assists in
+cross-compilation and support for arbitrary target @code{real} precisions wider
+than 80 bits. Because of this, the result of floating-point CTFE operations
+may have different results in GNU D compared with other D compilers that use
+the host's native floating-point type for storage and CTFE. In particular, GNU
+D won't overflow or underflow when a target real features a higher precision
+than the host. Differences also extend to @code{.stringof} representations of
+intermediate values due to formatting differences with @code{sprintf("%Lg")}.
+@smallexample
+version(GNU)
+ assert((25.5).stringof ~ (3.01).stringof == "2.55e+13.01e+0");
+else
+ assert((25.5).stringof ~ (3.01).stringof == "25.53.01");
+@end smallexample
+
+@item Function Calling Conventions
+GNU D does not implement the @code{extern(D)} calling convention for x86 as
+described in the D specification hosted at
+@uref{https://dlang.org/spec/abi.html#function_calling_conventions}.
+
+Instead, there is no distinction between @code{extern(C)} and @code{extern(D)}
+other than name mangling.
+
+@item ImportC Limitations
+GNU D does not run the preprocessor automatically for any ImportC sources.
+Instead all C files are expected to be manually preprocessed before they are
+imported into the compilation.
+
+@item Inline Assembler
+GNU D does not implement the D inline assembler for x86 and x86_64 as described
+in the D specification hosted at @uref{https://dlang.org/spec/iasm.html}. Nor
+does GNU D predefine the @code{D_InlineAsm_X86} and @code{D_InlineAsm_X86_64}
+version identifiers to indicate support.
+
+The GNU D compiler uses an alternative, GCC-based syntax for inline assembler
+(@pxref{Inline Assembly}).
+
+@item Interfacing to Objective-C
+GNU D does not support interfacing with Objective-C, nor its protocols,
+classes, subclasses, instance variables, instance methods and class methods.
+The @code{extern(Objective-C)} linkage is ignored, as are the @code{@@optional}
+and @code{@@selector} attributes. The @code{D_ObjectiveC} version identifier
+is not predefined for compilations.
+
+@item Pragma Directives
+Pragmas that are designed to embed information into object files or otherwise
+pass options to the linker are not supported by GNU D. These include
+@code{pragma(lib)}, @code{pragma(linkerDirective)}, and
+@code{pragma(startaddress)}.
+
+@item SIMD Intrinsics
+The Digital Mars D compiler implements the @code{core.simd} intrinsics
+@code{__simd}, @code{__simd_ib}, @code{__simd_sto}. These are not recognized
+by GNU D, nor does GNU D predefine the @code{D_SIMD} version identifier to
+indicate support.
+
+On x86 targets, all intrinsics are available as functions in the
+@code{gcc.builtins} module, and have predictable equivalents.
+@smallexample
+version (DigitalMars)
+@{
+ __simd(XMM.PSLLW, op1, op2);
+ __simd_ib(XMM.PSLLW, op1, imm8);
+@}
+version (GNU)
+@{
+ __builtin_ia32_psllw(op1, op2);
+ __builtin_ia32_psllwi(op1, imm8);
+@}
+@end smallexample
+
+@end table
diff --git a/gcc/d/imports.cc b/gcc/d/imports.cc
index 133d93d..2d331f4 100644
--- a/gcc/d/imports.cc
+++ b/gcc/d/imports.cc
@@ -160,6 +160,20 @@ public:
d->aliassym->accept (this);
}
+ /* Build IMPORTED_DECLs for all overloads in a set. */
+ void visit (OverloadSet *d) final override
+ {
+ vec<tree, va_gc> *tset = NULL;
+
+ vec_alloc (tset, d->a.length);
+
+ for (size_t i = 0; i < d->a.length; i++)
+ vec_safe_push (tset, build_import_decl (d->a[i]));
+
+ this->result_ = build_tree_list_vec (tset);
+ tset->truncate (0);
+ }
+
/* Function aliases are the same as alias symbols. */
void visit (FuncAliasDeclaration *d) final override
{
diff --git a/gcc/d/intrinsics.cc b/gcc/d/intrinsics.cc
index 75d4318..46380e5 100644
--- a/gcc/d/intrinsics.cc
+++ b/gcc/d/intrinsics.cc
@@ -170,10 +170,6 @@ maybe_set_intrinsic (FuncDeclaration *decl)
case INTRINSIC_SHUFFLEVECTOR:
case INTRINSIC_CONVERTVECTOR:
case INTRINSIC_BLENDVECTOR:
- case INTRINSIC_EQUALMASK:
- case INTRINSIC_NOTEQUALMASK:
- case INTRINSIC_GREATERMASK:
- case INTRINSIC_GREATEREQUALMASK:
case INTRINSIC_VLOAD8:
case INTRINSIC_VLOAD16:
case INTRINSIC_VLOAD32:
@@ -487,29 +483,6 @@ maybe_warn_intrinsic_mismatch (tree function, tree callexp)
return false;
}
-
- case INTRINSIC_EQUALMASK:
- case INTRINSIC_NOTEQUALMASK:
- case INTRINSIC_GREATERMASK:
- case INTRINSIC_GREATEREQUALMASK:
- {
- /* Expects the signature:
- vector(T) equalMask(vector(T), vector(T));
- vector(T) notEqualMask(vector(T), vector(T));
- vector(T) greaterMask(vector(T), vector(T));
- vector(T) greateOrEqualMask(vector(T), vector(T)); */
- gcc_assert (call_expr_nargs (callexp) == 2);
-
- tree vec0 = TREE_TYPE (CALL_EXPR_ARG (callexp, 0));
- tree vec1 = TREE_TYPE (CALL_EXPR_ARG (callexp, 1));
- if (!VECTOR_TYPE_P (TREE_TYPE (callexp))
- || !VECTOR_TYPE_P (vec0)
- || !VECTOR_TYPE_P (vec1)
- || TYPE_MAIN_VARIANT (vec0) != TYPE_MAIN_VARIANT (vec1))
- return warn_mismatched_return_type (callexp, "__vector(T)");
-
- return false;
- }
}
/* Generic mismatch warning if it hasn't already been handled. */
@@ -552,7 +525,7 @@ call_builtin_fn (tree callexp, built_in_function code, int n, ...)
static tree
expand_intrinsic_bsf (tree callexp)
{
- /* The bsr() intrinsic gets turned into __builtin_ctz(arg).
+ /* The bsf() intrinsic gets turned into __builtin_ctz(arg).
The return value is supposed to be undefined if arg is zero. */
tree arg = CALL_EXPR_ARG (callexp, 0);
int argsize = TYPE_PRECISION (TREE_TYPE (arg));
@@ -581,11 +554,11 @@ expand_intrinsic_bsf (tree callexp)
static tree
expand_intrinsic_bsr (tree callexp)
{
- /* The bsr() intrinsic gets turned into (size - 1) - __builtin_clz(arg).
+ /* The bsr() intrinsic gets turned into __builtin_clz(arg) ^ (size - 1).
The return value is supposed to be undefined if arg is zero. */
tree arg = CALL_EXPR_ARG (callexp, 0);
- tree type = TREE_TYPE (arg);
- int argsize = TYPE_PRECISION (type);
+ tree type = TREE_TYPE (callexp);
+ int argsize = TYPE_PRECISION (TREE_TYPE (arg));
/* Which variant of __builtin_clz* should we call? */
built_in_function code = (argsize <= INT_TYPE_SIZE) ? BUILT_IN_CLZ
@@ -597,13 +570,8 @@ expand_intrinsic_bsr (tree callexp)
tree result = call_builtin_fn (callexp, code, 1, arg);
- /* Handle int -> long conversions. */
- if (TREE_TYPE (result) != type)
- result = fold_convert (type, result);
-
- result = fold_build2 (MINUS_EXPR, type,
- build_integer_cst (argsize - 1, type), result);
- return fold_convert (TREE_TYPE (callexp), result);
+ return fold_build2 (BIT_XOR_EXPR, type, result,
+ build_integer_cst (argsize - 1, type));
}
/* Expand a front-end intrinsic call to INTRINSIC, which is either a call to
@@ -1072,32 +1040,6 @@ expand_volatile_store (tree callexp)
return modify_expr (result, value);
}
-/* Expand a front-end intrinsic call to a vector comparison intrinsic, which is
- either a call to equalMask(), notEqualMask(), greaterMask(), or
- greaterOrEqualMask(). These intrinsics take two arguments, the signature to
- which can be either:
-
- vector(T) equalMask(vector(T) vec0, vector(T) vec1);
- vector(T) notEqualMask(vector(T) vec0, vector(T) vec1);
- vector(T) greaterMask(vector(T) vec0, vector(T) vec1);
- vector(T) greaterOrEqualMask(vector(T) vec0, vector(T) vec1);
-
- This performs an element-wise comparison between two vectors VEC0 and VEC1,
- returning a vector with signed integral elements. */
-
-static tree
-expand_intrinsic_vec_cond (tree_code code, tree callexp)
-{
- tree vec0 = CALL_EXPR_ARG (callexp, 0);
- tree vec1 = CALL_EXPR_ARG (callexp, 1);
- tree type = TREE_TYPE (callexp);
-
- tree cmp = fold_build2_loc (EXPR_LOCATION (callexp), code,
- truth_type_for (type), vec0, vec1);
- return fold_build3_loc (EXPR_LOCATION (callexp), VEC_COND_EXPR, type, cmp,
- build_minus_one_cst (type), build_zero_cst (type));
-}
-
/* Expand a front-end instrinsic call to convertvector(). This takes one
argument, the signature to which is:
@@ -1488,18 +1430,6 @@ maybe_expand_intrinsic (tree callexp)
case INTRINSIC_BLENDVECTOR:
return expand_intrinsic_vec_blend (callexp);
- case INTRINSIC_EQUALMASK:
- return expand_intrinsic_vec_cond (EQ_EXPR, callexp);
-
- case INTRINSIC_NOTEQUALMASK:
- return expand_intrinsic_vec_cond (NE_EXPR, callexp);
-
- case INTRINSIC_GREATERMASK:
- return expand_intrinsic_vec_cond (GT_EXPR, callexp);
-
- case INTRINSIC_GREATEREQUALMASK:
- return expand_intrinsic_vec_cond (GE_EXPR, callexp);
-
default:
gcc_unreachable ();
}
diff --git a/gcc/d/intrinsics.def b/gcc/d/intrinsics.def
index b8d1ec5..96f9b93 100644
--- a/gcc/d/intrinsics.def
+++ b/gcc/d/intrinsics.def
@@ -266,14 +266,6 @@ DEF_D_BUILTIN (INTRINSIC_CONVERTVECTOR, BUILT_IN_NONE, "convertvector",
"gcc.simd", "F@1TZ@1V")
DEF_D_BUILTIN (INTRINSIC_BLENDVECTOR, BUILT_IN_NONE, "blendvector", "gcc.simd",
"F@2V0@2V1@1MZ@2V0")
-DEF_D_BUILTIN (INTRINSIC_EQUALMASK, BUILT_IN_NONE, "equalMask", "gcc.simd",
- "F@1V@1VZ@1V")
-DEF_D_BUILTIN (INTRINSIC_NOTEQUALMASK, BUILT_IN_NONE, "notEqualMask",
- "gcc.simd", "F@1V@1VZ@1V")
-DEF_D_BUILTIN (INTRINSIC_GREATERMASK, BUILT_IN_NONE, "greaterMask", "gcc.simd",
- "F@1V@1VZ@1V")
-DEF_D_BUILTIN (INTRINSIC_GREATEREQUALMASK, BUILT_IN_NONE,
- "greaterOrEqualMask", "gcc.simd", "F@1V@1VZ@1V")
#undef DEF_D_BUILTIN
#undef DEF_CTFE_BUILTIN
diff --git a/gcc/d/lang.opt b/gcc/d/lang.opt
index 15ab725..b039c76 100644
--- a/gcc/d/lang.opt
+++ b/gcc/d/lang.opt
@@ -422,7 +422,7 @@ Don't destruct fields of partially constructed objects.
frevert=intpromote
D RejectNegative
-Use C-style integral promotion for unary '+', '-' and '~'.
+Don't use C-style integral promotion for unary '+', '-' and '~'.
frtti
D
diff --git a/gcc/d/toir.cc b/gcc/d/toir.cc
index e5f5751..e387f27 100644
--- a/gcc/d/toir.cc
+++ b/gcc/d/toir.cc
@@ -529,6 +529,28 @@ public:
this->do_label (label);
}
+ /* Generate and set a new continue label for the current unrolled loop. */
+
+ void push_unrolled_continue_label (UnrolledLoopStatement *s)
+ {
+ this->push_continue_label (s);
+ }
+
+ /* Finish with the continue label for the unrolled loop. */
+
+ void pop_unrolled_continue_label (UnrolledLoopStatement *s)
+ {
+ Statement *stmt = s->getRelatedLabeled ();
+ d_label_entry *ent = d_function_chain->labels->get (stmt);
+ gcc_assert (ent != NULL && ent->bc_label == true);
+
+ this->pop_continue_label (TREE_VEC_ELT (ent->label, bc_continue));
+
+ /* Remove the continue label from the label htab, as a new one must be
+ inserted at the end of every unrolled loop. */
+ ent->label = TREE_VEC_ELT (ent->label, bc_break);
+ }
+
/* Visitor interfaces. */
@@ -1089,9 +1111,9 @@ public:
if (statement != NULL)
{
- tree lcontinue = this->push_continue_label (statement);
+ this->push_unrolled_continue_label (s);
this->build_stmt (statement);
- this->pop_continue_label (lcontinue);
+ this->pop_unrolled_continue_label (s);
}
}
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index 3577f66..00fa2ba 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -1064,17 +1064,6 @@ public:
: null_pointer_node;
this->layout_field (xhash);
- if (sd->xhash)
- {
- TypeFunction *tf = sd->xhash->type->toTypeFunction ();
- if (!tf->isnothrow () || tf->trust == TRUST::system)
- {
- warning (sd->xhash->loc, "toHash() must be declared as "
- "extern (D) size_t toHash() const nothrow @safe, "
- "not %s", tf->toChars ());
- }
- }
-
/* bool function(in void*, in void*) xopEquals; */
tree xeq = (sd->xeq) ? build_address (get_symbol_decl (sd->xeq))
: null_pointer_node;
@@ -1410,7 +1399,7 @@ check_typeinfo_type (const Loc &loc, Scope *sc, Expression *expr)
{
/* Even when compiling without RTTI we should still be able to evaluate
TypeInfo at compile-time, just not at run-time. */
- if (!sc || !(sc->flags & SCOPEctfe))
+ if (!sc || !(sc->flags & unsigned(SCOPE::ctfe)))
{
static int warned = 0;
diff --git a/gcc/dfp.cc b/gcc/dfp.cc
index 7c1db7d..084ceb7 100644
--- a/gcc/dfp.cc
+++ b/gcc/dfp.cc
@@ -364,6 +364,12 @@ decimal_from_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from)
/* We convert to string, then to decNumber then to decimal128. */
real_to_decimal (string, from, sizeof (string), 0, 1);
decimal_real_from_string (to, string);
+ /* When a canonical NaN is originally created, it is not marked as
+ decimal. Ensure the result of converting to another decimal type
+ (which passes through this function) is also marked as
+ canonical. */
+ if (from->cl == rvc_nan && from->canonical)
+ to->canonical = 1;
}
/* Helper function to real.cc:do_compare() to handle decimal internal
diff --git a/gcc/diagnostic-path.h b/gcc/diagnostic-path.h
index 8ce4ff7..aa5cda8 100644
--- a/gcc/diagnostic-path.h
+++ b/gcc/diagnostic-path.h
@@ -167,6 +167,9 @@ class diagnostic_path
virtual const diagnostic_event & get_event (int idx) const = 0;
bool interprocedural_p () const;
+
+private:
+ bool get_first_event_in_a_function (unsigned *out_idx) const;
};
/* Concrete subclasses. */
diff --git a/gcc/diagnostic-spec.cc b/gcc/diagnostic-spec.cc
index aece896..7a03fc4 100644
--- a/gcc/diagnostic-spec.cc
+++ b/gcc/diagnostic-spec.cc
@@ -79,7 +79,6 @@ nowarn_spec_t::nowarn_spec_t (opt_code opt)
break;
/* Access warning group. */
- case OPT_Warray_bounds:
case OPT_Warray_bounds_:
case OPT_Wformat_overflow_:
case OPT_Wformat_truncation_:
diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index 0461b32..8b36ffe 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -470,7 +470,7 @@ diagnostic_get_location_text (diagnostic_context *context,
const char *file = s.file ? s.file : progname;
int line = 0;
int col = -1;
- if (strcmp (file, N_("<built-in>")))
+ if (strcmp (file, special_fname_builtin ()))
{
line = s.line;
if (context->show_column)
@@ -939,18 +939,49 @@ diagnostic_event::meaning::maybe_get_property_str (enum property p)
/* class diagnostic_path. */
+/* Subroutint of diagnostic_path::interprocedural_p.
+ Look for the first event in this path that is within a function
+ i.e. has a non-NULL fndecl, and a non-zero stack depth.
+ If found, write its index to *OUT_IDX and return true.
+ Otherwise return false. */
+
+bool
+diagnostic_path::get_first_event_in_a_function (unsigned *out_idx) const
+{
+ const unsigned num = num_events ();
+ for (unsigned i = 0; i < num; i++)
+ {
+ if (!(get_event (i).get_fndecl () == NULL
+ && get_event (i).get_stack_depth () == 0))
+ {
+ *out_idx = i;
+ return true;
+ }
+ }
+ return false;
+}
+
/* Return true if the events in this path involve more than one
function, or false if it is purely intraprocedural. */
bool
diagnostic_path::interprocedural_p () const
{
+ /* Ignore leading events that are outside of any function. */
+ unsigned first_fn_event_idx;
+ if (!get_first_event_in_a_function (&first_fn_event_idx))
+ return false;
+
+ const diagnostic_event &first_fn_event = get_event (first_fn_event_idx);
+ tree first_fndecl = first_fn_event.get_fndecl ();
+ int first_fn_stack_depth = first_fn_event.get_stack_depth ();
+
const unsigned num = num_events ();
- for (unsigned i = 0; i < num; i++)
+ for (unsigned i = first_fn_event_idx + 1; i < num; i++)
{
- if (get_event (i).get_fndecl () != get_event (0).get_fndecl ())
+ if (get_event (i).get_fndecl () != first_fndecl)
return true;
- if (get_event (i).get_stack_depth () != get_event (0).get_stack_depth ())
+ if (get_event (i).get_stack_depth () != first_fn_stack_depth)
return true;
}
return false;
@@ -2608,7 +2639,10 @@ test_diagnostic_get_location_text ()
const char *old_progname = progname;
progname = "PROGNAME";
assert_location_text ("PROGNAME:", NULL, 0, 0, true);
- assert_location_text ("<built-in>:", "<built-in>", 42, 10, true);
+ char *built_in_colon = concat (special_fname_builtin (), ":", (char *) 0);
+ assert_location_text (built_in_colon, special_fname_builtin (),
+ 42, 10, true);
+ free (built_in_colon);
assert_location_text ("foo.c:42:10:", "foo.c", 42, 10, true);
assert_location_text ("foo.c:42:9:", "foo.c", 42, 10, true, 0);
assert_location_text ("foo.c:42:1010:", "foo.c", 42, 10, true, 1001);
diff --git a/gcc/doc/analyzer.texi b/gcc/doc/analyzer.texi
index ec49f95..52f89b9 100644
--- a/gcc/doc/analyzer.texi
+++ b/gcc/doc/analyzer.texi
@@ -432,16 +432,6 @@ For example, SSA names are printed to the user in ``raw'' form, rather
than printing the underlying variable name.
@end itemize
-Some ideas for other checkers
-@itemize @bullet
-@item
-File-descriptor-based APIs
-@item
-Linux kernel internal APIs
-@item
-Signal handling
-@end itemize
-
@node Debugging the Analyzer
@section Debugging the Analyzer
@cindex analyzer, debugging
@@ -524,6 +514,23 @@ With a non-zero argument
it will also dump all of the states within the ``processed'' nodes.
+The builtin @code{__analyzer_dump_named_constant} will emit a warning
+during analysis describing what is known about the value of a given
+named constant, for parts of the analyzer that interact with target
+headers.
+
+For example:
+
+@smallexample
+__analyzer_dump_named_constant ("O_RDONLY");
+@end smallexample
+
+might emit the warning:
+
+@smallexample
+warning: named constant 'O_RDONLY' has value '1'
+@end smallexample
+
@smallexample
__analyzer_dump_region_model ();
@end smallexample
diff --git a/gcc/doc/contrib.texi b/gcc/doc/contrib.texi
index e14cf5e..e3de5cc 100644
--- a/gcc/doc/contrib.texi
+++ b/gcc/doc/contrib.texi
@@ -9,7 +9,7 @@
The GCC project would like to thank its many contributors. Without them the
project would not have been nearly as successful as it has been. Any omissions
in this list are accidental. Feel free to contact
-@email{law@@redhat.com} or @email{gerald@@pfeifer.com} if you have been left
+@email{jlaw@@ventanamicro.com} or @email{gerald@@pfeifer.com} if you have been left
out or some of your contributions are not listed. Please keep this list in
alphabetical order.
diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index 90b2767..5e86a95 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -3843,6 +3843,10 @@ file will never be read again, no matter what. It is a less-portable
alternative to using @samp{#ifndef} to guard the contents of header files
against multiple inclusions.
+@item #pragma region @{tokens@}...
+@itemx #pragma endregion @{tokens@}...
+These pragmas are accepted, but have no effect.
+
@end ftable
@node Other Directives
diff --git a/gcc/doc/cppopts.texi b/gcc/doc/cppopts.texi
index 75c56a3..c0a92b3 100644
--- a/gcc/doc/cppopts.texi
+++ b/gcc/doc/cppopts.texi
@@ -318,9 +318,10 @@ supported by the system's @code{iconv} library routine.
@opindex fwide-exec-charset
@cindex character set, wide execution
Set the wide execution character set, used for wide string and
-character constants. The default is UTF-32 or UTF-16, whichever
-corresponds to the width of @code{wchar_t}. As with
-@option{-fexec-charset}, @var{charset} can be any encoding supported
+character constants. The default is one of UTF-32BE, UTF-32LE, UTF-16BE,
+or UTF-16LE, whichever corresponds to the width of @code{wchar_t} and the
+big-endian or little-endian byte order being used for code generation. As
+with @option{-fexec-charset}, @var{charset} can be any encoding supported
by the system's @code{iconv} library routine; however, you will have
problems with encodings that do not fit exactly in @code{wchar_t}.
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 53478b7..d3812fa 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -2542,7 +2542,6 @@ GCC plugins may provide their own attributes.
* M32R/D Function Attributes::
* m68k Function Attributes::
* MCORE Function Attributes::
-* MeP Function Attributes::
* MicroBlaze Function Attributes::
* Microsoft Windows Function Attributes::
* MIPS Function Attributes::
@@ -5392,45 +5391,6 @@ basic @code{asm} and C code may appear to work, they cannot be
depended upon to work reliably and are not supported.
@end table
-@node MeP Function Attributes
-@subsection MeP Function Attributes
-
-These function attributes are supported by the MeP back end:
-
-@table @code
-@item disinterrupt
-@cindex @code{disinterrupt} function attribute, MeP
-On MeP targets, this attribute causes the compiler to emit
-instructions to disable interrupts for the duration of the given
-function.
-
-@item interrupt
-@cindex @code{interrupt} function attribute, MeP
-Use this attribute to indicate
-that the specified function is an interrupt handler. The compiler generates
-function entry and exit sequences suitable for use in an interrupt handler
-when this attribute is present.
-
-@item near
-@cindex @code{near} function attribute, MeP
-This attribute causes the compiler to assume the called
-function is close enough to use the normal calling convention,
-overriding the @option{-mtf} command-line option.
-
-@item far
-@cindex @code{far} function attribute, MeP
-On MeP targets this causes the compiler to use a calling convention
-that assumes the called function is too far away for the built-in
-addressing modes.
-
-@item vliw
-@cindex @code{vliw} function attribute, MeP
-The @code{vliw} attribute tells the compiler to emit
-instructions in VLIW mode instead of core mode. Note that this
-attribute is not allowed unless a VLIW coprocessor has been configured
-and enabled through command-line options.
-@end table
-
@node MicroBlaze Function Attributes
@subsection MicroBlaze Function Attributes
@@ -7075,6 +7035,26 @@ Enable/disable the generation of the AVXVNNIINT8 instructions.
@cindex @code{target("avxneconvert")} function attribute, x86
Enable/disable the generation of the AVXNECONVERT instructions.
+@item cmpccxadd
+@itemx no-cmpccxadd
+@cindex @code{target("cmpccxadd")} function attribute, x86
+Enable/disable the generation of the CMPccXADD instructions.
+
+@item amx-fp16
+@itemx no-amx-fp16
+@cindex @code{target("amx-fp16")} function attribute, x86
+Enable/disable the generation of the AMX-FP16 instructions.
+
+@item prefetchi
+@itemx no-prefetchi
+@cindex @code{target("prefetchi")} function attribute, x86
+Enable/disable the generation of the PREFETCHI instructions.
+
+@item raoint
+@itemx no-raoint
+@cindex @code{target("raoint")} function attribute, x86
+Enable/disable the generation of the RAOINT instructions.
+
@item cld
@itemx no-cld
@cindex @code{target("cld")} function attribute, x86
@@ -7316,7 +7296,6 @@ attributes.
* IA-64 Variable Attributes::
* LoongArch Variable Attributes::
* M32R/D Variable Attributes::
-* MeP Variable Attributes::
* Microsoft Windows Variable Attributes::
* MSP430 Variable Attributes::
* Nvidia PTX Variable Attributes::
@@ -8162,70 +8141,6 @@ Medium and large model objects may live anywhere in the 32-bit address space
addresses).
@end table
-@node MeP Variable Attributes
-@subsection MeP Variable Attributes
-
-The MeP target has a number of addressing modes and busses. The
-@code{near} space spans the standard memory space's first 16 megabytes
-(24 bits). The @code{far} space spans the entire 32-bit memory space.
-The @code{based} space is a 128-byte region in the memory space that
-is addressed relative to the @code{$tp} register. The @code{tiny}
-space is a 65536-byte region relative to the @code{$gp} register. In
-addition to these memory regions, the MeP target has a separate 16-bit
-control bus which is specified with @code{cb} attributes.
-
-@table @code
-
-@item based
-@cindex @code{based} variable attribute, MeP
-Any variable with the @code{based} attribute is assigned to the
-@code{.based} section, and is accessed with relative to the
-@code{$tp} register.
-
-@item tiny
-@cindex @code{tiny} variable attribute, MeP
-Likewise, the @code{tiny} attribute assigned variables to the
-@code{.tiny} section, relative to the @code{$gp} register.
-
-@item near
-@cindex @code{near} variable attribute, MeP
-Variables with the @code{near} attribute are assumed to have addresses
-that fit in a 24-bit addressing mode. This is the default for large
-variables (@code{-mtiny=4} is the default) but this attribute can
-override @code{-mtiny=} for small variables, or override @code{-ml}.
-
-@item far
-@cindex @code{far} variable attribute, MeP
-Variables with the @code{far} attribute are addressed using a full
-32-bit address. Since this covers the entire memory space, this
-allows modules to make no assumptions about where variables might be
-stored.
-
-@item io
-@cindex @code{io} variable attribute, MeP
-@itemx io (@var{addr})
-Variables with the @code{io} attribute are used to address
-memory-mapped peripherals. If an address is specified, the variable
-is assigned that address, else it is not assigned an address (it is
-assumed some other module assigns an address). Example:
-
-@smallexample
-int timer_count __attribute__((io(0x123)));
-@end smallexample
-
-@item cb
-@itemx cb (@var{addr})
-@cindex @code{cb} variable attribute, MeP
-Variables with the @code{cb} attribute are used to access the control
-bus, using special instructions. @code{addr} indicates the control bus
-address. Example:
-
-@smallexample
-int cpu_clock __attribute__((cb(0x123)));
-@end smallexample
-
-@end table
-
@node Microsoft Windows Variable Attributes
@subsection Microsoft Windows Variable Attributes
@@ -8464,7 +8379,6 @@ attributes.
* ARC Type Attributes::
* ARM Type Attributes::
* BPF Type Attributes::
-* MeP Type Attributes::
* PowerPC Type Attributes::
* x86 Type Attributes::
@end menu
@@ -9049,18 +8963,6 @@ of that type. The behavior is equivalent to the programmer manually
wrapping every such access with @code{__builtin_preserve_access_index}.
-@node MeP Type Attributes
-@subsection MeP Type Attributes
-
-@cindex @code{based} type attribute, MeP
-@cindex @code{tiny} type attribute, MeP
-@cindex @code{near} type attribute, MeP
-@cindex @code{far} type attribute, MeP
-Many of the MeP variable attributes may be applied to types as well.
-Specifically, the @code{based}, @code{tiny}, @code{near}, and
-@code{far} attributes may be applied to either. The @code{io} and
-@code{cb} attributes may not be applied to types.
-
@node PowerPC Type Attributes
@subsection PowerPC Type Attributes
@@ -14745,7 +14647,6 @@ instructions, but allow the compiler to schedule those calls.
* Other MIPS Built-in Functions::
* MSP430 Built-in Functions::
* NDS32 Built-in Functions::
-* picoChip Built-in Functions::
* Basic PowerPC Built-in Functions::
* PowerPC AltiVec/VSX Built-in Functions::
* PowerPC Hardware Transactional Memory Built-in Functions::
@@ -17872,42 +17773,6 @@ Enable global interrupt.
Disable global interrupt.
@end deftypefn
-@node picoChip Built-in Functions
-@subsection picoChip Built-in Functions
-
-GCC provides an interface to selected machine instructions from the
-picoChip instruction set.
-
-@table @code
-@item int __builtin_sbc (int @var{value})
-Sign bit count. Return the number of consecutive bits in @var{value}
-that have the same value as the sign bit. The result is the number of
-leading sign bits minus one, giving the number of redundant sign bits in
-@var{value}.
-
-@item int __builtin_byteswap (int @var{value})
-Byte swap. Return the result of swapping the upper and lower bytes of
-@var{value}.
-
-@item int __builtin_brev (int @var{value})
-Bit reversal. Return the result of reversing the bits in
-@var{value}. Bit 15 is swapped with bit 0, bit 14 is swapped with bit 1,
-and so on.
-
-@item int __builtin_adds (int @var{x}, int @var{y})
-Saturating addition. Return the result of adding @var{x} and @var{y},
-storing the value 32767 if the result overflows.
-
-@item int __builtin_subs (int @var{x}, int @var{y})
-Saturating subtraction. Return the result of subtracting @var{y} from
-@var{x}, storing the value @minus{}32768 if the result overflows.
-
-@item void __builtin_halt (void)
-Halt. The processor stops execution. This built-in is useful for
-implementing assertions.
-
-@end table
-
@node Basic PowerPC Built-in Functions
@subsection Basic PowerPC Built-in Functions
@@ -21237,6 +21102,10 @@ processors.
Returns the value that is currently set in the @samp{tp} register.
@end deftypefn
+@deftypefn {Built-in Function} void __builtin_riscv_pause (void)
+Generates the @code{pause} (hint) machine instruction.
+@end deftypefn
+
@node RX Built-in Functions
@subsection RX Built-in Functions
GCC supports some of the RX instructions which cannot be expressed in
@@ -21945,6 +21814,9 @@ Intel Core i7 Alderlake CPU.
@item rocketlake
Intel Core i7 Rocketlake CPU.
+@item graniterapids
+Intel Core i7 graniterapids CPU.
+
@item bonnell
Intel Atom Bonnell CPU.
@@ -21960,6 +21832,12 @@ Intel Atom Goldmont Plus CPU.
@item tremont
Intel Atom Tremont CPU.
+@item sierraforest
+Intel Atom Sierra Forest CPU.
+
+@item grandridge
+Intel Atom Grand Ridge CPU.
+
@item knl
Intel Knights Landing CPU.
@@ -22019,18 +21897,6 @@ AMD Family 19h Zen version 3.
@item znver4
AMD Family 19h Zen version 4.
-
-@item x86-64
-Baseline x86-64 microarchitecture level (as defined in x86-64 psABI).
-
-@item x86-64-v2
-x86-64-v2 microarchitecture level.
-
-@item x86-64-v3
-x86-64-v3 microarchitecture level.
-
-@item x86-64-v4
-x86-64-v4 microarchitecture level.
@end table
Here is an example:
@@ -22124,6 +21990,16 @@ VPCLMULQDQ instructions.
AVX512VNNI instructions.
@item avx512bitalg
AVX512BITALG instructions.
+@item x86-64
+Baseline x86-64 microarchitecture level (as defined in x86-64 psABI).
+@item x86-64-v2
+x86-64-v2 microarchitecture level.
+@item x86-64-v3
+x86-64-v3 microarchitecture level.
+@item x86-64-v4
+x86-64-v4 microarchitecture level.
+
+
@end table
Here is an example:
@@ -23570,7 +23446,6 @@ information.
* AArch64 Pragmas::
* ARM Pragmas::
* M32C Pragmas::
-* MeP Pragmas::
* PRU Pragmas::
* RS/6000 and PowerPC Pragmas::
* S/390 Pragmas::
@@ -23652,77 +23527,6 @@ char port3;
@end table
-@node MeP Pragmas
-@subsection MeP Pragmas
-
-@table @code
-
-@item custom io_volatile (on|off)
-@cindex pragma, custom io_volatile
-Overrides the command-line option @code{-mio-volatile} for the current
-file. Note that for compatibility with future GCC releases, this
-option should only be used once before any @code{io} variables in each
-file.
-
-@item GCC coprocessor available @var{registers}
-@cindex pragma, coprocessor available
-Specifies which coprocessor registers are available to the register
-allocator. @var{registers} may be a single register, register range
-separated by ellipses, or comma-separated list of those. Example:
-
-@smallexample
-#pragma GCC coprocessor available $c0...$c10, $c28
-@end smallexample
-
-@item GCC coprocessor call_saved @var{registers}
-@cindex pragma, coprocessor call_saved
-Specifies which coprocessor registers are to be saved and restored by
-any function using them. @var{registers} may be a single register,
-register range separated by ellipses, or comma-separated list of
-those. Example:
-
-@smallexample
-#pragma GCC coprocessor call_saved $c4...$c6, $c31
-@end smallexample
-
-@item GCC coprocessor subclass '(A|B|C|D)' = @var{registers}
-@cindex pragma, coprocessor subclass
-Creates and defines a register class. These register classes can be
-used by inline @code{asm} constructs. @var{registers} may be a single
-register, register range separated by ellipses, or comma-separated
-list of those. Example:
-
-@smallexample
-#pragma GCC coprocessor subclass 'B' = $c2, $c4, $c6
-
-asm ("cpfoo %0" : "=B" (x));
-@end smallexample
-
-@item GCC disinterrupt @var{name} , @var{name} @dots{}
-@cindex pragma, disinterrupt
-For the named functions, the compiler adds code to disable interrupts
-for the duration of those functions. If any functions so named
-are not encountered in the source, a warning is emitted that the pragma is
-not used. Examples:
-
-@smallexample
-#pragma disinterrupt foo
-#pragma disinterrupt bar, grill
-int foo () @{ @dots{} @}
-@end smallexample
-
-@item GCC call @var{name} , @var{name} @dots{}
-@cindex pragma, call
-For the named functions, the compiler always uses a register-indirect
-call model when calling the named functions. Examples:
-
-@smallexample
-extern int foo ();
-#pragma call foo
-@end smallexample
-
-@end table
-
@node PRU Pragmas
@subsection PRU Pragmas
diff --git a/gcc/doc/gimple.texi b/gcc/doc/gimple.texi
index 7832fa6..a426392 100644
--- a/gcc/doc/gimple.texi
+++ b/gcc/doc/gimple.texi
@@ -682,8 +682,7 @@ more than two slots on the RHS. For instance, a @code{COND_EXPR}
expression of the form @code{(a op b) ? x : y} could be flattened
out on the operand vector using 4 slots, but it would also
require additional processing to distinguish @code{c = a op b}
-from @code{c = a op b ? x : y}. Something similar occurs with
-@code{ASSERT_EXPR}. In time, these special case tree
+from @code{c = a op b ? x : y}. In time, these special case tree
expressions should be flattened into the operand vector.
@end itemize
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index c1876f2..89ff6a6 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1914,7 +1914,8 @@ should not be built.
@item --with-dwarf2
Specify that the compiler should
-use DWARF 2 debugging information as the default.
+use DWARF debugging information as the default; the exact
+DWARF version that is the default is target-specific.
@item --with-advance-toolchain=@var{at}
On 64-bit PowerPC Linux systems, configure the compiler to use the
@@ -2337,7 +2338,7 @@ specifying paths @var{path1}, @dots{}, @var{pathN}.
@smallexample
% @var{srcdir}/configure \
- --enable-offload-targets=x86_64-intelmicemul-linux-gnu=/path/to/x86_64/compiler,nvptx-none
+ --enable-offload-targets=amdgcn-amdhsa,nvptx-none
@end smallexample
@item --enable-offload-defaulted
@@ -3102,9 +3103,7 @@ but it can give you confidence in your new GCC installation or point out
problems before you install and start using your new GCC@.
First, you must have @uref{download.html,,downloaded the testsuites}.
-These are part of the full distribution, but if you downloaded the
-``core'' compiler plus any front ends, you must download the testsuites
-separately.
+These are included in the source tarball.
Second, you must have the testing tools installed. This includes
@uref{https://www.gnu.org/software/dejagnu/,,DejaGnu}, Tcl, and Expect;
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index c6323a5..cb40b38 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -204,7 +204,7 @@ in the following sections.
-flax-vector-conversions -fms-extensions @gol
-foffload=@var{arg} -foffload-options=@var{arg} @gol
-fopenacc -fopenacc-dim=@var{geom} @gol
--fopenmp -fopenmp-simd @gol
+-fopenmp -fopenmp-simd -fopenmp-target-simd-clone@r{[}=@var{device-type}@r{]} @gol
-fpermitted-flt-eval-methods=@var{standard} @gol
-fplan9-extensions -fsigned-bitfields -funsigned-bitfields @gol
-fsigned-char -funsigned-char -fstrict-flex-arrays[=@var{n}] @gol
@@ -256,7 +256,7 @@ in the following sections.
-Wno-deprecated-enum-enum-conversion -Wno-deprecated-enum-float-conversion @gol
-Weffc++ -Wno-exceptions -Wextra-semi -Wno-inaccessible-base @gol
-Wno-inherited-variadic-ctor -Wno-init-list-lifetime @gol
--Winvalid-imported-macros @gol
+-Winvalid-constexpr -Winvalid-imported-macros @gol
-Wno-invalid-offsetof -Wno-literal-suffix @gol
-Wmismatched-new-delete -Wmismatched-tags @gol
-Wmultiple-inheritance -Wnamespaces -Wnarrowing @gol
@@ -453,11 +453,14 @@ Objective-C and Objective-C++ Dialects}.
-Wno-analyzer-fd-access-mode-mismatch @gol
-Wno-analyzer-fd-double-close @gol
-Wno-analyzer-fd-leak @gol
+-Wno-analyzer-fd-phase-mismatch @gol
+-Wno-analyzer-fd-type-mismatch @gol
-Wno-analyzer-fd-use-after-close @gol
-Wno-analyzer-fd-use-without-check @gol
-Wno-analyzer-file-leak @gol
-Wno-analyzer-free-of-non-heap @gol
-Wno-analyzer-imprecise-fp-arithmetic @gol
+-Wno-analyzer-infinite-recursion @gol
-Wno-analyzer-jump-through-null @gol
-Wno-analyzer-malloc-leak @gol
-Wno-analyzer-mismatching-deallocation @gol
@@ -471,6 +474,7 @@ Objective-C and Objective-C++ Dialects}.
-Wno-analyzer-shift-count-overflow @gol
-Wno-analyzer-stale-setjmp-buffer @gol
-Wno-analyzer-tainted-allocation-size @gol
+-Wno-analyzer-tainted-assertion @gol
-Wno-analyzer-tainted-array-index @gol
-Wno-analyzer-tainted-divisor @gol
-Wno-analyzer-tainted-offset @gol
@@ -738,7 +742,7 @@ Objective-C and Objective-C++ Dialects}.
-flto-report -flto-report-wpa -fmem-report-wpa @gol
-fmem-report -fpre-ipa-mem-report -fpost-ipa-mem-report @gol
-fopt-info -fopt-info-@var{options}@r{[}=@var{file}@r{]} @gol
--fprofile-report @gol
+-fmultiflags -fprofile-report @gol
-frandom-seed=@var{string} -fsched-verbose=@var{n} @gol
-fsel-sched-verbose -fsel-sched-dump-cfg -fsel-sched-pipelining-verbose @gol
-fstats -fstack-usage -ftime-report -ftime-report-details @gol
@@ -1056,13 +1060,6 @@ Objective-C and Objective-C++ Dialects}.
-mno-callgraph-data -mslow-bytes -mno-slow-bytes -mno-lsim @gol
-mlittle-endian -mbig-endian -m210 -m340 -mstack-increment}
-@emph{MeP Options}
-@gccoptlist{-mabsdiff -mall-opts -maverage -mbased=@var{n} -mbitops @gol
--mc=@var{n} -mclip -mconfig=@var{name} -mcop -mcop32 -mcop64 -mivc2 @gol
--mdc -mdiv -meb -mel -mio-volatile -ml -mleadz -mm -mminmax @gol
--mmult -mno-opts -mrepeat -ms -msatur -msdram -msim -msimnovec -mtf @gol
--mtiny=@var{n}}
-
@emph{MicroBlaze Options}
@gccoptlist{-msoft-float -mhard-float -msmall-divides -mcpu=@var{cpu} @gol
-mmemcpy -mxl-soft-mul -mxl-soft-div -mxl-barrel-shift @gol
@@ -1195,16 +1192,12 @@ Objective-C and Objective-C++ Dialects}.
-mint32 -mno-int16 -mint16 -mno-int32 @gol
-msplit -munix-asm -mdec-asm -mgnu-asm -mlra}
-@emph{picoChip Options}
-@gccoptlist{-mae=@var{ae_type} -mvliw-lookahead=@var{N} @gol
--msymbol-as-address -mno-inefficient-warnings}
-
@emph{PowerPC Options}
See RS/6000 and PowerPC Options.
@emph{PRU Options}
@gccoptlist{-mmcu=@var{mcu} -minrt -mno-relax -mloop @gol
--mabi=@var{variant} @gol}
+-mabi=@var{variant}}
@emph{RISC-V Options}
@gccoptlist{-mbranch-cost=@var{N-instruction} @gol
@@ -1227,8 +1220,8 @@ See RS/6000 and PowerPC Options.
-malign-data=@var{type} @gol
-mbig-endian -mlittle-endian @gol
-mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{reg} @gol
--mstack-protector-guard-offset=@var{offset}}
--mcsr-check -mno-csr-check @gol
+-mstack-protector-guard-offset=@var{offset} @gol
+-mcsr-check -mno-csr-check}
@emph{RL78 Options}
@gccoptlist{-msim -mmul=none -mmul=g13 -mmul=g14 -mallregs @gol
@@ -1325,13 +1318,6 @@ See RS/6000 and PowerPC Options.
-mwarn-framesize -mwarn-dynamicstack -mstack-size -mstack-guard @gol
-mhotpatch=@var{halfwords},@var{halfwords}}
-@emph{Score Options}
-@gccoptlist{-meb -mel @gol
--mnhwloop @gol
--muls @gol
--mmac @gol
--mscore5 -mscore5u -mscore7 -mscore7d}
-
@emph{SH Options}
@gccoptlist{-m1 -m2 -m2e @gol
-m2a-nofpu -m2a-single-only -m2a-single -m2a @gol
@@ -1437,7 +1423,8 @@ See RS/6000 and PowerPC Options.
-mavx5124fmaps -mavx512vnni -mavx5124vnniw -mprfchw -mrdpid @gol
-mrdseed -msgx -mavx512vp2intersect -mserialize -mtsxldtrk@gol
-mamx-tile -mamx-int8 -mamx-bf16 -muintr -mhreset -mavxvnni@gol
--mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert @gol
+-mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 @gol
+-mprefetchi -mraoint @gol
-mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops @gol
-minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol
-mkl -mwidekl @gol
@@ -1460,7 +1447,8 @@ See RS/6000 and PowerPC Options.
-mgeneral-regs-only -mcall-ms2sysv-xlogues -mrelax-cmpxchg-loop @gol
-mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol
-mindirect-branch-register -mharden-sls=@var{choice} @gol
--mindirect-branch-cs-prefix -mneeded -mno-direct-extern-access}
+-mindirect-branch-cs-prefix -mneeded -mno-direct-extern-access @gol
+-munroll-only-small-loops -mlam=@var{choice}}
@emph{x86 Windows Options}
@gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol
@@ -2213,7 +2201,8 @@ any references to them in the result of the compilation as if the
files resided in directory @file{@var{new}} instead. Specifying this
option is equivalent to specifying all the individual
@option{-f*-prefix-map} options. This can be used to make reproducible
-builds that are location independent. See also
+builds that are location independent. Directories referenced by
+directives are not affected by these options. See also
@option{-fmacro-prefix-map}, @option{-fdebug-prefix-map} and
@option{-fprofile-prefix-map}.
@@ -2754,6 +2743,27 @@ Enable handling of OpenMP's @code{simd}, @code{declare simd},
@code{[[omp::directive(...)]]} and @code{[[omp::sequence(...)]]} in C++
and @code{!$omp} in Fortran. Other OpenMP directives are ignored.
+@item -fopenmp-target-simd-clone
+@item -fopenmp-target-simd-clone=@var{device-type}
+@opindex fopenmp-target-simd-clone
+@cindex OpenMP target SIMD clone
+In addition to generating SIMD clones for functions marked with the
+@code{declare simd} directive, GCC also generates clones
+for functions marked with the OpenMP @code{declare target} directive
+that are suitable for vectorization when this option is in effect. The
+@var{device-type} may be one of @code{none}, @code{host}, @code{nohost},
+and @code{any}, which correspond to keywords for the @code{device_type}
+clause of the @code{declare target} directive; clones are generated for
+the intersection of devices specified.
+@option{-fopenmp-target-simd-clone} is equivalent to
+@option{-fopenmp-target-simd-clone=any} and
+@option{-fno-openmp-target-simd-clone} is equivalent to
+@option{-fopenmp-target-simd-clone=none}.
+
+At @option{-O2} and higher (but not @option{-Os} or @option{-Og}) this
+optimization defaults to @option{-fopenmp-target-simd-clone=nohost}; otherwise
+it is disabled by default.
+
@item -fpermitted-flt-eval-methods=@var{style}
@opindex fpermitted-flt-eval-methods
@opindex fpermitted-flt-eval-methods=c11
@@ -3075,14 +3085,14 @@ exhaustion is signalled by throwing @code{std::bad_alloc}. See also
@itemx -fconcepts-ts
@opindex fconcepts
@opindex fconcepts-ts
-Below @option{-std=c++20}, @option{-fconcepts} enables support for the
-C++ Extensions for Concepts Technical Specification, ISO 19217 (2015).
+Enable support for the C++ Concepts feature for constraining template
+arguments. With @option{-std=c++20} and above, Concepts are part of
+the language standard, so @option{-fconcepts} defaults to on.
-With @option{-std=c++20} and above, Concepts are part of the language
-standard, so @option{-fconcepts} defaults to on. But the standard
-specification of Concepts differs significantly from the TS, so some
-constructs that were allowed in the TS but didn't make it into the
-standard can still be enabled by @option{-fconcepts-ts}.
+Some constructs that were allowed by the earlier C++ Extensions for
+Concepts Technical Specification, ISO 19217 (2015), but didn't make it
+into the standard, can additionally be enabled by
+@option{-fconcepts-ts}.
@item -fconstexpr-depth=@var{n}
@opindex fconstexpr-depth
@@ -3132,6 +3142,85 @@ of a loop too many expressions need to be evaluated, the resulting constexpr
evaluation might take too long.
The default is 33554432 (1<<25).
+@item -fcontracts
+@opindex fcontracts
+Enable experimental support for the C++ Contracts feature, as briefly
+added to and then removed from the C++20 working paper (N4820). The
+implementation also includes proposed enhancements from papers P1290,
+P1332, and P1429. This functionality is intended mostly for those
+interested in experimentation towards refining the feature to get it
+into shape for a future C++ standard.
+
+On violation of a checked contract, the violation handler is called.
+Users can replace the violation handler by defining
+@smallexample
+void handle_contract_violation (const std::experimental::contract_violation&);
+@end smallexample
+
+There are different sets of additional flags that can be used together
+to specify which contracts will be checked and how, for N4820
+contracts, P1332 contracts, or P1429 contracts; these sets cannot be
+used together.
+
+@table @gcctabopt
+@item -fcontract-mode=[on|off]
+@opindex fcontract-mode
+Control whether any contracts have any semantics at all. Defaults to on.
+
+@item -fcontract-assumption-mode=[on|off]
+@opindex fcontract-assumption-mode
+[N4820] Control whether contracts with level @samp{axiom}
+should have the assume semantic. Defaults to on.
+
+@item -fcontract-build-level=[off|default|audit]
+@opindex fcontract-build-level
+[N4820] Specify which level of contracts to generate checks
+for. Defaults to @samp{default}.
+
+@item -fcontract-continuation-mode=[on|off]
+@opindex fcontract-continuation-mode
+[N4820] Control whether to allow the program to continue executing
+after a contract violation. That is, do checked contracts have the
+@samp{maybe} semantic described below rather than the @samp{never}
+semantic. Defaults to off.
+
+@item -fcontract-role=<name>:<default>,<audit>,<axiom>
+@opindex fcontract-role
+[P1332] Specify the concrete semantics for each contract level
+of a particular contract role.
+
+@item -fcontract-semantic=[default|audit|axiom]:<semantic>
+[P1429] Specify the concrete semantic for a particular
+contract level.
+
+@item -fcontract-strict-declarations=[on|off]
+@opindex fcontract-strict-declarations
+Control whether to reject adding contracts to a function after its
+first declaration. Defaults to off.
+@end table
+
+The possible concrete semantics for that can be specified with
+@samp{-fcontract-role} or @samp{-fcontract-semantic} are:
+
+@table @code
+@item ignore
+This contract has no effect.
+
+@item assume
+This contract is treated like C++23 @code{[[assume]]}.
+
+@item check_never_continue
+@itemx never
+@itemx abort
+This contract is checked. If it fails, the violation handler is
+called. If the handler returns, @code{std::terminate} is called.
+
+@item check_maybe_continue
+@itemx maybe
+This contract is checked. If it fails, the violation handler is
+called. If the handler returns, execution continues normally.
+@end table
+
@item -fcoroutines
@opindex fcoroutines
Enable support for the C++ coroutines extension (experimental).
@@ -3666,6 +3755,16 @@ const T& foo (const T&) @{ @dots{} @}
#pragma GCC diagnostic pop
@end smallexample
+@option{-Wdangling-reference} also warns about code like
+
+@smallexample
+auto p = std::minmax(1, 2);
+@end smallexample
+
+where @code{std::minmax} returns @code{std::pair<const int&, const int&>}, and
+both references dangle after the end of the full expression that contains
+the call to @code{std::minmax}.
+
This warning is enabled by @option{-Wall}.
@item -Wdelete-non-virtual-dtor @r{(C++ and Objective-C++ only)}
@@ -3768,6 +3867,32 @@ the variable declaration statement.
@end itemize
+@item -Winvalid-constexpr
+@opindex Winvalid-constexpr
+@opindex Wno-invalid-constexpr
+
+Warn when a function never produces a constant expression. In C++20
+and earlier, for every @code{constexpr} function and function template,
+there must be at least one set of function arguments in at least one
+instantiation such that an invocation of the function or constructor
+could be an evaluated subexpression of a core constant expression.
+C++23 removed this restriction, so it's possible to have a function
+or a function template marked @code{constexpr} for which no invocation
+satisfies the requirements of a core constant expression.
+
+This warning is enabled as a pedantic warning by default in C++20 and
+earlier. In C++23, @option{-Winvalid-constexpr} can be turned on, in
+which case it will be an ordinary warning. For example:
+
+@smallexample
+void f (int& i);
+constexpr void
+g (int& i)
+@{
+ f(i); // warns by default in C++20, in C++23 only with -Winvalid-constexpr
+@}
+@end smallexample
+
@item -Winvalid-imported-macros
@opindex Winvalid-imported-macros
@opindex Wno-invalid-imported-macros
@@ -3882,6 +4007,9 @@ destructor itself or in an accessible polymorphic base class, in which
case it is possible but unsafe to delete an instance of a derived
class through a pointer to the class itself or base class. This
warning is automatically enabled if @option{-Weffc++} is specified.
+The @option{-Wdelete-non-virtual-dtor} option (enabled by @option{-Wall})
+should be preferred because it warns about the unsafe cases without false
+positives.
@item -Wregister @r{(C++ and Objective-C++ only)}
@opindex Wregister
@@ -6481,6 +6609,10 @@ optimization levels but requires optimization in order to detect infinite
recursion in calls between two or more functions.
@option{-Winfinite-recursion} is included in @option{-Wall}.
+Compare with @option{-Wanalyzer-infinite-recursion} which provides a
+similar diagnostic, but is implemented in a different way (as part of
+@option{-fanalyzer}).
+
@item -Winit-self @r{(C, C++, Objective-C and Objective-C++ only)}
@opindex Winit-self
@opindex Wno-init-self
@@ -7908,17 +8040,34 @@ is enabled by @option{-Wall}. It is more effective when @option{-ftree-vrp}
is active (the default for @option{-O2} and above) but a subset of instances
are issued even without optimization.
+By default, the trailing array of a structure will be treated as a flexible
+array member by @option{-Warray-bounds} or @option{-Warray-bounds=@var{n}}
+if it is declared as either a flexible array member per C99 standard onwards
+(@samp{[]}), a GCC zero-length array extension (@samp{[0]}), or an one-element
+array (@samp{[1]}). As a result, out of bounds subscripts or offsets into
+zero-length arrays or one-element arrays are not warned by default.
+
+You can add the option @option{-fstrict-flex-arrays} or
+@option{-fstrict-flex-arrays=@var{level}} to control how this
+option treat trailing array of a structure as a flexible array member:
+
+when @var{level}<=1, no change to the default behavior.
+
+when @var{level}=2, additional warnings will be issued for out of bounds
+subscripts or offsets into one-element arrays;
+
+when @var{level}=3, in addition to @var{level}=2, additional warnings will be
+issued for out of bounds subscripts or offsets into zero-length arrays.
+
@table @gcctabopt
@item -Warray-bounds=1
This is the default warning level of @option{-Warray-bounds} and is enabled
by @option{-Wall}; higher levels are not, and must be explicitly requested.
@item -Warray-bounds=2
-This warning level also warns about out of bounds accesses to trailing
-struct members of one-element array types (@pxref{Zero Length}) and about
-the intermediate results of pointer arithmetic that may yield out of bounds
-values. This warning level may give a larger number of false positives and
-is deactivated by default.
+This warning level also warns about the intermediate results of pointer
+arithmetic that may yield out of bounds values. This warning level may
+give a larger number of false positives and is deactivated by default.
@end table
@item -Warray-compare
@@ -9891,6 +10040,7 @@ Enabling this option effectively enables the following warnings:
@gccoptlist{ @gol
-Wanalyzer-allocation-size @gol
+-Wanalyzer-deref-before-check @gol
-Wanalyzer-double-fclose @gol
-Wanalyzer-double-free @gol
-Wanalyzer-exposure-through-output-file @gol
@@ -9898,11 +10048,14 @@ Enabling this option effectively enables the following warnings:
-Wanalyzer-fd-access-mode-mismatch @gol
-Wanalyzer-fd-double-close @gol
-Wanalyzer-fd-leak @gol
+-Wanalyzer-fd-phase-mismatch @gol
+-Wanalyzer-fd-type-mismatch @gol
-Wanalyzer-fd-use-after-close @gol
-Wanalyzer-fd-use-without-check @gol
-Wanalyzer-file-leak @gol
-Wanalyzer-free-of-non-heap @gol
-Wanalyzer-imprecise-fp-arithmetic @gol
+-Wanalyzer-infinite-recursion @gol
-Wanalyzer-jump-through-null @gol
-Wanalyzer-malloc-leak @gol
-Wanalyzer-mismatching-deallocation @gol
@@ -9961,6 +10114,30 @@ multiple of @code{sizeof (*pointer)}.
See @uref{https://cwe.mitre.org/data/definitions/131.html, CWE-131: Incorrect Calculation of Buffer Size}.
+@item -Wno-analyzer-deref-before-check
+@opindex Wanalyzer-deref-before-check
+@opindex Wno-analyzer-deref-before-check
+This warning requires @option{-fanalyzer}, which enables it; use
+@option{-Wno-analyzer-deref-before-check}
+to disable it.
+
+This diagnostic warns for paths through the code in which a pointer
+is checked for @code{NULL} *after* it has already been
+dereferenced, suggesting that the pointer could have been NULL.
+Such cases suggest that the check for NULL is either redundant,
+or that it needs to be moved to before the pointer is dereferenced.
+
+This diagnostic also considers values passed to a function argument
+marked with @code{__attribute__((nonnull))} as requiring a non-NULL
+value, and thus will complain if such values are checked for @code{NULL}
+after returning from such a function call.
+
+This diagnostic is unlikely to be reported when any level of optimization
+is enabled, as GCC's optimization logic will typically consider such
+checks for NULL as being redundant, and optimize them away before the
+analyzer "sees" them. Hence optimization should be disabled when
+attempting to trigger this diagnostic.
+
@item -Wno-analyzer-double-fclose
@opindex Wanalyzer-double-fclose
@opindex Wno-analyzer-double-fclose
@@ -10051,6 +10228,33 @@ open file descriptor is leaked.
See @uref{https://cwe.mitre.org/data/definitions/775.html, CWE-775: Missing Release of File Descriptor or Handle after Effective Lifetime}.
+@item -Wno-analyzer-fd-phase-mismatch
+@opindex Wanalyzer-fd-phase-mismatch
+@opindex Wno-analyzer-fd-phase-mismatch
+This warning requires @option{-fanalyzer}, which enables it; use
+@option{-Wno-analyzer-fd-phase-mismatch}
+to disable it.
+
+This diagnostic warns for paths through code in which an operation is
+attempted in the wrong phase of a file descriptor's lifetime.
+For example, it will warn on attempts to call @code{accept} on a stream
+socket that has not yet had @code{listen} successfully called on it.
+
+See @uref{https://cwe.mitre.org/data/definitions/666.html, CWE-666: Operation on Resource in Wrong Phase of Lifetime}.
+
+@item -Wno-analyzer-fd-type-mismatch
+@opindex Wanalyzer-fd-type-mismatch
+@opindex Wno-analyzer-fd-type-mismatch
+This warning requires @option{-fanalyzer}, which enables it; use
+@option{-Wno-analyzer-fd-type-mismatch}
+to disable it.
+
+This diagnostic warns for paths through code in which an
+operation is attempted on the wrong type of file descriptor.
+For example, it will warn on attempts to use socket operations
+on a file descriptor obtained via @code{open}, or when attempting
+to use a stream socket operation on a datagram socket.
+
@item -Wno-analyzer-fd-use-after-close
@opindex Wanalyzer-fd-use-after-close
@opindex Wno-analyzer-fd-use-after-close
@@ -10117,6 +10321,30 @@ arithmetic is used in locations where precise computation is needed. This
diagnostic only warns on use of floating-point operands inside the
calculation of an allocation size at the moment.
+@item -Wno-analyzer-infinite-recursion
+@opindex Wanalyzer-infinite-recursion
+@opindex Wno-analyzer-infinite-recursion
+This warning requires @option{-fanalyzer}, which enables it; use
+@option{-Wno-analyzer-infinite-recursion} to disable it.
+
+This diagnostics warns for paths through the code which appear to
+lead to infinite recursion.
+
+Specifically, when the analyzer "sees" a recursive call, it will compare
+the state of memory at the entry to the new frame with that at the entry
+to the previous frame of that function on the stack. The warning is
+issued if nothing in memory appears to be changing; any changes observed
+to parameters or globals are assumed to lead to termination of the
+recursion and thus suppress the warning.
+
+This diagnostic is likely to miss cases of infinite recursion that
+are convered to iteration by the optimizer before the analyzer "sees"
+them. Hence optimization should be disabled when attempting to trigger
+this diagnostic.
+
+Compare with @option{-Winfinite-recursion}, which provides a similar
+diagnostic, but is implemented in a different way.
+
@item -Wno-analyzer-jump-through-null
@opindex Wanalyzer-jump-through-null
@opindex Wno-analyzer-jump-through-null
@@ -10291,6 +10519,69 @@ of service attack.
See @uref{https://cwe.mitre.org/data/definitions/789.html, CWE-789: Memory Allocation with Excessive Size Value}.
+@item -Wno-analyzer-tainted-assertion
+@opindex Wanalyzer-tainted-assertion
+@opindex Wno-analyzer-tainted-assertion
+
+This warning requires both @option{-fanalyzer} and
+@option{-fanalyzer-checker=taint} to enable it;
+use @option{-Wno-analyzer-tainted-assertion} to disable it.
+
+This diagnostic warns for paths through the code in which a value
+that could be under an attacker's control is used as part of a
+condition without being first sanitized, and that condition guards a
+call to a function marked with attribute @code{noreturn}
+(such as the function @code{__builtin_unreachable}). Such functions
+typically indicate abnormal termination of the program, such as for
+assertion failure handlers. For example:
+
+@smallexample
+assert (some_tainted_value < SOME_LIMIT);
+@end smallexample
+
+In such cases:
+
+@itemize
+@item
+when assertion-checking is enabled: an attacker could trigger
+a denial of service by injecting an assertion failure
+
+@item
+when assertion-checking is disabled, such as by defining @code{NDEBUG},
+an attacker could inject data that subverts the process, since it
+presumably violates a precondition that is being assumed by the code.
+
+@end itemize
+
+Note that when assertion-checking is disabled, the assertions are
+typically removed by the preprocessor before the analyzer has a chance
+to "see" them, so this diagnostic can only generate warnings on builds
+in which assertion-checking is enabled.
+
+For the purpose of this warning, any function marked with attribute
+@code{noreturn} is considered as a possible assertion failure
+handler, including @code{__builtin_unreachable}. Note that these functions
+are sometimes removed by the optimizer before the analyzer "sees" them.
+Hence optimization should be disabled when attempting to trigger this
+diagnostic.
+
+See @uref{https://cwe.mitre.org/data/definitions/617.html, CWE-617: Reachable Assertion}.
+
+The warning can also report problematic constructions such as
+
+@smallexample
+switch (some_tainted_value) @{
+case 0:
+ /* [...etc; various valid cases omitted...] */
+ break;
+
+default:
+ __builtin_unreachable (); /* BUG: attacker can trigger this */
+@}
+@end smallexample
+
+despite the above not being an assertion failure, strictly speaking.
+
@item -Wno-analyzer-tainted-array-index
@opindex Wanalyzer-tainted-array-index
@opindex Wno-analyzer-tainted-array-index
@@ -10500,9 +10791,11 @@ of the following functions for working with file descriptors:
@item @code{close}
@item @code{creat}
@item @code{dup}, @code{dup2} and @code{dup3}
+@item @code{isatty}
@item @code{pipe}, and @code{pipe2}
@item @code{read}
@item @code{write}
+@item @code{socket}, @code{bind}, @code{listen}, @code{accept}, and @code{connect}
@end itemize
of the following functions for working with @code{<stdio.h>} streams:
@@ -10519,9 +10812,12 @@ of the following functions for working with @code{<stdio.h>} streams:
@code{__builtin_vprintf}
@item @code{fopen}
@item @code{fclose}
+@item @code{ferror}
@item @code{fgets}
@item @code{fgets_unlocked}
+@item @code{fileno}
@item @code{fread}
+@item @code{getc}
@item @code{getchar}
@item @code{fprintf}
@item @code{printf}
@@ -10585,6 +10881,7 @@ to enable them.
following warnings from @option{-fanalyzer}:
@gccoptlist{ @gol
+-Wanalyzer-deref-before-check @gol
-Wanalyzer-double-fclose @gol
-Wanalyzer-double-free @gol
-Wanalyzer-exposure-through-output-file @gol
@@ -14683,6 +14980,9 @@ The maximum depth of a loop nest suitable for complete peeling.
@item max-unswitch-insns
The maximum number of insns of an unswitched loop.
+@item max-unswitch-depth
+The maximum depth of a loop nest to be unswitched.
+
@item lim-expensive
The minimum cost of an expensive expression in the loop invariant motion.
@@ -15529,19 +15829,9 @@ The maximum number of may-defs we analyze when looking for a must-def
specifying the dynamic type of an object that invokes a virtual call
we may be able to devirtualize speculatively.
-@item max-vrp-switch-assertions
-The maximum number of assertions to add along the default edge of a switch
-statement during VRP.
-
@item evrp-sparse-threshold
Maximum number of basic blocks before EVRP uses a sparse cache.
-@item vrp1-mode
-Specifies the mode VRP pass 1 should operate in.
-
-@item vrp2-mode
-Specifies the mode VRP pass 2 should operate in.
-
@item ranger-debug
Specifies the type of debug output to be issued for ranges.
@@ -16220,6 +16510,16 @@ The option cannot be combined with @option{-fsanitize=thread} or
@option{-fsanitize=hwaddress}. Note that the only target
@option{-fsanitize=hwaddress} is currently supported on is AArch64.
+To get more accurate stack traces, it is possible to use options such as
+@option{-O0}, @option{-O1}, or @option{-Og} (which, for instance, prevent
+most function inlining), @option{-fno-optimize-sibling-calls} (which prevents
+optimizing sibling and tail recursive calls; this option is implicit for
+@option{-O0}, @option{-O1}, or @option{-Og}), or @option{-fno-ipa-icf} (which
+disables Identical Code Folding for functions). Since multiple runs of the
+program may yield backtraces with different addresses due to ASLR (Address
+Space Layout Randomization), it may be desirable to turn ASLR off. On Linux,
+this can be achieved with @samp{setarch `uname -m` -R ./prog}.
+
@item -fsanitize=kernel-address
@opindex fsanitize=kernel-address
Enable AddressSanitizer for Linux kernel.
@@ -16501,9 +16801,10 @@ by this option.
@end table
-Note the enabled sanitizer options tend to increase a false-positive rate
-of selected warnings, most notably @option{-Wmaybe-uninitialized}.
-And thus we recommend to disable @option{-Werror}.
+Note that sanitizers tend to increase the rate of false positive
+warnings, most notably those around @option{-Wmaybe-uninitialized}.
+We recommend against combining @option{-Werror} and [the use of]
+sanitizers.
While @option{-ftrapv} causes traps for signed overflows to be emitted,
@option{-fsanitize=undefined} gives a diagnostic message.
@@ -16899,7 +17200,7 @@ routines generate output or allocate memory).
@xref{Common Function Attributes}.
@item -finstrument-functions-once
-@opindex -finstrument-functions-once
+@opindex finstrument-functions-once
This is similar to @option{-finstrument-functions}, but the profiling
functions are called only once per instrumented function, i.e. the first
profiling function is called after the first entry into the instrumented
@@ -19344,6 +19645,34 @@ allocation for the WPA phase only.
Makes the compiler print some statistics about permanent memory
allocation before or after interprocedural optimization.
+@item -fmultiflags
+@opindex fmultiflags
+This option enables multilib-aware @code{TFLAGS} to be used to build
+target libraries with options different from those the compiler is
+configured to use by default, through the use of specs (@xref{Spec
+Files}) set up by compiler internals, by the target, or by builders at
+configure time.
+
+Like @code{TFLAGS}, this allows the target libraries to be built for
+portable baseline environments, while the compiler defaults to more
+demanding ones. That's useful because users can easily override the
+defaults the compiler is configured to use to build their own programs,
+if the defaults are not ideal for their target environment, whereas
+rebuilding the runtime libraries is usually not as easy or desirable.
+
+Unlike @code{TFLAGS}, the use of specs enables different flags to be
+selected for different multilibs. The way to accomplish that is to
+build with @samp{make TFLAGS=-fmultiflags}, after configuring
+@samp{--with-specs=%@{fmultiflags:...@}}.
+
+This option is discarded by the driver once it's done processing driver
+self spec.
+
+It is also useful to check that @code{TFLAGS} are being used to build
+all target libraries, by configuring a non-bootstrap compiler
+@samp{--with-specs='%@{!fmultiflags:%emissing TFLAGS@}'} and building
+the compiler and target libraries.
+
@item -fprofile-report
@opindex fprofile-report
Makes the compiler print some statistics about consistency of the
@@ -19558,7 +19887,6 @@ platform.
* M32R/D Options::
* M680x0 Options::
* MCore Options::
-* MeP Options::
* MicroBlaze Options::
* MIPS Options::
* MMIX Options::
@@ -19570,7 +19898,6 @@ platform.
* Nvidia PTX Options::
* OpenRISC Options::
* PDP-11 Options::
-* picoChip Options::
* PowerPC Options::
* PRU Options::
* RISC-V Options::
@@ -19578,7 +19905,6 @@ platform.
* RS/6000 and PowerPC Options::
* RX Options::
* S/390 and zSeries Options::
-* Score Options::
* SH Options::
* Solaris 2 Options::
* SPARC Options::
@@ -19832,8 +20158,9 @@ performance of the code. Permissible values for this option are:
@samp{cortex-a57.cortex-a53}, @samp{cortex-a72.cortex-a53},
@samp{cortex-a73.cortex-a35}, @samp{cortex-a73.cortex-a53},
@samp{cortex-a75.cortex-a55}, @samp{cortex-a76.cortex-a55},
-@samp{cortex-r82}, @samp{cortex-x1}, @samp{cortex-x2},
-@samp{cortex-a510}, @samp{cortex-a710}, @samp{ampere1}, @samp{native}.
+@samp{cortex-r82}, @samp{cortex-x1}, @samp{cortex-x1c}, @samp{cortex-x2},
+@samp{cortex-x3}, @samp{cortex-a510}, @samp{cortex-a710}, @samp{cortex-a715},
+@samp{ampere1}, @samp{ampere1a}, and @samp{native}.
The values @samp{cortex-a57.cortex-a53}, @samp{cortex-a72.cortex-a53},
@samp{cortex-a73.cortex-a35}, @samp{cortex-a73.cortex-a53},
@@ -20006,9 +20333,9 @@ Enable FP16 fmla extension. This also enables FP16 extensions and
floating-point instructions. This option is enabled by default for @option{-march=armv8.4-a}. Use of this option with architectures prior to Armv8.2-A is not supported.
@item rcpc
-Enable the RcPc extension. This does not change code generation from GCC,
-but is passed on to the assembler, enabling inline asm statements to use
-instructions from the RcPc extension.
+Enable the RCpc extension. This enables the use of the LDAPR instructions for
+load-acquire atomic semantics, and passes it on to the assembler, enabling
+inline asm statements to use instructions from the RCpc extension.
@item dotprod
Enable the Dot Product extension. This also enables Advanced SIMD instructions.
@item aes
@@ -20087,6 +20414,8 @@ Enable the instructions to accelerate memory operations like @code{memcpy},
Enable the Flag Manipulation instructions Extension.
@item pauth
Enable the Pointer Authentication Extension.
+@item cssc
+Enable the Common Short Sequence Compression instructions.
@end table
@@ -21724,7 +22053,7 @@ Permissible names are: @samp{arm7tdmi}, @samp{arm7tdmi-s}, @samp{arm710t},
@samp{cortex-r7}, @samp{cortex-r8}, @samp{cortex-r52}, @samp{cortex-r52plus},
@samp{cortex-m0}, @samp{cortex-m0plus}, @samp{cortex-m1}, @samp{cortex-m3},
@samp{cortex-m4}, @samp{cortex-m7}, @samp{cortex-m23}, @samp{cortex-m33},
-@samp{cortex-m35p}, @samp{cortex-m55}, @samp{cortex-x1},
+@samp{cortex-m35p}, @samp{cortex-m55}, @samp{cortex-x1}, @samp{cortex-x1c},
@samp{cortex-m1.small-multiply}, @samp{cortex-m0.small-multiply},
@samp{cortex-m0plus.small-multiply}, @samp{exynos-m1}, @samp{marvell-pj4},
@samp{neoverse-n1}, @samp{neoverse-n2}, @samp{neoverse-v1}, @samp{xscale},
@@ -25053,7 +25382,7 @@ These command-line options are defined for LoongArch targets:
@table @gcctabopt
@item -march=@var{cpu-type}
-@opindex -march
+@opindex march
Generate instructions for the machine type @var{cpu-type}. In contrast to
@option{-mtune=@var{cpu-type}}, which merely tunes the generated code
for the specified @var{cpu-type}, @option{-march=@var{cpu-type}} allows GCC
@@ -25123,43 +25452,43 @@ registers for parameter passing. This option may change the target
ABI.
@item -msingle-float
-@opindex -msingle-float
+@opindex msingle-float
Force @option{-mfpu=32} and allow the use of 32-bit floating-point
registers for parameter passing. This option may change the target
ABI.
@item -mdouble-float
-@opindex -mdouble-float
+@opindex mdouble-float
Force @option{-mfpu=64} and allow the use of 32/64-bit floating-point
registers for parameter passing. This option may change the target
ABI.
@item -mbranch-cost=@var{n}
-@opindex -mbranch-cost
+@opindex mbranch-cost
Set the cost of branches to roughly @var{n} instructions.
@item -mcheck-zero-division
@itemx -mno-check-zero-divison
-@opindex -mcheck-zero-division
+@opindex mcheck-zero-division
Trap (do not trap) on integer division by zero. The default is
@option{-mcheck-zero-division} for @option{-O0} or @option{-Og}, and
@option{-mno-check-zero-division} for other optimization levels.
@item -mcond-move-int
@itemx -mno-cond-move-int
-@opindex -mcond-move-int
+@opindex mcond-move-int
Conditional moves for integral data in general-purpose registers
are enabled (disabled). The default is @option{-mcond-move-int}.
@item -mcond-move-float
@itemx -mno-cond-move-float
-@opindex -mcond-move-float
+@opindex mcond-move-float
Conditional moves for floating-point registers are enabled (disabled).
The default is @option{-mcond-move-float}.
@item -mmemcpy
@itemx -mno-memcpy
-@opindex -mmemcpy
+@opindex mmemcpy
Force (do not force) the use of @code{memcpy} for non-trivial block moves.
The default is @option{-mno-memcpy}, which allows GCC to inline most
constant-sized copies. Setting optimization level to @option{-Os} also
@@ -25169,18 +25498,18 @@ the command line.
@item -mstrict-align
@itemx -mno-strict-align
-@opindex -mstrict-align
+@opindex mstrict-align
Avoid or allow generating memory accesses that may not be aligned on a natural
object boundary as described in the architecture specification. The default is
@option{-mno-strict-align}.
@item -msmall-data-limit=@var{number}
-@opindex -msmall-data-limit
+@opindex msmall-data-limit
Put global and static data smaller than @var{number} bytes into a special
section (on some targets). The default value is 0.
@item -mmax-inline-memcpy-size=@var{n}
-@opindex -mmax-inline-memcpy-size
+@opindex mmax-inline-memcpy-size
Inline all block moves (such as calls to @code{memcpy} or structure copies)
less than or equal to @var{n} bytes. The default value of @var{n} is 1024.
@@ -25851,169 +26180,6 @@ value is 0x1000.
@end table
-@node MeP Options
-@subsection MeP Options
-@cindex MeP options
-
-@table @gcctabopt
-
-@item -mabsdiff
-@opindex mabsdiff
-Enables the @code{abs} instruction, which is the absolute difference
-between two registers.
-
-@item -mall-opts
-@opindex mall-opts
-Enables all the optional instructions---average, multiply, divide, bit
-operations, leading zero, absolute difference, min/max, clip, and
-saturation.
-
-
-@item -maverage
-@opindex maverage
-Enables the @code{ave} instruction, which computes the average of two
-registers.
-
-@item -mbased=@var{n}
-@opindex mbased=
-Variables of size @var{n} bytes or smaller are placed in the
-@code{.based} section by default. Based variables use the @code{$tp}
-register as a base register, and there is a 128-byte limit to the
-@code{.based} section.
-
-@item -mbitops
-@opindex mbitops
-Enables the bit operation instructions---bit test (@code{btstm}), set
-(@code{bsetm}), clear (@code{bclrm}), invert (@code{bnotm}), and
-test-and-set (@code{tas}).
-
-@item -mc=@var{name}
-@opindex mc=
-Selects which section constant data is placed in. @var{name} may
-be @samp{tiny}, @samp{near}, or @samp{far}.
-
-@item -mclip
-@opindex mclip
-Enables the @code{clip} instruction. Note that @option{-mclip} is not
-useful unless you also provide @option{-mminmax}.
-
-@item -mconfig=@var{name}
-@opindex mconfig=
-Selects one of the built-in core configurations. Each MeP chip has
-one or more modules in it; each module has a core CPU and a variety of
-coprocessors, optional instructions, and peripherals. The
-@code{MeP-Integrator} tool, not part of GCC, provides these
-configurations through this option; using this option is the same as
-using all the corresponding command-line options. The default
-configuration is @samp{default}.
-
-@item -mcop
-@opindex mcop
-Enables the coprocessor instructions. By default, this is a 32-bit
-coprocessor. Note that the coprocessor is normally enabled via the
-@option{-mconfig=} option.
-
-@item -mcop32
-@opindex mcop32
-Enables the 32-bit coprocessor's instructions.
-
-@item -mcop64
-@opindex mcop64
-Enables the 64-bit coprocessor's instructions.
-
-@item -mivc2
-@opindex mivc2
-Enables IVC2 scheduling. IVC2 is a 64-bit VLIW coprocessor.
-
-@item -mdc
-@opindex mdc
-Causes constant variables to be placed in the @code{.near} section.
-
-@item -mdiv
-@opindex mdiv
-Enables the @code{div} and @code{divu} instructions.
-
-@item -meb
-@opindex meb
-Generate big-endian code.
-
-@item -mel
-@opindex mel
-Generate little-endian code.
-
-@item -mio-volatile
-@opindex mio-volatile
-Tells the compiler that any variable marked with the @code{io}
-attribute is to be considered volatile.
-
-@item -ml
-@opindex ml
-Causes variables to be assigned to the @code{.far} section by default.
-
-@item -mleadz
-@opindex mleadz
-Enables the @code{leadz} (leading zero) instruction.
-
-@item -mm
-@opindex mm
-Causes variables to be assigned to the @code{.near} section by default.
-
-@item -mminmax
-@opindex mminmax
-Enables the @code{min} and @code{max} instructions.
-
-@item -mmult
-@opindex mmult
-Enables the multiplication and multiply-accumulate instructions.
-
-@item -mno-opts
-@opindex mno-opts
-Disables all the optional instructions enabled by @option{-mall-opts}.
-
-@item -mrepeat
-@opindex mrepeat
-Enables the @code{repeat} and @code{erepeat} instructions, used for
-low-overhead looping.
-
-@item -ms
-@opindex ms
-Causes all variables to default to the @code{.tiny} section. Note
-that there is a 65536-byte limit to this section. Accesses to these
-variables use the @code{%gp} base register.
-
-@item -msatur
-@opindex msatur
-Enables the saturation instructions. Note that the compiler does not
-currently generate these itself, but this option is included for
-compatibility with other tools, like @code{as}.
-
-@item -msdram
-@opindex msdram
-Link the SDRAM-based runtime instead of the default ROM-based runtime.
-
-@item -msim
-@opindex msim
-Link the simulator run-time libraries.
-
-@item -msimnovec
-@opindex msimnovec
-Link the simulator runtime libraries, excluding built-in support
-for reset and exception vectors and tables.
-
-@item -mtf
-@opindex mtf
-Causes all functions to default to the @code{.far} section. Without
-this option, functions default to the @code{.near} section.
-
-@item -mtiny=@var{n}
-@opindex mtiny=
-Variables that are @var{n} bytes or smaller are allocated to the
-@code{.tiny} section. These variables use the @code{$gp} base
-register. The default for this option is 4, but note that there's a
-65536-byte limit to the @code{.tiny} section.
-
-@end table
-
@node MicroBlaze Options
@subsection MicroBlaze Options
@cindex MicroBlaze Options
@@ -28403,54 +28569,6 @@ Use the new LRA register allocator. By default, the old ``reload''
allocator is used.
@end table
-@node picoChip Options
-@subsection picoChip Options
-@cindex picoChip options
-
-These @samp{-m} options are defined for picoChip implementations:
-
-@table @gcctabopt
-
-@item -mae=@var{ae_type}
-@opindex mcpu
-Set the instruction set, register set, and instruction scheduling
-parameters for array element type @var{ae_type}. Supported values
-for @var{ae_type} are @samp{ANY}, @samp{MUL}, and @samp{MAC}.
-
-@option{-mae=ANY} selects a completely generic AE type. Code
-generated with this option runs on any of the other AE types. The
-code is not as efficient as it would be if compiled for a specific
-AE type, and some types of operation (e.g., multiplication) do not
-work properly on all types of AE.
-
-@option{-mae=MUL} selects a MUL AE type. This is the most useful AE type
-for compiled code, and is the default.
-
-@option{-mae=MAC} selects a DSP-style MAC AE. Code compiled with this
-option may suffer from poor performance of byte (char) manipulation,
-since the DSP AE does not provide hardware support for byte load/stores.
-
-@item -msymbol-as-address
-Enable the compiler to directly use a symbol name as an address in a
-load/store instruction, without first loading it into a
-register. Typically, the use of this option generates larger
-programs, which run faster than when the option isn't used. However, the
-results vary from program to program, so it is left as a user option,
-rather than being permanently enabled.
-
-@item -mno-inefficient-warnings
-Disables warnings about the generation of inefficient code. These
-warnings can be generated, for example, when compiling code that
-performs byte-level memory operations on the MAC AE type. The MAC AE has
-no hardware support for byte-level memory operations, so all byte
-load/stores must be synthesized from word load/store operations. This is
-inefficient and a warning is generated to indicate
-that you should rewrite the code to avoid byte operations, or to target
-an AE type that has the necessary hardware support. This option disables
-these warnings.
-
-@end table
-
@node PowerPC Options
@subsection PowerPC Options
@cindex PowerPC options
@@ -29475,7 +29593,7 @@ Specify both @option{-mcall-sysv} and @option{-meabi} options.
Specify both @option{-mcall-sysv} and @option{-mno-eabi} options.
@item -mcall-aixdesc
-@opindex m
+@opindex mcall-aixdesc
On System V.4 and embedded PowerPC systems compile code for the AIX
operating system.
@@ -29495,7 +29613,7 @@ On System V.4 and embedded PowerPC systems compile code for the
NetBSD operating system.
@item -mcall-openbsd
-@opindex mcall-netbsd
+@opindex mcall-openbsd
On System V.4 and embedded PowerPC systems compile code for the
OpenBSD operating system.
@@ -30484,50 +30602,6 @@ This option can be overridden for individual functions with the
@code{hotpatch} attribute.
@end table
-@node Score Options
-@subsection Score Options
-@cindex Score Options
-
-These options are defined for Score implementations:
-
-@table @gcctabopt
-@item -meb
-@opindex meb
-Compile code for big-endian mode. This is the default.
-
-@item -mel
-@opindex mel
-Compile code for little-endian mode.
-
-@item -mnhwloop
-@opindex mnhwloop
-Disable generation of @code{bcnz} instructions.
-
-@item -muls
-@opindex muls
-Enable generation of unaligned load and store instructions.
-
-@item -mmac
-@opindex mmac
-Enable the use of multiply-accumulate instructions. Disabled by default.
-
-@item -mscore5
-@opindex mscore5
-Specify the SCORE5 as the target architecture.
-
-@item -mscore5u
-@opindex mscore5u
-Specify the SCORE5U of the target architecture.
-
-@item -mscore7
-@opindex mscore7
-Specify the SCORE7 as the target architecture. This is the default.
-
-@item -mscore7d
-@opindex mscore7d
-Specify the SCORE7D as the target architecture.
-@end table
-
@node SH Options
@subsection SH Options
@@ -32043,6 +32117,23 @@ RDSEED, XSAVE, XSAVEC, XSAVES, XSAVEOPT, CLFLUSHOPT, FSGSBASE, PTWRITE, RDPID,
SGX, CLWB, GFNI-SSE, MOVDIRI, MOVDIR64B, CLDEMOTE and WAITPKG instruction set
support.
+@item sierraforest
+Intel Sierra Forest CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3,
+SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC,
+XSAVES, XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI,
+MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA, LZCNT,
+PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL, AVX-VNNI,
+AVXIFMA, AVXVNNIINT8, AVXNECONVERT and CMPCCXADD instruction set support.
+
+@item grandridge
+Intel Grand Ridge CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3,
+SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC,
+XSAVES, XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI,
+MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA, LZCNT,
+PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL, AVX-VNNI,
+AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD and RAOINT instruction set
+support.
+
@item knl
Intel Knight's Landing CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3,
SSSE3, SSE4.1, SSE4.2, POPCNT, CX16, SAHF, FXSR, AVX, XSAVE, PCLMUL, FSGSBASE,
@@ -32138,6 +32229,17 @@ CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD
PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI, VAES, AVX512VBMI2,
VPCLMULQDQ, AVX512BITALG, RDPID and AVX512VPOPCNTDQ instruction set support.
+@item graniterapids
+Intel graniterapids CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3,
+SSSE3, SSE4.1, SSE4.2, POPCNT, CX16, SAHF, FXSR, AVX, XSAVE, PCLMUL, FSGSBASE,
+RDRND, F16C, AVX2, BMI, BMI2, LZCNT, FMA, MOVBE, HLE, RDSEED, ADCX, PREFETCHW,
+AES, CLFLUSHOPT, XSAVEC, XSAVES, SGX, AVX512F, AVX512VL, AVX512BW, AVX512DQ,
+AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI, VAES, AVX512VBMI2,
+VPCLMULQDQ, AVX512BITALG, RDPID, AVX512VPOPCNTDQ, PCONFIG, WBNOINVD, CLWB,
+MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG,
+SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI, AVX512FP16,
+AVX512BF16, AMX-FP16 and PREFETCHI instruction set support.
+
@item k6
AMD K6 CPU with MMX instruction set support.
@@ -32444,7 +32546,7 @@ comparison is unordered.
@item -m80387
@itemx -mhard-float
-@opindex 80387
+@opindex m80387
@opindex mhard-float
Generate output containing 80387 instructions for floating point.
@@ -32970,6 +33072,18 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
@need 200
@itemx -mavxneconvert
@opindex mavxneconvert
+@need 200
+@itemx -mcmpccxadd
+@opindex mcmpccxadd
+@need 200
+@itemx -mamx-fp16
+@opindex mamx-fp16
+@need 200
+@itemx -mprefetchi
+@opindex mprefetchi
+@need 200
+@itemx -mraoint
+@opindex mraoint
These switches enable the use of instructions in the MMX, SSE,
SSE2, SSE3, SSSE3, SSE4, SSE4A, SSE4.1, SSE4.2, AVX, AVX2, AVX512F, AVX512PF,
AVX512ER, AVX512CD, AVX512VL, AVX512BW, AVX512DQ, AVX512IFMA, AVX512VBMI, SHA,
@@ -32980,8 +33094,9 @@ XSAVEOPT, XSAVEC, XSAVES, RTM, HLE, TBM, MWAITX, CLZERO, PKU, AVX512VBMI2,
GFNI, VAES, WAITPKG, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B, AVX512BF16,
ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, SERIALIZE,
UINTR, HRESET, AMXTILE, AMXINT8, AMXBF16, KL, WIDEKL, AVXVNNI, AVX512FP16,
-AVXIFMA, AVXVNNIINT8, AVXNECONVERT or CLDEMOTE extended instruction sets. Each
-has a corresponding @option{-mno-} option to disable use of these instructions.
+AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD, AMX-FP16, PREFETCHI, RAOINT or
+CLDEMOTE extended instruction sets. Each has a corresponding @option{-mno-}
+option to disable use of these instructions.
These extensions are also available as built-in functions: see
@ref{x86 Built-in Functions}, for details of the functions enabled and
@@ -33600,10 +33715,11 @@ registers.
@item -mrelax-cmpxchg-loop
@opindex mrelax-cmpxchg-loop
-Relax cmpxchg loop by emitting an early load and compare before cmpxchg,
-execute pause if load value is not expected. This reduces excessive
-cachline bouncing when and works for all atomic logic fetch builtins
-that generates compare and swap loop.
+When emitting a compare-and-swap loop for @ref{__sync Builtins}
+and @ref{__atomic Builtins} lacking a native instruction, optimize
+for the highly contended case by issuing an atomic load before the
+@code{CMPXCHG} instruction, and using the @code{PAUSE} instruction
+to save CPU power when restarting the loop.
@item -mindirect-branch=@var{choice}
@opindex mindirect-branch
@@ -33767,6 +33883,21 @@ treat access to protected symbols as local symbols. The default is
@option{-mno-direct-extern-access} and executable compiled with
@option{-mdirect-extern-access} may not be binary compatible if
protected symbols are used in shared libraries and executable.
+
+@item -munroll-only-small-loops
+@opindex munroll-only-small-loops
+@opindex mno-unroll-only-small-loops
+Controls conservative small loop unrolling. It is default enabled by
+O2, and unrolls loop with less than 4 insns by 1 time. Explicit
+-f[no-]unroll-[all-]loops would disable this flag to avoid any
+unintended unrolling behavior that user does not want.
+
+@item -mlam=@var{choice}
+@opindex mlam
+LAM(linear-address masking) allows special bits in the pointer to be used
+for metadata. The default is @samp{none}. With @samp{u48}, pointer bits in
+positions 62:48 can be used for metadata; With @samp{u57}, pointer bits in
+positions 62:57 can be used for metadata.
@end table
@node x86 Windows Options
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index d0a71ecb..482e86f 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -6964,6 +6964,13 @@ case, you can and should make operand 1's predicate reject some operators
in the @samp{cstore@var{mode}4} pattern, or remove the pattern altogether
from the machine description.
+@cindex @code{tbranch_@var{op}@var{mode}3} instruction pattern
+@item @samp{tbranch_@var{op}@var{mode}3}
+Conditional branch instruction combined with a bit test-and-compare
+instruction. Operand 0 is the operand of the comparison. Operand 1 is the bit
+position of Operand 1 to test. Operand 3 is the @code{code_label} to jump to.
+@var{op} is one of @var{eq} or @var{ne}.
+
@cindex @code{cbranch@var{mode}4} instruction pattern
@item @samp{cbranch@var{mode}4}
Conditional branch instruction combined with a compare instruction.
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index a12175b..ffe69d6 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -116,9 +116,6 @@ The runtime support library for transactional memory.
@item libobjc
The Objective-C and Objective-C++ runtime library.
-@item liboffloadmic
-A library to allow OpenMP to Intel MIC targets.
-
@item libphobos
The D standard and runtime library. The bulk of this library is mirrored
from the @uref{https://github.com/@/dlang, master D repositories}.
@@ -2508,9 +2505,15 @@ Target supports the execution of @code{amx-int8} instructions.
@item amx_bf16
Target supports the execution of @code{amx-bf16} instructions.
+@item amx_fp16
+Target supports the execution of @code{amx-fp16} instructions.
+
@item cell_hw
Test system can execute AltiVec and Cell PPU instructions.
+@item cmpccxadd
+Target supports the execution of @code{cmpccxadd} instructions.
+
@item coldfire_fpu
Target uses a ColdFire FPU.
@@ -2529,6 +2532,12 @@ Target does not require strict alignment.
@item pie_copyreloc
The x86-64 target linker supports PIE with copy reloc.
+@item prefetchi
+Target supports the execution of @code{prefetchi} instructions.
+
+@item raoint
+Target supports the execution of @code{raoint} instructions.
+
@item rdrand
Target supports x86 @code{rdrand} instruction.
@@ -2657,6 +2666,9 @@ Target can compile using @code{pthread.h} with no errors or warnings.
@item pthread_h
Target has @code{pthread.h}.
+@item sockets
+Target can compile using @code{sys/socket.h} with no errors or warnings.
+
@item run_expensive_tests
Expensive testcases (usually those that consume excessive amounts of CPU
time) should be run on this target. This can be enabled by setting the
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 438c51c..2330338 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -6146,6 +6146,22 @@ instruction pattern. There is no need for the hook to handle these two
implementation approaches itself.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_VECTORIZE_CAN_SPECIAL_DIV_BY_CONST (enum @var{tree_code}, tree @var{vectype}, wide_int @var{constant}, rtx *@var{output}, rtx @var{in0}, rtx @var{in1})
+This hook is used to test whether the target has a special method of
+division of vectors of type @var{vectype} using the value @var{constant},
+and producing a vector of type @var{vectype}. The division
+will then not be decomposed by the vectorizer and kept as a div.
+
+When the hook is being used to test whether the target supports a special
+divide, @var{in0}, @var{in1}, and @var{output} are all null. When the hook
+is being used to emit a division, @var{in0} and @var{in1} are the source
+vectors of type @var{vecttype} and @var{output} is the destination vector of
+type @var{vectype}.
+
+Return true if the operation is possible, emitting instructions for it
+if rtxes are provided and updating @var{output}.
+@end deftypefn
+
@deftypefn {Target Hook} tree TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION (unsigned @var{code}, tree @var{vec_type_out}, tree @var{vec_type_in})
This hook should return the decl of a function that implements the
vectorized variant of the function with the @code{combined_fn} code
@@ -6283,7 +6299,7 @@ The default is @code{NULL_TREE} which means to not vectorize scatter
stores.
@end deftypefn
-@deftypefn {Target Hook} int TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN (struct cgraph_node *@var{}, struct cgraph_simd_clone *@var{}, @var{tree}, @var{int})
+@deftypefn {Target Hook} int TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN (struct cgraph_node *@var{}, struct cgraph_simd_clone *@var{}, @var{tree}, @var{int}, @var{bool})
This hook should set @var{vecsize_mangle}, @var{vecsize_int}, @var{vecsize_float}
fields in @var{simd_clone} structure pointed by @var{clone_info} argument and also
@var{simdlen} field if it was previously 0.
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 8cc3026..c1a1576 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -4182,6 +4182,8 @@ address; but often a machine-dependent strategy can generate better code.
@hook TARGET_VECTORIZE_VEC_PERM_CONST
+@hook TARGET_VECTORIZE_CAN_SPECIAL_DIV_BY_CONST
+
@hook TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
@hook TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION
diff --git a/gcc/dojump.cc b/gcc/dojump.cc
index 2af0cd1..190324f 100644
--- a/gcc/dojump.cc
+++ b/gcc/dojump.cc
@@ -619,7 +619,7 @@ do_jump (tree exp, rtx_code_label *if_false_label,
}
do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)),
NE, TYPE_UNSIGNED (TREE_TYPE (exp)),
- GET_MODE (temp), NULL_RTX,
+ exp, GET_MODE (temp), NULL_RTX,
if_false_label, if_true_label, prob);
}
@@ -687,7 +687,7 @@ do_jump_by_parts_greater_rtx (scalar_int_mode mode, int unsignedp, rtx op0,
/* All but high-order word must be compared as unsigned. */
do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0),
- word_mode, NULL_RTX, NULL, if_true_label,
+ NULL, word_mode, NULL_RTX, NULL, if_true_label,
prob);
/* Emit only one comparison for 0. Do not emit the last cond jump. */
@@ -695,8 +695,8 @@ do_jump_by_parts_greater_rtx (scalar_int_mode mode, int unsignedp, rtx op0,
break;
/* Consider lower words only if these are equal. */
- do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode,
- NULL_RTX, NULL, if_false_label,
+ do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, NULL,
+ word_mode, NULL_RTX, NULL, if_false_label,
prob.invert ());
}
@@ -755,7 +755,7 @@ do_jump_by_parts_zero_rtx (scalar_int_mode mode, rtx op0,
if (part != 0)
{
- do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode,
+ do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, NULL, word_mode,
NULL_RTX, if_false_label, if_true_label, prob);
return;
}
@@ -766,7 +766,7 @@ do_jump_by_parts_zero_rtx (scalar_int_mode mode, rtx op0,
for (i = 0; i < nwords; i++)
do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
- const0_rtx, EQ, 1, word_mode, NULL_RTX,
+ const0_rtx, EQ, 1, NULL, word_mode, NULL_RTX,
if_false_label, NULL, prob);
if (if_true_label)
@@ -809,8 +809,8 @@ do_jump_by_parts_equality_rtx (scalar_int_mode mode, rtx op0, rtx op1,
for (i = 0; i < nwords; i++)
do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
- operand_subword_force (op1, i, mode),
- EQ, 0, word_mode, NULL_RTX,
+ operand_subword_force (op1, i, mode),
+ EQ, 0, NULL, word_mode, NULL_RTX,
if_false_label, NULL, prob);
if (if_true_label)
@@ -963,6 +963,23 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
rtx_code_label *if_true_label,
profile_probability prob)
{
+ do_compare_rtx_and_jump (op0, op1, code, unsignedp, NULL, mode, size,
+ if_false_label, if_true_label, prob);
+}
+
+/* Like do_compare_and_jump but expects the values to compare as two rtx's.
+ The decision as to signed or unsigned comparison must be made by the caller.
+
+ If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
+ compared. */
+
+void
+do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
+ tree val, machine_mode mode, rtx size,
+ rtx_code_label *if_false_label,
+ rtx_code_label *if_true_label,
+ profile_probability prob)
+{
rtx tem;
rtx_code_label *dummy_label = NULL;
@@ -1177,8 +1194,10 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
}
else
dest_label = if_false_label;
- do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
- size, dest_label, NULL, first_prob);
+
+ do_compare_rtx_and_jump (op0, op1, first_code, unsignedp,
+ val, mode, size, dest_label, NULL,
+ first_prob);
}
/* For !and_them we want to split:
if (x) goto t; // prob;
@@ -1192,8 +1211,9 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
else
{
profile_probability first_prob = prob.split (cprob);
- do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
- size, NULL, if_true_label, first_prob);
+ do_compare_rtx_and_jump (op0, op1, first_code, unsignedp,
+ val, mode, size, NULL,
+ if_true_label, first_prob);
if (orig_code == NE && can_compare_p (UNEQ, mode, ccp_jump))
{
/* x != y can be split into x unord y || x ltgt y
@@ -1215,7 +1235,7 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
}
}
- emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp,
+ emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp, val,
if_true_label, prob);
}
@@ -1289,9 +1309,9 @@ do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code,
op1 = new_op1;
}
- do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode,
- ((mode == BLKmode)
- ? expr_size (treeop0) : NULL_RTX),
+ do_compare_rtx_and_jump (op0, op1, code, unsignedp, treeop0, mode,
+ ((mode == BLKmode)
+ ? expr_size (treeop0) : NULL_RTX),
if_false_label, if_true_label, prob);
}
diff --git a/gcc/dojump.h b/gcc/dojump.h
index e379cce..d1d79c4 100644
--- a/gcc/dojump.h
+++ b/gcc/dojump.h
@@ -71,6 +71,10 @@ extern void jumpifnot (tree exp, rtx_code_label *label,
extern void jumpifnot_1 (enum tree_code, tree, tree, rtx_code_label *,
profile_probability);
+extern void do_compare_rtx_and_jump (rtx, rtx, enum rtx_code, int, tree,
+ machine_mode, rtx, rtx_code_label *,
+ rtx_code_label *, profile_probability);
+
extern void do_compare_rtx_and_jump (rtx, rtx, enum rtx_code, int,
machine_mode, rtx, rtx_code_label *,
rtx_code_label *, profile_probability);
diff --git a/gcc/explow.cc b/gcc/explow.cc
index ddb4d6ae..568e0eb 100644
--- a/gcc/explow.cc
+++ b/gcc/explow.cc
@@ -1037,7 +1037,7 @@ round_push (rtx size)
TRUNC_DIV_EXPR. */
size = expand_binop (Pmode, add_optab, size, alignm1_rtx,
NULL_RTX, 1, OPTAB_LIB_WIDEN);
- size = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, size, align_rtx,
+ size = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, NULL, NULL, size, align_rtx,
NULL_RTX, 1);
size = expand_mult (Pmode, size, align_rtx, NULL_RTX, 1);
@@ -1203,7 +1203,7 @@ align_dynamic_address (rtx target, unsigned required_align)
gen_int_mode (required_align / BITS_PER_UNIT - 1,
Pmode),
NULL_RTX, 1, OPTAB_LIB_WIDEN);
- target = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, target,
+ target = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, NULL, NULL, target,
gen_int_mode (required_align / BITS_PER_UNIT,
Pmode),
NULL_RTX, 1);
diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index 323565f..b12b0e0 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -4222,8 +4222,8 @@ expand_sdiv_pow2 (scalar_int_mode mode, rtx op0, HOST_WIDE_INT d)
rtx
expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
- rtx op0, rtx op1, rtx target, int unsignedp,
- enum optab_methods methods)
+ tree treeop0, tree treeop1, rtx op0, rtx op1, rtx target,
+ int unsignedp, enum optab_methods methods)
{
machine_mode compute_mode;
rtx tquotient;
@@ -4375,6 +4375,17 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
last_div_const = ! rem_flag && op1_is_constant ? INTVAL (op1) : 0;
+ /* Check if the target has specific expansions for the division. */
+ tree cst;
+ if (treeop0
+ && treeop1
+ && (cst = uniform_integer_cst_p (treeop1))
+ && targetm.vectorize.can_special_div_by_const (code, TREE_TYPE (treeop0),
+ wi::to_wide (cst),
+ &target, op0, op1))
+ return target;
+
+
/* Now convert to the best mode to use. */
if (compute_mode != mode)
{
@@ -4618,8 +4629,8 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
|| (optab_handler (sdivmod_optab, int_mode)
!= CODE_FOR_nothing)))
quotient = expand_divmod (0, TRUNC_DIV_EXPR,
- int_mode, op0,
- gen_int_mode (abs_d,
+ int_mode, treeop0, treeop1,
+ op0, gen_int_mode (abs_d,
int_mode),
NULL_RTX, 0);
else
@@ -4808,8 +4819,8 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
size - 1, NULL_RTX, 0);
t3 = force_operand (gen_rtx_MINUS (int_mode, t1, nsign),
NULL_RTX);
- t4 = expand_divmod (0, TRUNC_DIV_EXPR, int_mode, t3, op1,
- NULL_RTX, 0);
+ t4 = expand_divmod (0, TRUNC_DIV_EXPR, int_mode, treeop0,
+ treeop1, t3, op1, NULL_RTX, 0);
if (t4)
{
rtx t5;
diff --git a/gcc/expmed.h b/gcc/expmed.h
index f50f323..98fc5b7 100644
--- a/gcc/expmed.h
+++ b/gcc/expmed.h
@@ -710,8 +710,9 @@ extern rtx expand_shift (enum tree_code, machine_mode, rtx, poly_int64, rtx,
extern rtx maybe_expand_shift (enum tree_code, machine_mode, rtx, int, rtx,
int);
#ifdef GCC_OPTABS_H
-extern rtx expand_divmod (int, enum tree_code, machine_mode, rtx, rtx,
- rtx, int, enum optab_methods = OPTAB_LIB_WIDEN);
+extern rtx expand_divmod (int, enum tree_code, machine_mode, tree, tree,
+ rtx, rtx, rtx, int,
+ enum optab_methods = OPTAB_LIB_WIDEN);
#endif
#endif
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 9145193..d940743 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -2901,19 +2901,19 @@ emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED,
if (!REG_P (dst) || REGNO (dst) < FIRST_PSEUDO_REGISTER)
dst = gen_reg_rtx (outer);
- /* Make life a bit easier for combine. */
- /* If the first element of the vector is the low part
- of the destination mode, use a paradoxical subreg to
- initialize the destination. */
+ /* Make life a bit easier for combine: if the first element of the
+ vector is the word (or larger) low part of the destination mode,
+ use a paradoxical subreg to initialize the destination. */
if (start < finish)
{
inner = GET_MODE (tmps[start]);
bytepos = subreg_lowpart_offset (inner, outer);
- if (known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0, start), 1)),
- bytepos))
+ if (known_ge (GET_MODE_BITSIZE (inner), BITS_PER_WORD)
+ && known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0,
+ start), 1)),
+ bytepos))
{
- temp = simplify_gen_subreg (outer, tmps[start],
- inner, 0);
+ temp = simplify_gen_subreg (outer, tmps[start], inner, 0);
if (temp)
{
emit_move_insn (dst, temp);
@@ -2929,12 +2929,12 @@ emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED,
{
inner = GET_MODE (tmps[finish - 1]);
bytepos = subreg_lowpart_offset (inner, outer);
- if (known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0,
- finish - 1), 1)),
- bytepos))
+ if (known_ge (GET_MODE_BITSIZE (inner), BITS_PER_WORD)
+ && known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0,
+ finish - 1), 1)),
+ bytepos))
{
- temp = simplify_gen_subreg (outer, tmps[finish - 1],
- inner, 0);
+ temp = simplify_gen_subreg (outer, tmps[finish - 1], inner, 0);
if (temp)
{
emit_move_insn (dst, temp);
@@ -8204,16 +8204,17 @@ force_operand (rtx value, rtx target)
return expand_divmod (0,
FLOAT_MODE_P (GET_MODE (value))
? RDIV_EXPR : TRUNC_DIV_EXPR,
- GET_MODE (value), op1, op2, target, 0);
+ GET_MODE (value), NULL, NULL, op1, op2,
+ target, 0);
case MOD:
- return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
- target, 0);
+ return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), NULL, NULL,
+ op1, op2, target, 0);
case UDIV:
- return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), op1, op2,
- target, 1);
+ return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), NULL, NULL,
+ op1, op2, target, 1);
case UMOD:
- return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
- target, 1);
+ return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), NULL, NULL,
+ op1, op2, target, 1);
case ASHIFTRT:
return expand_simple_binop (GET_MODE (value), code, op1, op2,
target, 0, OPTAB_LIB_WIDEN);
@@ -9166,11 +9167,13 @@ expand_expr_divmod (tree_code code, machine_mode mode, tree treeop0,
bool speed_p = optimize_insn_for_speed_p ();
do_pending_stack_adjust ();
start_sequence ();
- rtx uns_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 1);
+ rtx uns_ret = expand_divmod (mod_p, code, mode, treeop0, treeop1,
+ op0, op1, target, 1);
rtx_insn *uns_insns = get_insns ();
end_sequence ();
start_sequence ();
- rtx sgn_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 0);
+ rtx sgn_ret = expand_divmod (mod_p, code, mode, treeop0, treeop1,
+ op0, op1, target, 0);
rtx_insn *sgn_insns = get_insns ();
end_sequence ();
unsigned uns_cost = seq_cost (uns_insns, speed_p);
@@ -9192,7 +9195,8 @@ expand_expr_divmod (tree_code code, machine_mode mode, tree treeop0,
emit_insn (sgn_insns);
return sgn_ret;
}
- return expand_divmod (mod_p, code, mode, op0, op1, target, unsignedp);
+ return expand_divmod (mod_p, code, mode, treeop0, treeop1,
+ op0, op1, target, unsignedp);
}
rtx
diff --git a/gcc/file-prefix-map.cc b/gcc/file-prefix-map.cc
index 24733f8..40b10ed 100644
--- a/gcc/file-prefix-map.cc
+++ b/gcc/file-prefix-map.cc
@@ -70,19 +70,29 @@ remap_filename (file_prefix_map *maps, const char *filename)
file_prefix_map *map;
char *s;
const char *name;
+ char *realname;
size_t name_len;
+ if (!filename || lbasename (filename) == filename)
+ return filename;
+
+ realname = lrealpath (filename);
+
for (map = maps; map; map = map->next)
- if (filename_ncmp (filename, map->old_prefix, map->old_len) == 0)
+ if (filename_ncmp (realname, map->old_prefix, map->old_len) == 0)
break;
if (!map)
- return filename;
- name = filename + map->old_len;
+ {
+ free (realname);
+ return filename;
+ }
+ name = realname + map->old_len;
name_len = strlen (name) + 1;
s = (char *) ggc_alloc_atomic (name_len + map->new_len);
memcpy (s, map->new_prefix, map->new_len);
memcpy (s + map->new_len, name, name_len);
+ free (realname);
return s;
}
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
index d2e7510..60dff0a 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -494,6 +494,15 @@ enum openacc_privatization
OPENACC_PRIVATIZATION_NOISY
};
+/* Targets for -fopenmp-target-simd-clone. */
+enum omp_target_simd_clone_device_kind
+{
+ OMP_TARGET_SIMD_CLONE_NONE = 0,
+ OMP_TARGET_SIMD_CLONE_HOST = 1,
+ OMP_TARGET_SIMD_CLONE_NOHOST = 2,
+ OMP_TARGET_SIMD_CLONE_ANY = 3
+};
+
#endif
#endif /* ! GCC_FLAG_TYPES_H */
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 7e1ea58..e4c43fb 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -3377,9 +3377,6 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1,
if (compare_address
&& (flags & OEP_ADDRESS_OF_SAME_FIELD) == 0)
{
- if (TREE_OPERAND (arg0, 2)
- || TREE_OPERAND (arg1, 2))
- return OP_SAME_WITH_NULL (2);
tree field0 = TREE_OPERAND (arg0, 1);
tree field1 = TREE_OPERAND (arg1, 1);
@@ -3890,17 +3887,10 @@ operand_compare::hash_operand (const_tree t, inchash::hash &hstate,
if (sflags & OEP_ADDRESS_OF)
{
hash_operand (TREE_OPERAND (t, 0), hstate, flags);
- if (TREE_OPERAND (t, 2))
- hash_operand (TREE_OPERAND (t, 2), hstate,
- flags & ~OEP_ADDRESS_OF);
- else
- {
- tree field = TREE_OPERAND (t, 1);
- hash_operand (DECL_FIELD_OFFSET (field),
- hstate, flags & ~OEP_ADDRESS_OF);
- hash_operand (DECL_FIELD_BIT_OFFSET (field),
- hstate, flags & ~OEP_ADDRESS_OF);
- }
+ hash_operand (DECL_FIELD_OFFSET (TREE_OPERAND (t, 1)),
+ hstate, flags & ~OEP_ADDRESS_OF);
+ hash_operand (DECL_FIELD_BIT_OFFSET (TREE_OPERAND (t, 1)),
+ hstate, flags & ~OEP_ADDRESS_OF);
return;
}
break;
@@ -9379,8 +9369,8 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
&& TREE_CODE (tem) == COND_EXPR
&& TREE_CODE (TREE_OPERAND (tem, 1)) == code
&& TREE_CODE (TREE_OPERAND (tem, 2)) == code
- && ! VOID_TYPE_P (TREE_OPERAND (tem, 1))
- && ! VOID_TYPE_P (TREE_OPERAND (tem, 2))
+ && ! VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (tem, 1)))
+ && ! VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (tem, 2)))
&& (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 1), 0))
== TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 2), 0)))
&& (! (INTEGRAL_TYPE_P (TREE_TYPE (tem))
@@ -10761,7 +10751,6 @@ tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
case COND_EXPR:
case CONSTRUCTOR:
case OBJ_TYPE_REF:
- case ASSERT_EXPR:
case ADDR_EXPR:
case WITH_SIZE_EXPR:
case SSA_NAME:
@@ -12628,10 +12617,6 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type,
: fold_convert_loc (loc, type, arg1);
return tem;
- case ASSERT_EXPR:
- /* An ASSERT_EXPR should never be passed to fold_binary. */
- gcc_unreachable ();
-
default:
return NULL_TREE;
} /* switch (code) */
@@ -15017,7 +15002,7 @@ tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p, int depth)
/* If the initializer is non-void, then it's a normal expression
that will be assigned to the slot. */
- if (!VOID_TYPE_P (t))
+ if (!VOID_TYPE_P (TREE_TYPE (t)))
return RECURSE (t);
/* Otherwise, the initializer sets the slot in some way. One common
@@ -15127,7 +15112,6 @@ tree_expr_nonnegative_warnv_p (tree t, bool *strict_overflow_p, int depth)
case COND_EXPR:
case CONSTRUCTOR:
case OBJ_TYPE_REF:
- case ASSERT_EXPR:
case ADDR_EXPR:
case WITH_SIZE_EXPR:
case SSA_NAME:
@@ -16360,6 +16344,11 @@ split_address_to_core_and_offset (tree exp,
poly_int64 bitsize;
location_t loc = EXPR_LOCATION (exp);
+ if (TREE_CODE (exp) == SSA_NAME)
+ if (gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (exp)))
+ if (gimple_assign_rhs_code (def) == ADDR_EXPR)
+ exp = gimple_assign_rhs1 (def);
+
if (TREE_CODE (exp) == ADDR_EXPR)
{
core = get_inner_reference (TREE_OPERAND (exp, 0), &bitsize, pbitpos,
@@ -16644,6 +16633,10 @@ address_compare (tree_code code, tree type, tree op0, tree op1,
tree &base0, tree &base1, poly_int64 &off0, poly_int64 &off1,
bool generic)
{
+ if (TREE_CODE (op0) == SSA_NAME)
+ op0 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op0));
+ if (TREE_CODE (op1) == SSA_NAME)
+ op1 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op1));
gcc_checking_assert (TREE_CODE (op0) == ADDR_EXPR);
gcc_checking_assert (TREE_CODE (op1) == ADDR_EXPR);
base0 = get_addr_base_and_unit_offset (TREE_OPERAND (op0, 0), &off0);
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 7b2d93b..4535398 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,2749 @@
+2022-12-12 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/102180
+ * array.cc (match_array_element_spec): Add check for bad
+ assumed-implied-spec.
+ (gfc_match_array_spec): Reorder logic so that the first bad array
+ element spec may trigger an error.
+
+2022-12-11 Steve Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/107995
+ * interface.cc (gfc_check_dummy_characteristics): Reject statement
+ function dummy arguments.
+
+2022-12-11 Tobias Burnus <tobias@codesourcery.com>
+
+ * openmp.cc (gfc_match_omp_context_selector_specification):
+ Remove spurious 's' in an error message.
+
+2022-12-10 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/106911
+ * simplify.cc (gfc_simplify_ishftc): If the SIZE argument is known
+ to be outside the allowed range, terminate simplification.
+
+2022-12-10 Tobias Burnus <tobias@codesourcery.com>
+
+ * match.cc (gfc_match_member_sep): Use %<...%> in gfc_error.
+ * openmp.cc (gfc_match_oacc_routine, gfc_match_omp_context_selector,
+ gfc_match_omp_context_selector_specification,
+ gfc_match_omp_declare_variant, resolve_omp_clauses): Likewise;
+ use %qs instead of '%s'.
+ * primary.cc (match_real_constant, gfc_match_varspec): Likewise.
+ * resolve.cc (gfc_resolve_formal_arglist, resolve_operator,
+ resolve_ordinary_assign): Likewise.
+
+2022-12-09 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/107872
+ * resolve.cc (derived_inaccessible): Skip over allocatable components
+ to prevent an infinite loop.
+
+2022-12-09 Tobias Burnus <tobias@codesourcery.com>
+
+ * dump-parse-tree.cc (show_omp_namelist): Improve OMP_LIST_ALLOCATE
+ output.
+ * gfortran.h (struct gfc_omp_namelist): Add 'align' to 'u'.
+ (gfc_free_omp_namelist): Add bool arg.
+ * match.cc (gfc_free_omp_namelist): Likewise; free 'u.align'.
+ * openmp.cc (gfc_free_omp_clauses, gfc_match_omp_clause_reduction,
+ gfc_match_omp_flush): Update call.
+ (gfc_match_omp_clauses): Match 'align/allocate modifers in
+ 'allocate' clause.
+ (resolve_omp_clauses): Resolve align.
+ * st.cc (gfc_free_statement): Update call
+ * trans-openmp.cc (gfc_trans_omp_clauses): Handle 'align'.
+
+2022-12-08 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/108025
+ * symbol.cc (gfc_add_contiguous): Diagnose and reject duplicate
+ CONTIGUOUS attribute.
+
+2022-12-07 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/108010
+ * arith.cc (reduce_unary): Handle zero-sized arrays.
+ (reduce_binary_aa): Likewise.
+
+2022-12-04 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107922
+ * simplify.cc (gfc_simplify_unpack): Terminate simplification when
+ array-valued argument FIELD does not provide enough elements.
+
+2022-12-04 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107870
+ * intrinsic.texi: Fix typo in documentation of intrinsic FLOOR.
+ Describe the optional KIND argument to intrinsics as a scalar
+ constant expression, in accordance with the current standard.
+
+2022-12-04 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107899
+ * resolve.cc (resolve_deallocate_expr): Avoid NULL pointer dereference
+ on invalid CLASS variable.
+
+2022-11-30 Martin Liska <mliska@suse.cz>
+
+ * parse.cc (parse_omp_structured_block): Remove extra semicolon.
+
+2022-11-29 Harald Anlauf <anlauf@gmx.de>
+ Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/107874
+ * simplify.cc (gfc_simplify_merge): When simplifying MERGE with a
+ constant scalar MASK, ensure that arguments TSOURCE and FSOURCE are
+ either constant or will be evaluated.
+ * trans-intrinsic.cc (gfc_conv_intrinsic_merge): Evaluate arguments
+ before generating conditional expression.
+
+2022-11-28 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107819
+ * trans-stmt.cc (gfc_conv_elemental_dependencies): In checking for
+ elemental dependencies, treat dummy argument with VALUE attribute
+ as implicitly having intent(in).
+
+2022-11-28 Tobias Burnus <tobias@codesourcery.com>
+
+ * openmp.cc (OMP_DO_CLAUSES, OMP_SCOPE_CLAUSES,
+ OMP_SECTIONS_CLAUSES): Add 'nowait'.
+ (OMP_SINGLE_CLAUSES): Add 'nowait' and 'copyprivate'.
+ (gfc_match_omp_distribute_parallel_do,
+ gfc_match_omp_distribute_parallel_do_simd,
+ gfc_match_omp_parallel_do,
+ gfc_match_omp_parallel_do_simd,
+ gfc_match_omp_parallel_sections,
+ gfc_match_omp_teams_distribute_parallel_do,
+ gfc_match_omp_teams_distribute_parallel_do_simd): Disallow 'nowait'.
+ (gfc_match_omp_workshare): Match 'nowait' clause.
+ (gfc_match_omp_end_single): Use clause matcher for 'nowait'.
+ (resolve_omp_clauses): Reject 'nowait' + 'copyprivate'.
+ * parse.cc (decode_omp_directive): Break too long line.
+ (parse_omp_do, parse_omp_structured_block): Diagnose duplicated
+ 'nowait' clause.
+
+2022-11-23 Steve Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/107577
+ * resolve.cc (find_array_spec): Choose appropriate locus either of
+ bad array reference or of non-array entity in error message.
+
+2022-11-18 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107576
+ * interface.cc (gfc_procedure_use): Reject NULL as actual argument
+ when there is no explicit procedure interface.
+
+2022-11-17 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
+
+ PR fortran/99884
+ * io.cc (check_open_constraints): Remove double spaces.
+
+2022-11-16 Steve Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/107707
+ * interface.cc (gfc_compare_actual_formal): Check that we actually
+ have integer values before asking gmp_* to use them.
+
+2022-11-16 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107681
+ * resolve.cc (resolve_fl_var_and_proc): Prevent NULL pointer
+ dereference with reference to bad CLASS variable.
+
+2022-11-16 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107680
+ * arith.cc (arith_power): Check that operands are properly converted
+ before attempting to simplify.
+
+2022-11-15 Lewis Hyatt <lhyatt@gmail.com>
+
+ * cpp.cc (gfc_cpp_init): Use special_fname_builtin () rather than a
+ hardcoded string (which was also incorrectly left untranslated
+ previously.)
+ * error.cc (gfc_diagnostic_build_locus_prefix): Likewise.
+ * f95-lang.cc (gfc_init): Likewise.
+
+2022-11-14 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107444
+ * trans-openmp.cc (gfc_omp_check_optional_argument): Adjust to change
+ of prefix of internal symbol for presence status to '.'.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * gfortran.texi: Port from Sphinx.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/gfc-internals/code-that-interacts-with-the-user.rst: New file.
+ * doc/gfc-internals/command-line-options.rst: New file.
+ * doc/gfc-internals/conf.py: New file.
+ * doc/gfc-internals/copyright.rst: New file.
+ * doc/gfc-internals/error-handling.rst: New file.
+ * doc/gfc-internals/frontend-data-structures.rst: New file.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages.rst: New file.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/accessing-declarations.rst:
+ New file.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/basic-data-structures.rst:
+ New file.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/converting-expressions-to-tree.rst:
+ New file.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/translating-statements.rst:
+ New file.
+ * doc/gfc-internals/gfccode.rst: New file.
+ * doc/gfc-internals/gfcexpr.rst: New file.
+ * doc/gfc-internals/gnu-free-documentation-license.rst: New file.
+ * doc/gfc-internals/index.rst: New file.
+ * doc/gfc-internals/indices-and-tables.rst: New file.
+ * doc/gfc-internals/internals-of-fortran-2003-oop-features.rst: New file.
+ * doc/gfc-internals/introduction.rst: New file.
+ * doc/gfc-internals/symbol-versioning.rst: New file.
+ * doc/gfc-internals/the-libgfortran-runtime-library.rst: New file.
+ * doc/gfc-internals/type-bound-operators.rst: New file.
+ * doc/gfc-internals/type-bound-procedures.rst: New file.
+ * doc/gfortran/about-gnu-fortran.rst: New file.
+ * doc/gfortran/coarray-programming.rst: New file.
+ * doc/gfortran/compiler-characteristics.rst: New file.
+ * doc/gfortran/compiler-characteristics/asynchronous-i-o.rst: New file.
+ * doc/gfortran/compiler-characteristics/data-consistency-and-durability.rst: New file.
+ * doc/gfortran/compiler-characteristics/evaluation-of-logical-expressions.rst: New file.
+ * doc/gfortran/compiler-characteristics/file-format-of-unformatted-sequential-files.rst:
+ New file.
+ * doc/gfortran/compiler-characteristics/file-operations-on-symbolic-links.rst: New file.
+ * doc/gfortran/compiler-characteristics/files-opened-without-an-explicit-action=-specifier.rst:
+ New file.
+ * doc/gfortran/compiler-characteristics/internal-representation-of-logical-variables.rst:
+ New file.
+ * doc/gfortran/compiler-characteristics/kind-type-parameters.rst: New file.
+ * doc/gfortran/compiler-characteristics/max-and-min-intrinsics-with-real-nan-arguments.rst:
+ New file.
+ * doc/gfortran/compiler-characteristics/thread-safety-of-the-runtime-library.rst: New file.
+ * doc/gfortran/conf.py: New file.
+ * doc/gfortran/contributing.rst: New file.
+ * doc/gfortran/contributors-to-gnu-fortran.rst: New file.
+ * doc/gfortran/copyright.rst: New file.
+ * doc/gfortran/extensions-implemented-in-gnu-fortran.rst: New file.
+ * doc/gfortran/extensions-not-implemented-in-gnu-fortran.rst: New file.
+ * doc/gfortran/extensions.rst: New file.
+ * doc/gfortran/function-abi-documentation.rst: New file.
+ * doc/gfortran/funding.rst: New file.
+ * doc/gfortran/general-public-license-3.rst: New file.
+ * doc/gfortran/gnu-fortran-and-gcc.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options/description.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options/enable-and-customize-preprocessing.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options/environment-variables-affecting-gfortran.rst:
+ New file.
+ * doc/gfortran/gnu-fortran-command-options/influencing-runtime-behavior.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options/influencing-the-linking-step.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options/option-summary.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options/options-controlling-fortran-dialect.rst:
+ New file.
+ * doc/gfortran/gnu-fortran-command-options/options-for-code-generation-conventions.rst:
+ New file.
+ * doc/gfortran/gnu-fortran-command-options/options-for-debugging-your-program-or-gnu-fortran.rst:
+ New file.
+ * doc/gfortran/gnu-fortran-command-options/options-for-directory-search.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options/options-for-interoperability-with-other-languages.rst:
+ New file.
+ * doc/gfortran/gnu-fortran-command-options/options-to-request-or-suppress-errors-and-warnings.rst:
+ New file.
+ * doc/gfortran/gnu-fortran-compiler-directives.rst: New file.
+ * doc/gfortran/gnu-free-documentation-license.rst: New file.
+ * doc/gfortran/index.rst: New file.
+ * doc/gfortran/indices-and-tables.rst: New file.
+ * doc/gfortran/interoperability-with-c.rst: New file.
+ * doc/gfortran/intrinsic-modules.rst: New file.
+ * doc/gfortran/intrinsic-modules/ieee-modules-ieeeexceptions-ieeearithmetic-and-ieeefeatures.rst:
+ New file.
+ * doc/gfortran/intrinsic-modules/isocbinding.rst: New file.
+ * doc/gfortran/intrinsic-modules/isofortranenv.rst: New file.
+ * doc/gfortran/intrinsic-modules/openacc-module-openacc.rst: New file.
+ * doc/gfortran/intrinsic-modules/openmp-modules-omplib-and-omplibkinds.rst: New file.
+ * doc/gfortran/intrinsic-procedures.rst: New file.
+ * doc/gfortran/intrinsic-procedures/abort.rst: New file.
+ * doc/gfortran/intrinsic-procedures/abs.rst: New file.
+ * doc/gfortran/intrinsic-procedures/access.rst: New file.
+ * doc/gfortran/intrinsic-procedures/achar.rst: New file.
+ * doc/gfortran/intrinsic-procedures/acos.rst: New file.
+ * doc/gfortran/intrinsic-procedures/acosd.rst: New file.
+ * doc/gfortran/intrinsic-procedures/acosh.rst: New file.
+ * doc/gfortran/intrinsic-procedures/adjustl.rst: New file.
+ * doc/gfortran/intrinsic-procedures/adjustr.rst: New file.
+ * doc/gfortran/intrinsic-procedures/aimag.rst: New file.
+ * doc/gfortran/intrinsic-procedures/aint.rst: New file.
+ * doc/gfortran/intrinsic-procedures/alarm.rst: New file.
+ * doc/gfortran/intrinsic-procedures/all.rst: New file.
+ * doc/gfortran/intrinsic-procedures/allocated.rst: New file.
+ * doc/gfortran/intrinsic-procedures/and.rst: New file.
+ * doc/gfortran/intrinsic-procedures/anint.rst: New file.
+ * doc/gfortran/intrinsic-procedures/any.rst: New file.
+ * doc/gfortran/intrinsic-procedures/asin.rst: New file.
+ * doc/gfortran/intrinsic-procedures/asind.rst: New file.
+ * doc/gfortran/intrinsic-procedures/asinh.rst: New file.
+ * doc/gfortran/intrinsic-procedures/associated.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atan.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atan2.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atan2d.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atanh.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicadd.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomiccas.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicdefine.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicfetchadd.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicfetchand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicfetchor.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicfetchxor.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicor.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicref.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicxor.rst: New file.
+ * doc/gfortran/intrinsic-procedures/backtrace.rst: New file.
+ * doc/gfortran/intrinsic-procedures/besselj0.rst: New file.
+ * doc/gfortran/intrinsic-procedures/besselj1.rst: New file.
+ * doc/gfortran/intrinsic-procedures/besseljn.rst: New file.
+ * doc/gfortran/intrinsic-procedures/bessely0.rst: New file.
+ * doc/gfortran/intrinsic-procedures/bessely1.rst: New file.
+ * doc/gfortran/intrinsic-procedures/besselyn.rst: New file.
+ * doc/gfortran/intrinsic-procedures/bge.rst: New file.
+ * doc/gfortran/intrinsic-procedures/bgt.rst: New file.
+ * doc/gfortran/intrinsic-procedures/bitsize.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ble.rst: New file.
+ * doc/gfortran/intrinsic-procedures/blt.rst: New file.
+ * doc/gfortran/intrinsic-procedures/btest.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cassociated.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ceiling.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cfpointer.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cfprocpointer.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cfunloc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/char.rst: New file.
+ * doc/gfortran/intrinsic-procedures/chdir.rst: New file.
+ * doc/gfortran/intrinsic-procedures/chmod.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cloc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cmplx.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cobroadcast.rst: New file.
+ * doc/gfortran/intrinsic-procedures/comax.rst: New file.
+ * doc/gfortran/intrinsic-procedures/comin.rst: New file.
+ * doc/gfortran/intrinsic-procedures/commandargumentcount.rst: New file.
+ * doc/gfortran/intrinsic-procedures/compileroptions.rst: New file.
+ * doc/gfortran/intrinsic-procedures/compilerversion.rst: New file.
+ * doc/gfortran/intrinsic-procedures/complex.rst: New file.
+ * doc/gfortran/intrinsic-procedures/conjg.rst: New file.
+ * doc/gfortran/intrinsic-procedures/coreduce.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cos.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cosd.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cosh.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cosum.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cotan.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cotand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/count.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cputime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cshift.rst: New file.
+ * doc/gfortran/intrinsic-procedures/csizeof.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ctime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dateandtime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dble.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dcmplx.rst: New file.
+ * doc/gfortran/intrinsic-procedures/digits.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dim.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dotproduct.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dprod.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dreal.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dshiftl.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dshiftr.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dtime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/eoshift.rst: New file.
+ * doc/gfortran/intrinsic-procedures/epsilon.rst: New file.
+ * doc/gfortran/intrinsic-procedures/erf.rst: New file.
+ * doc/gfortran/intrinsic-procedures/erfc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/erfcscaled.rst: New file.
+ * doc/gfortran/intrinsic-procedures/etime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/eventquery.rst: New file.
+ * doc/gfortran/intrinsic-procedures/executecommandline.rst: New file.
+ * doc/gfortran/intrinsic-procedures/exit.rst: New file.
+ * doc/gfortran/intrinsic-procedures/exp.rst: New file.
+ * doc/gfortran/intrinsic-procedures/exponent.rst: New file.
+ * doc/gfortran/intrinsic-procedures/extendstypeof.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fdate.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fget.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fgetc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/findloc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/floor.rst: New file.
+ * doc/gfortran/intrinsic-procedures/flush.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fnum.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fput.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fputc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fraction.rst: New file.
+ * doc/gfortran/intrinsic-procedures/free.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fseek.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fstat.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ftell.rst: New file.
+ * doc/gfortran/intrinsic-procedures/gamma.rst: New file.
+ * doc/gfortran/intrinsic-procedures/gerror.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getarg.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getcommand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getcommandargument.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getcwd.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getenv.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getenvironmentvariable.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getgid.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getlog.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getpid.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getuid.rst: New file.
+ * doc/gfortran/intrinsic-procedures/gmtime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/hostnm.rst: New file.
+ * doc/gfortran/intrinsic-procedures/huge.rst: New file.
+ * doc/gfortran/intrinsic-procedures/hypot.rst: New file.
+ * doc/gfortran/intrinsic-procedures/iachar.rst: New file.
+ * doc/gfortran/intrinsic-procedures/iall.rst: New file.
+ * doc/gfortran/intrinsic-procedures/iand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/iany.rst: New file.
+ * doc/gfortran/intrinsic-procedures/iargc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ibclr.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ibits.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ibset.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ichar.rst: New file.
+ * doc/gfortran/intrinsic-procedures/idate.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ieor.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ierrno.rst: New file.
+ * doc/gfortran/intrinsic-procedures/imageindex.rst: New file.
+ * doc/gfortran/intrinsic-procedures/index.rst: New file.
+ * doc/gfortran/intrinsic-procedures/int.rst: New file.
+ * doc/gfortran/intrinsic-procedures/int2.rst: New file.
+ * doc/gfortran/intrinsic-procedures/int8.rst: New file.
+ * doc/gfortran/intrinsic-procedures/introduction-to-intrinsic-procedures.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ior.rst: New file.
+ * doc/gfortran/intrinsic-procedures/iparity.rst: New file.
+ * doc/gfortran/intrinsic-procedures/irand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/isatty.rst: New file.
+ * doc/gfortran/intrinsic-procedures/iscontiguous.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ishft.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ishftc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/isiostatend.rst: New file.
+ * doc/gfortran/intrinsic-procedures/isiostateor.rst: New file.
+ * doc/gfortran/intrinsic-procedures/isnan.rst: New file.
+ * doc/gfortran/intrinsic-procedures/itime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/kill.rst: New file.
+ * doc/gfortran/intrinsic-procedures/kind.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lbound.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lcobound.rst: New file.
+ * doc/gfortran/intrinsic-procedures/leadz.rst: New file.
+ * doc/gfortran/intrinsic-procedures/len.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lentrim.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lge.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lgt.rst: New file.
+ * doc/gfortran/intrinsic-procedures/link.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lle.rst: New file.
+ * doc/gfortran/intrinsic-procedures/llt.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lnblnk.rst: New file.
+ * doc/gfortran/intrinsic-procedures/loc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/log.rst: New file.
+ * doc/gfortran/intrinsic-procedures/log10.rst: New file.
+ * doc/gfortran/intrinsic-procedures/loggamma.rst: New file.
+ * doc/gfortran/intrinsic-procedures/logical.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lshift.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lstat.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ltime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/malloc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/maskl.rst: New file.
+ * doc/gfortran/intrinsic-procedures/maskr.rst: New file.
+ * doc/gfortran/intrinsic-procedures/matmul.rst: New file.
+ * doc/gfortran/intrinsic-procedures/max.rst: New file.
+ * doc/gfortran/intrinsic-procedures/maxexponent.rst: New file.
+ * doc/gfortran/intrinsic-procedures/maxloc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/maxval.rst: New file.
+ * doc/gfortran/intrinsic-procedures/mclock.rst: New file.
+ * doc/gfortran/intrinsic-procedures/mclock8.rst: New file.
+ * doc/gfortran/intrinsic-procedures/merge.rst: New file.
+ * doc/gfortran/intrinsic-procedures/mergebits.rst: New file.
+ * doc/gfortran/intrinsic-procedures/min.rst: New file.
+ * doc/gfortran/intrinsic-procedures/minexponent.rst: New file.
+ * doc/gfortran/intrinsic-procedures/minloc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/minval.rst: New file.
+ * doc/gfortran/intrinsic-procedures/mod.rst: New file.
+ * doc/gfortran/intrinsic-procedures/modulo.rst: New file.
+ * doc/gfortran/intrinsic-procedures/movealloc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/mvbits.rst: New file.
+ * doc/gfortran/intrinsic-procedures/nearest.rst: New file.
+ * doc/gfortran/intrinsic-procedures/newline.rst: New file.
+ * doc/gfortran/intrinsic-procedures/nint.rst: New file.
+ * doc/gfortran/intrinsic-procedures/norm2.rst: New file.
+ * doc/gfortran/intrinsic-procedures/not.rst: New file.
+ * doc/gfortran/intrinsic-procedures/null.rst: New file.
+ * doc/gfortran/intrinsic-procedures/numimages.rst: New file.
+ * doc/gfortran/intrinsic-procedures/or.rst: New file.
+ * doc/gfortran/intrinsic-procedures/pack.rst: New file.
+ * doc/gfortran/intrinsic-procedures/parity.rst: New file.
+ * doc/gfortran/intrinsic-procedures/perror.rst: New file.
+ * doc/gfortran/intrinsic-procedures/popcnt.rst: New file.
+ * doc/gfortran/intrinsic-procedures/poppar.rst: New file.
+ * doc/gfortran/intrinsic-procedures/precision.rst: New file.
+ * doc/gfortran/intrinsic-procedures/present.rst: New file.
+ * doc/gfortran/intrinsic-procedures/product.rst: New file.
+ * doc/gfortran/intrinsic-procedures/radix.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ran.rst: New file.
+ * doc/gfortran/intrinsic-procedures/rand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/randominit.rst: New file.
+ * doc/gfortran/intrinsic-procedures/randomnumber.rst: New file.
+ * doc/gfortran/intrinsic-procedures/randomseed.rst: New file.
+ * doc/gfortran/intrinsic-procedures/range.rst: New file.
+ * doc/gfortran/intrinsic-procedures/rank.rst: New file.
+ * doc/gfortran/intrinsic-procedures/real.rst: New file.
+ * doc/gfortran/intrinsic-procedures/rename.rst: New file.
+ * doc/gfortran/intrinsic-procedures/repeat.rst: New file.
+ * doc/gfortran/intrinsic-procedures/reshape.rst: New file.
+ * doc/gfortran/intrinsic-procedures/rrspacing.rst: New file.
+ * doc/gfortran/intrinsic-procedures/rshift.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sametypeas.rst: New file.
+ * doc/gfortran/intrinsic-procedures/scale.rst: New file.
+ * doc/gfortran/intrinsic-procedures/scan.rst: New file.
+ * doc/gfortran/intrinsic-procedures/secnds.rst: New file.
+ * doc/gfortran/intrinsic-procedures/second.rst: New file.
+ * doc/gfortran/intrinsic-procedures/selectedcharkind.rst: New file.
+ * doc/gfortran/intrinsic-procedures/selectedintkind.rst: New file.
+ * doc/gfortran/intrinsic-procedures/selectedrealkind.rst: New file.
+ * doc/gfortran/intrinsic-procedures/setexponent.rst: New file.
+ * doc/gfortran/intrinsic-procedures/shape.rst: New file.
+ * doc/gfortran/intrinsic-procedures/shifta.rst: New file.
+ * doc/gfortran/intrinsic-procedures/shiftl.rst: New file.
+ * doc/gfortran/intrinsic-procedures/shiftr.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sign.rst: New file.
+ * doc/gfortran/intrinsic-procedures/signal.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sin.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sind.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sinh.rst: New file.
+ * doc/gfortran/intrinsic-procedures/size.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sizeof.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sleep.rst: New file.
+ * doc/gfortran/intrinsic-procedures/spacing.rst: New file.
+ * doc/gfortran/intrinsic-procedures/spread.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sqrt.rst: New file.
+ * doc/gfortran/intrinsic-procedures/srand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/stat.rst: New file.
+ * doc/gfortran/intrinsic-procedures/storagesize.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sum.rst: New file.
+ * doc/gfortran/intrinsic-procedures/symlnk.rst: New file.
+ * doc/gfortran/intrinsic-procedures/system.rst: New file.
+ * doc/gfortran/intrinsic-procedures/systemclock.rst: New file.
+ * doc/gfortran/intrinsic-procedures/tan.rst: New file.
+ * doc/gfortran/intrinsic-procedures/tand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/tanh.rst: New file.
+ * doc/gfortran/intrinsic-procedures/thisimage.rst: New file.
+ * doc/gfortran/intrinsic-procedures/time.rst: New file.
+ * doc/gfortran/intrinsic-procedures/time8.rst: New file.
+ * doc/gfortran/intrinsic-procedures/tiny.rst: New file.
+ * doc/gfortran/intrinsic-procedures/trailz.rst: New file.
+ * doc/gfortran/intrinsic-procedures/transfer.rst: New file.
+ * doc/gfortran/intrinsic-procedures/transpose.rst: New file.
+ * doc/gfortran/intrinsic-procedures/trim.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ttynam.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ubound.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ucobound.rst: New file.
+ * doc/gfortran/intrinsic-procedures/umask.rst: New file.
+ * doc/gfortran/intrinsic-procedures/unlink.rst: New file.
+ * doc/gfortran/intrinsic-procedures/unpack.rst: New file.
+ * doc/gfortran/intrinsic-procedures/verify.rst: New file.
+ * doc/gfortran/intrinsic-procedures/xor.rst: New file.
+ * doc/gfortran/introduction.rst: New file.
+ * doc/gfortran/mixed-language-programming.rst: New file.
+ * doc/gfortran/naming-and-argument-passing-conventions.rst: New file.
+ * doc/gfortran/non-fortran-main-program.rst: New file.
+ * doc/gfortran/projects.rst: New file.
+ * doc/gfortran/runtime.rst: New file.
+ * doc/gfortran/runtime/gfortranconvertunit.rst: New file.
+ * doc/gfortran/runtime/gfortranerrorbacktrace.rst: New file.
+ * doc/gfortran/runtime/gfortranformattedbuffersize.rst: New file.
+ * doc/gfortran/runtime/gfortranlistseparator.rst: New file.
+ * doc/gfortran/runtime/gfortranoptionalplus.rst: New file.
+ * doc/gfortran/runtime/gfortranshowlocus.rst: New file.
+ * doc/gfortran/runtime/gfortranstderrunit.rst: New file.
+ * doc/gfortran/runtime/gfortranstdinunit.rst: New file.
+ * doc/gfortran/runtime/gfortranstdoutunit.rst: New file.
+ * doc/gfortran/runtime/gfortranunbufferedall.rst: New file.
+ * doc/gfortran/runtime/gfortranunbufferedpreconnected.rst: New file.
+ * doc/gfortran/runtime/gfortranunformattedbuffersize.rst: New file.
+ * doc/gfortran/runtime/tmpdir.rst: New file.
+ * doc/gfortran/standards.rst: New file.
+ * doc/gfortran/type-and-enum-abi-documentation.rst: New file.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support Sphinx based documentation.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * gfc-internals.texi: Removed.
+ * gfortran.texi: Removed.
+ * intrinsic.texi: Removed.
+ * invoke.texi: Removed.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support --with-sphinx-build.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in:
+ Support installation if sphinx-build is missing.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gfortran/intrinsic-procedures/aint.rst: Simplify function
+ declaration.
+ * doc/gfortran/intrinsic-procedures/int.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/anint.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/char.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/real.rst: Likewise.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/gfc-internals/code-that-interacts-with-the-user.rst:
+ Add trailing newline.
+ * doc/gfc-internals/command-line-options.rst:
+ Add trailing newline.
+ * doc/gfc-internals/copyright.rst:
+ Add trailing newline.
+ * doc/gfc-internals/error-handling.rst:
+ Add trailing newline.
+ * doc/gfc-internals/frontend-data-structures.rst:
+ Add trailing newline.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages.rst:
+ Add trailing newline.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/accessing-declarations.rst:
+ Add trailing newline.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/basic-data-structures.rst:
+ Add trailing newline.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/converting-expressions-to-tree.rst:
+ Add trailing newline.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/translating-statements.rst:
+ Add trailing newline.
+ * doc/gfc-internals/gfccode.rst:
+ Add trailing newline.
+ * doc/gfc-internals/gfcexpr.rst:
+ Add trailing newline.
+ * doc/gfc-internals/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/gfc-internals/index.rst:
+ Add trailing newline.
+ * doc/gfc-internals/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/gfc-internals/internals-of-fortran-2003-oop-features.rst:
+ Add trailing newline.
+ * doc/gfc-internals/introduction.rst:
+ Add trailing newline.
+ * doc/gfc-internals/symbol-versioning.rst:
+ Add trailing newline.
+ * doc/gfc-internals/the-libgfortran-runtime-library.rst:
+ Add trailing newline.
+ * doc/gfc-internals/type-bound-operators.rst:
+ Add trailing newline.
+ * doc/gfc-internals/type-bound-procedures.rst:
+ Add trailing newline.
+ * doc/gfortran/about-gnu-fortran.rst:
+ Add trailing newline.
+ * doc/gfortran/coarray-programming.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/asynchronous-i-o.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/data-consistency-and-durability.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/evaluation-of-logical-expressions.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/file-format-of-unformatted-sequential-files.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/file-operations-on-symbolic-links.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/files-opened-without-an-explicit-action=-specifier.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/internal-representation-of-logical-variables.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/kind-type-parameters.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/max-and-min-intrinsics-with-real-nan-arguments.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/thread-safety-of-the-runtime-library.rst:
+ Add trailing newline.
+ * doc/gfortran/contributing.rst:
+ Add trailing newline.
+ * doc/gfortran/contributors-to-gnu-fortran.rst:
+ Add trailing newline.
+ * doc/gfortran/copyright.rst:
+ Add trailing newline.
+ * doc/gfortran/extensions-implemented-in-gnu-fortran.rst:
+ Add trailing newline.
+ * doc/gfortran/extensions-not-implemented-in-gnu-fortran.rst:
+ Add trailing newline.
+ * doc/gfortran/extensions.rst:
+ Add trailing newline.
+ * doc/gfortran/function-abi-documentation.rst:
+ Add trailing newline.
+ * doc/gfortran/funding.rst:
+ Add trailing newline.
+ * doc/gfortran/general-public-license-3.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-and-gcc.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/description.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/enable-and-customize-preprocessing.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/environment-variables-affecting-gfortran.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/influencing-runtime-behavior.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/influencing-the-linking-step.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/option-summary.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/options-controlling-fortran-dialect.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/options-for-code-generation-conventions.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/options-for-debugging-your-program-or-gnu-fortran.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/options-for-directory-search.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/options-for-interoperability-with-other-languages.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/options-to-request-or-suppress-errors-and-warnings.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-compiler-directives.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/gfortran/index.rst:
+ Add trailing newline.
+ * doc/gfortran/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/gfortran/interoperability-with-c.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-modules.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-modules/ieee-modules-ieeeexceptions-ieeearithmetic-and-ieeefeatures.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-modules/isocbinding.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-modules/isofortranenv.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-modules/openacc-module-openacc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-modules/openmp-modules-omplib-and-omplibkinds.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/abort.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/abs.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/access.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/achar.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/acos.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/acosd.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/acosh.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/adjustl.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/adjustr.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/aimag.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/alarm.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/all.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/allocated.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/and.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/any.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/asin.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/asind.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/asinh.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/associated.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atan.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atan2.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atan2d.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atanh.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicadd.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomiccas.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicdefine.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicfetchadd.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicfetchand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicfetchor.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicfetchxor.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicor.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicref.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicxor.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/backtrace.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/besselj0.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/besselj1.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/besseljn.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/bessely0.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/bessely1.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/besselyn.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/bge.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/bgt.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/bitsize.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ble.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/blt.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/btest.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cassociated.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ceiling.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cfpointer.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cfprocpointer.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cfunloc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/chdir.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/chmod.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cloc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cmplx.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cobroadcast.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/comax.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/comin.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/commandargumentcount.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/compileroptions.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/compilerversion.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/complex.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/conjg.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/coreduce.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cos.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cosd.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cosh.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cosum.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cotan.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cotand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/count.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cputime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cshift.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/csizeof.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ctime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dateandtime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dble.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dcmplx.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/digits.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dim.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dotproduct.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dprod.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dreal.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dshiftl.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dshiftr.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dtime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/eoshift.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/epsilon.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/erf.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/erfc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/erfcscaled.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/etime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/eventquery.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/executecommandline.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/exit.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/exp.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/exponent.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/extendstypeof.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fdate.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fget.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fgetc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/findloc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/floor.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/flush.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fnum.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fput.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fputc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fraction.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/free.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fseek.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fstat.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ftell.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/gamma.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/gerror.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getarg.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getcommand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getcommandargument.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getcwd.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getenv.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getenvironmentvariable.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getgid.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getlog.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getpid.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getuid.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/gmtime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/hostnm.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/huge.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/hypot.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/iachar.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/iall.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/iand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/iany.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/iargc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ibclr.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ibits.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ibset.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ichar.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/idate.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ieor.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ierrno.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/imageindex.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/index.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/int2.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/int8.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/introduction-to-intrinsic-procedures.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ior.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/iparity.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/irand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/isatty.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/iscontiguous.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ishft.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ishftc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/isiostatend.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/isiostateor.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/isnan.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/itime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/kill.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/kind.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lbound.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lcobound.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/leadz.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/len.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lentrim.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lge.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lgt.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/link.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lle.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/llt.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lnblnk.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/loc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/log.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/log10.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/loggamma.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/logical.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lshift.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lstat.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ltime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/malloc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/maskl.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/maskr.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/matmul.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/max.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/maxexponent.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/maxloc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/maxval.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/mclock.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/mclock8.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/merge.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/mergebits.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/min.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/minexponent.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/minloc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/minval.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/mod.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/modulo.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/movealloc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/mvbits.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/nearest.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/newline.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/nint.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/norm2.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/not.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/null.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/numimages.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/or.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/pack.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/parity.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/perror.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/popcnt.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/poppar.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/precision.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/present.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/product.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/radix.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ran.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/rand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/randominit.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/randomnumber.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/randomseed.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/range.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/rank.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/rename.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/repeat.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/reshape.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/rrspacing.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/rshift.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sametypeas.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/scale.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/scan.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/secnds.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/second.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/selectedcharkind.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/selectedintkind.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/selectedrealkind.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/setexponent.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/shape.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/shifta.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/shiftl.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/shiftr.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sign.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/signal.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sin.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sind.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sinh.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/size.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sizeof.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sleep.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/spacing.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/spread.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sqrt.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/srand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/stat.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/storagesize.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sum.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/symlnk.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/system.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/systemclock.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/tan.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/tand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/tanh.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/thisimage.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/time.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/time8.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/tiny.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/trailz.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/transfer.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/transpose.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/trim.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ttynam.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ubound.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ucobound.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/umask.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/unlink.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/unpack.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/verify.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/xor.rst:
+ Add trailing newline.
+ * doc/gfortran/introduction.rst:
+ Add trailing newline.
+ * doc/gfortran/mixed-language-programming.rst:
+ Add trailing newline.
+ * doc/gfortran/naming-and-argument-passing-conventions.rst:
+ Add trailing newline.
+ * doc/gfortran/non-fortran-main-program.rst:
+ Add trailing newline.
+ * doc/gfortran/projects.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranconvertunit.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranerrorbacktrace.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranformattedbuffersize.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranlistseparator.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranoptionalplus.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranshowlocus.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranstderrunit.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranstdinunit.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranstdoutunit.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranunbufferedall.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranunbufferedpreconnected.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranunformattedbuffersize.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/tmpdir.rst:
+ Add trailing newline.
+ * doc/gfortran/standards.rst:
+ Add trailing newline.
+ * doc/gfortran/type-and-enum-abi-documentation.rst:
+ Add trailing newline.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/gfc-internals/conf.py: Add newline at last line.
+ * doc/gfortran/conf.py: Add newline at last line.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-10 Martin Liska <mliska@suse.cz>
+
+ * doc/gfortran/intrinsic-procedures/abs.rst: Move label directly before title.
+ * doc/gfortran/intrinsic-procedures/acos.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/acosd.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/acosh.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/aimag.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/aint.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/anint.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/asin.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/asind.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/asinh.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/atan.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/atan2.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/atan2d.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/atand.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/atanh.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/besselj0.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/besselj1.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/besseljn.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/bessely0.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/bessely1.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/besselyn.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/btest.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/char.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/conjg.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/cos.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/cosd.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/cosh.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/cotan.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/cotand.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/dim.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/dprod.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/erf.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/erfc.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/exp.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/gamma.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/iand.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ibclr.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ibits.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ibset.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ichar.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ieor.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/index.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/int.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ior.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ishft.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ishftc.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/len.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/lge.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/lgt.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/lle.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/llt.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/log.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/log10.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/loggamma.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/max.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/min.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/mod.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/mvbits.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/nint.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/not.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/real.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/sign.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/sin.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/sind.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/sinh.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/sqrt.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/tan.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/tand.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/tanh.rst: Likewise.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/gfortran/naming-and-argument-passing-conventions.rst:
+ Revert.
+
+2022-11-13 José Rui Faustino de Sousa <jrfsousa@gmail.com>
+
+ PR fortran/94104
+ * interface.cc (gfc_compare_actual_formal): Improve error message
+ dependent on Fortran standard level.
+
+2021-11-06 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
+
+ * gfortran.h (gfc_check_include): Remove declaration.
+
+2022-11-12 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107444
+ * trans-decl.cc (create_function_arglist): Extend presence status
+ to all intrinsic types, and change prefix of internal symbol to '.'.
+ * trans-expr.cc (gfc_conv_expr_present): Align to changes in
+ create_function_arglist.
+ (gfc_conv_procedure_call): Fix generation of procedure arguments for
+ the case of character dummy arguments with optional+value attribute.
+ * trans-types.cc (gfc_get_function_type): Synchronize with changes
+ to create_function_arglist.
+ * doc/gfortran/naming-and-argument-passing-conventions.rst: Clarify
+ the gfortran argument passing conventions with regard to OPTIONAL
+ dummy arguments of intrinsic type.
+
+2022-11-10 Martin Liska <mliska@suse.cz>
+
+ * doc/gfortran/intrinsic-procedures/abs.rst: Move label directly before title.
+ * doc/gfortran/intrinsic-procedures/acos.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/acosd.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/acosh.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/aimag.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/aint.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/anint.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/asin.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/asind.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/asinh.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/atan.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/atan2.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/atan2d.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/atand.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/atanh.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/besselj0.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/besselj1.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/besseljn.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/bessely0.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/bessely1.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/besselyn.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/btest.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/char.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/conjg.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/cos.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/cosd.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/cosh.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/cotan.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/cotand.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/dim.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/dprod.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/erf.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/erfc.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/exp.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/gamma.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/iand.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ibclr.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ibits.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ibset.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ichar.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ieor.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/index.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/int.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ior.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ishft.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/ishftc.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/len.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/lge.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/lgt.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/lle.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/llt.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/log.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/log10.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/loggamma.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/max.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/min.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/mod.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/mvbits.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/nint.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/not.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/real.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/sign.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/sin.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/sind.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/sinh.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/sqrt.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/tan.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/tand.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/tanh.rst: Likewise.
+
+2022-11-10 Martin Liska <mliska@suse.cz>
+
+ * doc/gfc-internals/conf.py: Add newline at last line.
+ * doc/gfortran/conf.py: Add newline at last line.
+
+2022-11-09 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107559
+ * resolve.cc (resolve_equivalence): Avoid NULL pointer dereference
+ while emitting diagnostics for bad EQUIVALENCEs.
+
+2022-11-09 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107441
+ * trans-decl.cc (create_function_arglist): Adjust the ordering of
+ automatically generated hidden procedure arguments to match the
+ documented ABI for gfortran.
+ * trans-types.cc (gfc_get_function_type): Separate hidden parameters
+ so that the presence flag for optional+value arguments come before
+ string length, coarray token and offset, as required.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gfc-internals/code-that-interacts-with-the-user.rst:
+ Add trailing newline.
+ * doc/gfc-internals/command-line-options.rst:
+ Add trailing newline.
+ * doc/gfc-internals/copyright.rst:
+ Add trailing newline.
+ * doc/gfc-internals/error-handling.rst:
+ Add trailing newline.
+ * doc/gfc-internals/frontend-data-structures.rst:
+ Add trailing newline.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages.rst:
+ Add trailing newline.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/accessing-declarations.rst:
+ Add trailing newline.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/basic-data-structures.rst:
+ Add trailing newline.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/converting-expressions-to-tree.rst:
+ Add trailing newline.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/translating-statements.rst:
+ Add trailing newline.
+ * doc/gfc-internals/gfccode.rst:
+ Add trailing newline.
+ * doc/gfc-internals/gfcexpr.rst:
+ Add trailing newline.
+ * doc/gfc-internals/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/gfc-internals/index.rst:
+ Add trailing newline.
+ * doc/gfc-internals/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/gfc-internals/internals-of-fortran-2003-oop-features.rst:
+ Add trailing newline.
+ * doc/gfc-internals/introduction.rst:
+ Add trailing newline.
+ * doc/gfc-internals/symbol-versioning.rst:
+ Add trailing newline.
+ * doc/gfc-internals/the-libgfortran-runtime-library.rst:
+ Add trailing newline.
+ * doc/gfc-internals/type-bound-operators.rst:
+ Add trailing newline.
+ * doc/gfc-internals/type-bound-procedures.rst:
+ Add trailing newline.
+ * doc/gfortran/about-gnu-fortran.rst:
+ Add trailing newline.
+ * doc/gfortran/coarray-programming.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/asynchronous-i-o.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/data-consistency-and-durability.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/evaluation-of-logical-expressions.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/file-format-of-unformatted-sequential-files.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/file-operations-on-symbolic-links.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/files-opened-without-an-explicit-action=-specifier.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/internal-representation-of-logical-variables.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/kind-type-parameters.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/max-and-min-intrinsics-with-real-nan-arguments.rst:
+ Add trailing newline.
+ * doc/gfortran/compiler-characteristics/thread-safety-of-the-runtime-library.rst:
+ Add trailing newline.
+ * doc/gfortran/contributing.rst:
+ Add trailing newline.
+ * doc/gfortran/contributors-to-gnu-fortran.rst:
+ Add trailing newline.
+ * doc/gfortran/copyright.rst:
+ Add trailing newline.
+ * doc/gfortran/extensions-implemented-in-gnu-fortran.rst:
+ Add trailing newline.
+ * doc/gfortran/extensions-not-implemented-in-gnu-fortran.rst:
+ Add trailing newline.
+ * doc/gfortran/extensions.rst:
+ Add trailing newline.
+ * doc/gfortran/function-abi-documentation.rst:
+ Add trailing newline.
+ * doc/gfortran/funding.rst:
+ Add trailing newline.
+ * doc/gfortran/general-public-license-3.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-and-gcc.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/description.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/enable-and-customize-preprocessing.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/environment-variables-affecting-gfortran.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/influencing-runtime-behavior.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/influencing-the-linking-step.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/option-summary.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/options-controlling-fortran-dialect.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/options-for-code-generation-conventions.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/options-for-debugging-your-program-or-gnu-fortran.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/options-for-directory-search.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/options-for-interoperability-with-other-languages.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-command-options/options-to-request-or-suppress-errors-and-warnings.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-fortran-compiler-directives.rst:
+ Add trailing newline.
+ * doc/gfortran/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/gfortran/index.rst:
+ Add trailing newline.
+ * doc/gfortran/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/gfortran/interoperability-with-c.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-modules.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-modules/ieee-modules-ieeeexceptions-ieeearithmetic-and-ieeefeatures.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-modules/isocbinding.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-modules/isofortranenv.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-modules/openacc-module-openacc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-modules/openmp-modules-omplib-and-omplibkinds.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/abort.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/abs.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/access.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/achar.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/acos.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/acosd.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/acosh.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/adjustl.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/adjustr.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/aimag.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/alarm.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/all.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/allocated.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/and.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/any.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/asin.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/asind.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/asinh.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/associated.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atan.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atan2.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atan2d.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atanh.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicadd.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomiccas.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicdefine.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicfetchadd.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicfetchand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicfetchor.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicfetchxor.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicor.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicref.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/atomicxor.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/backtrace.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/besselj0.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/besselj1.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/besseljn.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/bessely0.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/bessely1.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/besselyn.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/bge.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/bgt.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/bitsize.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ble.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/blt.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/btest.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cassociated.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ceiling.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cfpointer.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cfprocpointer.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cfunloc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/chdir.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/chmod.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cloc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cmplx.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cobroadcast.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/comax.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/comin.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/commandargumentcount.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/compileroptions.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/compilerversion.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/complex.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/conjg.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/coreduce.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cos.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cosd.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cosh.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cosum.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cotan.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cotand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/count.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cputime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/cshift.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/csizeof.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ctime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dateandtime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dble.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dcmplx.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/digits.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dim.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dotproduct.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dprod.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dreal.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dshiftl.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dshiftr.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/dtime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/eoshift.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/epsilon.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/erf.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/erfc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/erfcscaled.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/etime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/eventquery.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/executecommandline.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/exit.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/exp.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/exponent.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/extendstypeof.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fdate.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fget.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fgetc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/findloc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/floor.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/flush.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fnum.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fput.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fputc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fraction.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/free.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fseek.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/fstat.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ftell.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/gamma.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/gerror.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getarg.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getcommand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getcommandargument.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getcwd.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getenv.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getenvironmentvariable.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getgid.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getlog.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getpid.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/getuid.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/gmtime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/hostnm.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/huge.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/hypot.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/iachar.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/iall.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/iand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/iany.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/iargc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ibclr.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ibits.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ibset.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ichar.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/idate.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ieor.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ierrno.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/imageindex.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/index.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/int2.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/int8.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/introduction-to-intrinsic-procedures.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ior.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/iparity.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/irand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/isatty.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/iscontiguous.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ishft.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ishftc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/isiostatend.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/isiostateor.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/isnan.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/itime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/kill.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/kind.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lbound.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lcobound.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/leadz.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/len.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lentrim.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lge.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lgt.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/link.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lle.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/llt.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lnblnk.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/loc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/log.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/log10.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/loggamma.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/logical.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lshift.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/lstat.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ltime.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/malloc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/maskl.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/maskr.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/matmul.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/max.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/maxexponent.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/maxloc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/maxval.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/mclock.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/mclock8.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/merge.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/mergebits.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/min.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/minexponent.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/minloc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/minval.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/mod.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/modulo.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/movealloc.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/mvbits.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/nearest.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/newline.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/nint.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/norm2.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/not.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/null.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/numimages.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/or.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/pack.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/parity.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/perror.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/popcnt.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/poppar.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/precision.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/present.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/product.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/radix.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ran.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/rand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/randominit.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/randomnumber.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/randomseed.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/range.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/rank.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/rename.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/repeat.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/reshape.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/rrspacing.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/rshift.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sametypeas.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/scale.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/scan.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/secnds.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/second.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/selectedcharkind.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/selectedintkind.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/selectedrealkind.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/setexponent.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/shape.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/shifta.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/shiftl.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/shiftr.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sign.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/signal.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sin.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sind.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sinh.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/size.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sizeof.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sleep.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/spacing.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/spread.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sqrt.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/srand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/stat.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/storagesize.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/sum.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/symlnk.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/system.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/systemclock.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/tan.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/tand.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/tanh.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/thisimage.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/time.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/time8.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/tiny.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/trailz.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/transfer.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/transpose.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/trim.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ttynam.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ubound.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/ucobound.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/umask.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/unlink.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/unpack.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/verify.rst:
+ Add trailing newline.
+ * doc/gfortran/intrinsic-procedures/xor.rst:
+ Add trailing newline.
+ * doc/gfortran/introduction.rst:
+ Add trailing newline.
+ * doc/gfortran/mixed-language-programming.rst:
+ Add trailing newline.
+ * doc/gfortran/naming-and-argument-passing-conventions.rst:
+ Add trailing newline.
+ * doc/gfortran/non-fortran-main-program.rst:
+ Add trailing newline.
+ * doc/gfortran/projects.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranconvertunit.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranerrorbacktrace.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranformattedbuffersize.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranlistseparator.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranoptionalplus.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranshowlocus.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranstderrunit.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranstdinunit.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranstdoutunit.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranunbufferedall.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranunbufferedpreconnected.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/gfortranunformattedbuffersize.rst:
+ Add trailing newline.
+ * doc/gfortran/runtime/tmpdir.rst:
+ Add trailing newline.
+ * doc/gfortran/standards.rst:
+ Add trailing newline.
+ * doc/gfortran/type-and-enum-abi-documentation.rst:
+ Add trailing newline.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gfortran/intrinsic-procedures/aint.rst: Simplify function
+ declaration.
+ * doc/gfortran/intrinsic-procedures/int.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/anint.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/char.rst: Likewise.
+ * doc/gfortran/intrinsic-procedures/real.rst: Likewise.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in:
+ Support installation if sphinx-build is missing.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support --with-sphinx-build.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * gfc-internals.texi: Removed.
+ * gfortran.texi: Removed.
+ * intrinsic.texi: Removed.
+ * invoke.texi: Removed.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support Sphinx based documentation.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/gfc-internals/code-that-interacts-with-the-user.rst: New file.
+ * doc/gfc-internals/command-line-options.rst: New file.
+ * doc/gfc-internals/conf.py: New file.
+ * doc/gfc-internals/copyright.rst: New file.
+ * doc/gfc-internals/error-handling.rst: New file.
+ * doc/gfc-internals/frontend-data-structures.rst: New file.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages.rst: New file.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/accessing-declarations.rst:
+ New file.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/basic-data-structures.rst:
+ New file.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/converting-expressions-to-tree.rst:
+ New file.
+ * doc/gfc-internals/generating-the-intermediate-language-for-later-stages/translating-statements.rst:
+ New file.
+ * doc/gfc-internals/gfccode.rst: New file.
+ * doc/gfc-internals/gfcexpr.rst: New file.
+ * doc/gfc-internals/gnu-free-documentation-license.rst: New file.
+ * doc/gfc-internals/index.rst: New file.
+ * doc/gfc-internals/indices-and-tables.rst: New file.
+ * doc/gfc-internals/internals-of-fortran-2003-oop-features.rst: New file.
+ * doc/gfc-internals/introduction.rst: New file.
+ * doc/gfc-internals/symbol-versioning.rst: New file.
+ * doc/gfc-internals/the-libgfortran-runtime-library.rst: New file.
+ * doc/gfc-internals/type-bound-operators.rst: New file.
+ * doc/gfc-internals/type-bound-procedures.rst: New file.
+ * doc/gfortran/about-gnu-fortran.rst: New file.
+ * doc/gfortran/coarray-programming.rst: New file.
+ * doc/gfortran/compiler-characteristics.rst: New file.
+ * doc/gfortran/compiler-characteristics/asynchronous-i-o.rst: New file.
+ * doc/gfortran/compiler-characteristics/data-consistency-and-durability.rst: New file.
+ * doc/gfortran/compiler-characteristics/evaluation-of-logical-expressions.rst: New file.
+ * doc/gfortran/compiler-characteristics/file-format-of-unformatted-sequential-files.rst:
+ New file.
+ * doc/gfortran/compiler-characteristics/file-operations-on-symbolic-links.rst: New file.
+ * doc/gfortran/compiler-characteristics/files-opened-without-an-explicit-action=-specifier.rst:
+ New file.
+ * doc/gfortran/compiler-characteristics/internal-representation-of-logical-variables.rst:
+ New file.
+ * doc/gfortran/compiler-characteristics/kind-type-parameters.rst: New file.
+ * doc/gfortran/compiler-characteristics/max-and-min-intrinsics-with-real-nan-arguments.rst:
+ New file.
+ * doc/gfortran/compiler-characteristics/thread-safety-of-the-runtime-library.rst: New file.
+ * doc/gfortran/conf.py: New file.
+ * doc/gfortran/contributing.rst: New file.
+ * doc/gfortran/contributors-to-gnu-fortran.rst: New file.
+ * doc/gfortran/copyright.rst: New file.
+ * doc/gfortran/extensions-implemented-in-gnu-fortran.rst: New file.
+ * doc/gfortran/extensions-not-implemented-in-gnu-fortran.rst: New file.
+ * doc/gfortran/extensions.rst: New file.
+ * doc/gfortran/function-abi-documentation.rst: New file.
+ * doc/gfortran/funding.rst: New file.
+ * doc/gfortran/general-public-license-3.rst: New file.
+ * doc/gfortran/gnu-fortran-and-gcc.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options/description.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options/enable-and-customize-preprocessing.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options/environment-variables-affecting-gfortran.rst:
+ New file.
+ * doc/gfortran/gnu-fortran-command-options/influencing-runtime-behavior.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options/influencing-the-linking-step.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options/option-summary.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options/options-controlling-fortran-dialect.rst:
+ New file.
+ * doc/gfortran/gnu-fortran-command-options/options-for-code-generation-conventions.rst:
+ New file.
+ * doc/gfortran/gnu-fortran-command-options/options-for-debugging-your-program-or-gnu-fortran.rst:
+ New file.
+ * doc/gfortran/gnu-fortran-command-options/options-for-directory-search.rst: New file.
+ * doc/gfortran/gnu-fortran-command-options/options-for-interoperability-with-other-languages.rst:
+ New file.
+ * doc/gfortran/gnu-fortran-command-options/options-to-request-or-suppress-errors-and-warnings.rst:
+ New file.
+ * doc/gfortran/gnu-fortran-compiler-directives.rst: New file.
+ * doc/gfortran/gnu-free-documentation-license.rst: New file.
+ * doc/gfortran/index.rst: New file.
+ * doc/gfortran/indices-and-tables.rst: New file.
+ * doc/gfortran/interoperability-with-c.rst: New file.
+ * doc/gfortran/intrinsic-modules.rst: New file.
+ * doc/gfortran/intrinsic-modules/ieee-modules-ieeeexceptions-ieeearithmetic-and-ieeefeatures.rst:
+ New file.
+ * doc/gfortran/intrinsic-modules/isocbinding.rst: New file.
+ * doc/gfortran/intrinsic-modules/isofortranenv.rst: New file.
+ * doc/gfortran/intrinsic-modules/openacc-module-openacc.rst: New file.
+ * doc/gfortran/intrinsic-modules/openmp-modules-omplib-and-omplibkinds.rst: New file.
+ * doc/gfortran/intrinsic-procedures.rst: New file.
+ * doc/gfortran/intrinsic-procedures/abort.rst: New file.
+ * doc/gfortran/intrinsic-procedures/abs.rst: New file.
+ * doc/gfortran/intrinsic-procedures/access.rst: New file.
+ * doc/gfortran/intrinsic-procedures/achar.rst: New file.
+ * doc/gfortran/intrinsic-procedures/acos.rst: New file.
+ * doc/gfortran/intrinsic-procedures/acosd.rst: New file.
+ * doc/gfortran/intrinsic-procedures/acosh.rst: New file.
+ * doc/gfortran/intrinsic-procedures/adjustl.rst: New file.
+ * doc/gfortran/intrinsic-procedures/adjustr.rst: New file.
+ * doc/gfortran/intrinsic-procedures/aimag.rst: New file.
+ * doc/gfortran/intrinsic-procedures/aint.rst: New file.
+ * doc/gfortran/intrinsic-procedures/alarm.rst: New file.
+ * doc/gfortran/intrinsic-procedures/all.rst: New file.
+ * doc/gfortran/intrinsic-procedures/allocated.rst: New file.
+ * doc/gfortran/intrinsic-procedures/and.rst: New file.
+ * doc/gfortran/intrinsic-procedures/anint.rst: New file.
+ * doc/gfortran/intrinsic-procedures/any.rst: New file.
+ * doc/gfortran/intrinsic-procedures/asin.rst: New file.
+ * doc/gfortran/intrinsic-procedures/asind.rst: New file.
+ * doc/gfortran/intrinsic-procedures/asinh.rst: New file.
+ * doc/gfortran/intrinsic-procedures/associated.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atan.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atan2.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atan2d.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atanh.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicadd.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomiccas.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicdefine.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicfetchadd.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicfetchand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicfetchor.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicfetchxor.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicor.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicref.rst: New file.
+ * doc/gfortran/intrinsic-procedures/atomicxor.rst: New file.
+ * doc/gfortran/intrinsic-procedures/backtrace.rst: New file.
+ * doc/gfortran/intrinsic-procedures/besselj0.rst: New file.
+ * doc/gfortran/intrinsic-procedures/besselj1.rst: New file.
+ * doc/gfortran/intrinsic-procedures/besseljn.rst: New file.
+ * doc/gfortran/intrinsic-procedures/bessely0.rst: New file.
+ * doc/gfortran/intrinsic-procedures/bessely1.rst: New file.
+ * doc/gfortran/intrinsic-procedures/besselyn.rst: New file.
+ * doc/gfortran/intrinsic-procedures/bge.rst: New file.
+ * doc/gfortran/intrinsic-procedures/bgt.rst: New file.
+ * doc/gfortran/intrinsic-procedures/bitsize.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ble.rst: New file.
+ * doc/gfortran/intrinsic-procedures/blt.rst: New file.
+ * doc/gfortran/intrinsic-procedures/btest.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cassociated.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ceiling.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cfpointer.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cfprocpointer.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cfunloc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/char.rst: New file.
+ * doc/gfortran/intrinsic-procedures/chdir.rst: New file.
+ * doc/gfortran/intrinsic-procedures/chmod.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cloc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cmplx.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cobroadcast.rst: New file.
+ * doc/gfortran/intrinsic-procedures/comax.rst: New file.
+ * doc/gfortran/intrinsic-procedures/comin.rst: New file.
+ * doc/gfortran/intrinsic-procedures/commandargumentcount.rst: New file.
+ * doc/gfortran/intrinsic-procedures/compileroptions.rst: New file.
+ * doc/gfortran/intrinsic-procedures/compilerversion.rst: New file.
+ * doc/gfortran/intrinsic-procedures/complex.rst: New file.
+ * doc/gfortran/intrinsic-procedures/conjg.rst: New file.
+ * doc/gfortran/intrinsic-procedures/coreduce.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cos.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cosd.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cosh.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cosum.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cotan.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cotand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/count.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cputime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/cshift.rst: New file.
+ * doc/gfortran/intrinsic-procedures/csizeof.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ctime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dateandtime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dble.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dcmplx.rst: New file.
+ * doc/gfortran/intrinsic-procedures/digits.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dim.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dotproduct.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dprod.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dreal.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dshiftl.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dshiftr.rst: New file.
+ * doc/gfortran/intrinsic-procedures/dtime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/eoshift.rst: New file.
+ * doc/gfortran/intrinsic-procedures/epsilon.rst: New file.
+ * doc/gfortran/intrinsic-procedures/erf.rst: New file.
+ * doc/gfortran/intrinsic-procedures/erfc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/erfcscaled.rst: New file.
+ * doc/gfortran/intrinsic-procedures/etime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/eventquery.rst: New file.
+ * doc/gfortran/intrinsic-procedures/executecommandline.rst: New file.
+ * doc/gfortran/intrinsic-procedures/exit.rst: New file.
+ * doc/gfortran/intrinsic-procedures/exp.rst: New file.
+ * doc/gfortran/intrinsic-procedures/exponent.rst: New file.
+ * doc/gfortran/intrinsic-procedures/extendstypeof.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fdate.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fget.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fgetc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/findloc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/floor.rst: New file.
+ * doc/gfortran/intrinsic-procedures/flush.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fnum.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fput.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fputc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fraction.rst: New file.
+ * doc/gfortran/intrinsic-procedures/free.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fseek.rst: New file.
+ * doc/gfortran/intrinsic-procedures/fstat.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ftell.rst: New file.
+ * doc/gfortran/intrinsic-procedures/gamma.rst: New file.
+ * doc/gfortran/intrinsic-procedures/gerror.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getarg.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getcommand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getcommandargument.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getcwd.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getenv.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getenvironmentvariable.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getgid.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getlog.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getpid.rst: New file.
+ * doc/gfortran/intrinsic-procedures/getuid.rst: New file.
+ * doc/gfortran/intrinsic-procedures/gmtime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/hostnm.rst: New file.
+ * doc/gfortran/intrinsic-procedures/huge.rst: New file.
+ * doc/gfortran/intrinsic-procedures/hypot.rst: New file.
+ * doc/gfortran/intrinsic-procedures/iachar.rst: New file.
+ * doc/gfortran/intrinsic-procedures/iall.rst: New file.
+ * doc/gfortran/intrinsic-procedures/iand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/iany.rst: New file.
+ * doc/gfortran/intrinsic-procedures/iargc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ibclr.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ibits.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ibset.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ichar.rst: New file.
+ * doc/gfortran/intrinsic-procedures/idate.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ieor.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ierrno.rst: New file.
+ * doc/gfortran/intrinsic-procedures/imageindex.rst: New file.
+ * doc/gfortran/intrinsic-procedures/index.rst: New file.
+ * doc/gfortran/intrinsic-procedures/int.rst: New file.
+ * doc/gfortran/intrinsic-procedures/int2.rst: New file.
+ * doc/gfortran/intrinsic-procedures/int8.rst: New file.
+ * doc/gfortran/intrinsic-procedures/introduction-to-intrinsic-procedures.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ior.rst: New file.
+ * doc/gfortran/intrinsic-procedures/iparity.rst: New file.
+ * doc/gfortran/intrinsic-procedures/irand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/isatty.rst: New file.
+ * doc/gfortran/intrinsic-procedures/iscontiguous.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ishft.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ishftc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/isiostatend.rst: New file.
+ * doc/gfortran/intrinsic-procedures/isiostateor.rst: New file.
+ * doc/gfortran/intrinsic-procedures/isnan.rst: New file.
+ * doc/gfortran/intrinsic-procedures/itime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/kill.rst: New file.
+ * doc/gfortran/intrinsic-procedures/kind.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lbound.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lcobound.rst: New file.
+ * doc/gfortran/intrinsic-procedures/leadz.rst: New file.
+ * doc/gfortran/intrinsic-procedures/len.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lentrim.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lge.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lgt.rst: New file.
+ * doc/gfortran/intrinsic-procedures/link.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lle.rst: New file.
+ * doc/gfortran/intrinsic-procedures/llt.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lnblnk.rst: New file.
+ * doc/gfortran/intrinsic-procedures/loc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/log.rst: New file.
+ * doc/gfortran/intrinsic-procedures/log10.rst: New file.
+ * doc/gfortran/intrinsic-procedures/loggamma.rst: New file.
+ * doc/gfortran/intrinsic-procedures/logical.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lshift.rst: New file.
+ * doc/gfortran/intrinsic-procedures/lstat.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ltime.rst: New file.
+ * doc/gfortran/intrinsic-procedures/malloc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/maskl.rst: New file.
+ * doc/gfortran/intrinsic-procedures/maskr.rst: New file.
+ * doc/gfortran/intrinsic-procedures/matmul.rst: New file.
+ * doc/gfortran/intrinsic-procedures/max.rst: New file.
+ * doc/gfortran/intrinsic-procedures/maxexponent.rst: New file.
+ * doc/gfortran/intrinsic-procedures/maxloc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/maxval.rst: New file.
+ * doc/gfortran/intrinsic-procedures/mclock.rst: New file.
+ * doc/gfortran/intrinsic-procedures/mclock8.rst: New file.
+ * doc/gfortran/intrinsic-procedures/merge.rst: New file.
+ * doc/gfortran/intrinsic-procedures/mergebits.rst: New file.
+ * doc/gfortran/intrinsic-procedures/min.rst: New file.
+ * doc/gfortran/intrinsic-procedures/minexponent.rst: New file.
+ * doc/gfortran/intrinsic-procedures/minloc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/minval.rst: New file.
+ * doc/gfortran/intrinsic-procedures/mod.rst: New file.
+ * doc/gfortran/intrinsic-procedures/modulo.rst: New file.
+ * doc/gfortran/intrinsic-procedures/movealloc.rst: New file.
+ * doc/gfortran/intrinsic-procedures/mvbits.rst: New file.
+ * doc/gfortran/intrinsic-procedures/nearest.rst: New file.
+ * doc/gfortran/intrinsic-procedures/newline.rst: New file.
+ * doc/gfortran/intrinsic-procedures/nint.rst: New file.
+ * doc/gfortran/intrinsic-procedures/norm2.rst: New file.
+ * doc/gfortran/intrinsic-procedures/not.rst: New file.
+ * doc/gfortran/intrinsic-procedures/null.rst: New file.
+ * doc/gfortran/intrinsic-procedures/numimages.rst: New file.
+ * doc/gfortran/intrinsic-procedures/or.rst: New file.
+ * doc/gfortran/intrinsic-procedures/pack.rst: New file.
+ * doc/gfortran/intrinsic-procedures/parity.rst: New file.
+ * doc/gfortran/intrinsic-procedures/perror.rst: New file.
+ * doc/gfortran/intrinsic-procedures/popcnt.rst: New file.
+ * doc/gfortran/intrinsic-procedures/poppar.rst: New file.
+ * doc/gfortran/intrinsic-procedures/precision.rst: New file.
+ * doc/gfortran/intrinsic-procedures/present.rst: New file.
+ * doc/gfortran/intrinsic-procedures/product.rst: New file.
+ * doc/gfortran/intrinsic-procedures/radix.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ran.rst: New file.
+ * doc/gfortran/intrinsic-procedures/rand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/randominit.rst: New file.
+ * doc/gfortran/intrinsic-procedures/randomnumber.rst: New file.
+ * doc/gfortran/intrinsic-procedures/randomseed.rst: New file.
+ * doc/gfortran/intrinsic-procedures/range.rst: New file.
+ * doc/gfortran/intrinsic-procedures/rank.rst: New file.
+ * doc/gfortran/intrinsic-procedures/real.rst: New file.
+ * doc/gfortran/intrinsic-procedures/rename.rst: New file.
+ * doc/gfortran/intrinsic-procedures/repeat.rst: New file.
+ * doc/gfortran/intrinsic-procedures/reshape.rst: New file.
+ * doc/gfortran/intrinsic-procedures/rrspacing.rst: New file.
+ * doc/gfortran/intrinsic-procedures/rshift.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sametypeas.rst: New file.
+ * doc/gfortran/intrinsic-procedures/scale.rst: New file.
+ * doc/gfortran/intrinsic-procedures/scan.rst: New file.
+ * doc/gfortran/intrinsic-procedures/secnds.rst: New file.
+ * doc/gfortran/intrinsic-procedures/second.rst: New file.
+ * doc/gfortran/intrinsic-procedures/selectedcharkind.rst: New file.
+ * doc/gfortran/intrinsic-procedures/selectedintkind.rst: New file.
+ * doc/gfortran/intrinsic-procedures/selectedrealkind.rst: New file.
+ * doc/gfortran/intrinsic-procedures/setexponent.rst: New file.
+ * doc/gfortran/intrinsic-procedures/shape.rst: New file.
+ * doc/gfortran/intrinsic-procedures/shifta.rst: New file.
+ * doc/gfortran/intrinsic-procedures/shiftl.rst: New file.
+ * doc/gfortran/intrinsic-procedures/shiftr.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sign.rst: New file.
+ * doc/gfortran/intrinsic-procedures/signal.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sin.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sind.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sinh.rst: New file.
+ * doc/gfortran/intrinsic-procedures/size.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sizeof.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sleep.rst: New file.
+ * doc/gfortran/intrinsic-procedures/spacing.rst: New file.
+ * doc/gfortran/intrinsic-procedures/spread.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sqrt.rst: New file.
+ * doc/gfortran/intrinsic-procedures/srand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/stat.rst: New file.
+ * doc/gfortran/intrinsic-procedures/storagesize.rst: New file.
+ * doc/gfortran/intrinsic-procedures/sum.rst: New file.
+ * doc/gfortran/intrinsic-procedures/symlnk.rst: New file.
+ * doc/gfortran/intrinsic-procedures/system.rst: New file.
+ * doc/gfortran/intrinsic-procedures/systemclock.rst: New file.
+ * doc/gfortran/intrinsic-procedures/tan.rst: New file.
+ * doc/gfortran/intrinsic-procedures/tand.rst: New file.
+ * doc/gfortran/intrinsic-procedures/tanh.rst: New file.
+ * doc/gfortran/intrinsic-procedures/thisimage.rst: New file.
+ * doc/gfortran/intrinsic-procedures/time.rst: New file.
+ * doc/gfortran/intrinsic-procedures/time8.rst: New file.
+ * doc/gfortran/intrinsic-procedures/tiny.rst: New file.
+ * doc/gfortran/intrinsic-procedures/trailz.rst: New file.
+ * doc/gfortran/intrinsic-procedures/transfer.rst: New file.
+ * doc/gfortran/intrinsic-procedures/transpose.rst: New file.
+ * doc/gfortran/intrinsic-procedures/trim.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ttynam.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ubound.rst: New file.
+ * doc/gfortran/intrinsic-procedures/ucobound.rst: New file.
+ * doc/gfortran/intrinsic-procedures/umask.rst: New file.
+ * doc/gfortran/intrinsic-procedures/unlink.rst: New file.
+ * doc/gfortran/intrinsic-procedures/unpack.rst: New file.
+ * doc/gfortran/intrinsic-procedures/verify.rst: New file.
+ * doc/gfortran/intrinsic-procedures/xor.rst: New file.
+ * doc/gfortran/introduction.rst: New file.
+ * doc/gfortran/mixed-language-programming.rst: New file.
+ * doc/gfortran/naming-and-argument-passing-conventions.rst: New file.
+ * doc/gfortran/non-fortran-main-program.rst: New file.
+ * doc/gfortran/projects.rst: New file.
+ * doc/gfortran/runtime.rst: New file.
+ * doc/gfortran/runtime/gfortranconvertunit.rst: New file.
+ * doc/gfortran/runtime/gfortranerrorbacktrace.rst: New file.
+ * doc/gfortran/runtime/gfortranformattedbuffersize.rst: New file.
+ * doc/gfortran/runtime/gfortranlistseparator.rst: New file.
+ * doc/gfortran/runtime/gfortranoptionalplus.rst: New file.
+ * doc/gfortran/runtime/gfortranshowlocus.rst: New file.
+ * doc/gfortran/runtime/gfortranstderrunit.rst: New file.
+ * doc/gfortran/runtime/gfortranstdinunit.rst: New file.
+ * doc/gfortran/runtime/gfortranstdoutunit.rst: New file.
+ * doc/gfortran/runtime/gfortranunbufferedall.rst: New file.
+ * doc/gfortran/runtime/gfortranunbufferedpreconnected.rst: New file.
+ * doc/gfortran/runtime/gfortranunformattedbuffersize.rst: New file.
+ * doc/gfortran/runtime/tmpdir.rst: New file.
+ * doc/gfortran/standards.rst: New file.
+ * doc/gfortran/type-and-enum-abi-documentation.rst: New file.
+
+2022-11-07 Tobias Burnus <tobias@codesourcery.com>
+
+ PR fortran/107508
+ * trans-array.cc (gfc_alloc_allocatable_for_assignment): Fix
+ string-length check, plug memory leak, and avoid generation of
+ effectively no-op code.
+ * trans-expr.cc (alloc_scalar_allocatable_for_assignment): Extend
+ comment; minor cleanup.
+
+2022-11-03 Tobias Burnus <tobias@codesourcery.com>
+
+ * openmp.cc (gfc_match_omp_clauses): Permit derived types for
+ the 'to' and 'from' clauses of 'target update'.
+ * trans-openmp.cc (gfc_trans_omp_clauses): Fixes for
+ derived-type changes; fix size for scalars.
+
2022-10-28 Joseph Myers <joseph@codesourcery.com>
* trans-types.cc (gfc_get_function_type): Do not use
@@ -150,7 +2896,7 @@
(gfc_match_omp_clauses): Call it; optionally use passed
omp_clauses argument.
(omp_verify_merge_absent_contains, gfc_match_omp_assume,
- gfc_match_omp_assumes, gfc_resolve_omp_assumptions): New.
+ gfc_match_omp_assumes, gfc_resolve_omp_assumptions): New.
(resolve_omp_clauses): Call the latter.
(gfc_resolve_omp_directive, omp_code_to_statement): Handle
EXEC_OMP_ASSUME.
diff --git a/gcc/fortran/arith.cc b/gcc/fortran/arith.cc
index fc9224eb..c0d12cf 100644
--- a/gcc/fortran/arith.cc
+++ b/gcc/fortran/arith.cc
@@ -845,6 +845,13 @@ arith_power (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp)
if (!gfc_numeric_ts (&op1->ts) || !gfc_numeric_ts (&op2->ts))
return ARITH_INVALID_TYPE;
+ /* The result type is derived from op1 and must be compatible with the
+ result of the simplification. Otherwise postpone simplification until
+ after operand conversions usually done by gfc_type_convert_binary. */
+ if ((op1->ts.type == BT_INTEGER && op2->ts.type != BT_INTEGER)
+ || (op1->ts.type == BT_REAL && op2->ts.type == BT_COMPLEX))
+ return ARITH_NOT_REDUCED;
+
rc = ARITH_OK;
result = gfc_get_constant_expr (op1->ts.type, op1->ts.kind, &op1->where);
@@ -1335,8 +1342,16 @@ reduce_unary (arith (*eval) (gfc_expr *, gfc_expr **), gfc_expr *op,
else
{
gfc_constructor *c = gfc_constructor_first (head);
- r = gfc_get_array_expr (c->expr->ts.type, c->expr->ts.kind,
- &op->where);
+ if (c == NULL)
+ {
+ /* Handle zero-sized arrays. */
+ r = gfc_get_array_expr (op->ts.type, op->ts.kind, &op->where);
+ }
+ else
+ {
+ r = gfc_get_array_expr (c->expr->ts.type, c->expr->ts.kind,
+ &op->where);
+ }
r->shape = gfc_copy_shape (op->shape, op->rank);
r->rank = op->rank;
r->value.constructor = head;
@@ -1494,8 +1509,16 @@ reduce_binary_aa (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **),
else
{
gfc_constructor *c = gfc_constructor_first (head);
- r = gfc_get_array_expr (c->expr->ts.type, c->expr->ts.kind,
- &op1->where);
+ if (c == NULL)
+ {
+ /* Handle zero-sized arrays. */
+ r = gfc_get_array_expr (op1->ts.type, op1->ts.kind, &op1->where);
+ }
+ else
+ {
+ r = gfc_get_array_expr (c->expr->ts.type, c->expr->ts.kind,
+ &op1->where);
+ }
r->shape = gfc_copy_shape (op1->shape, op1->rank);
r->rank = op1->rank;
r->value.constructor = head;
diff --git a/gcc/fortran/array.cc b/gcc/fortran/array.cc
index bbdb5b3..10d9e0c 100644
--- a/gcc/fortran/array.cc
+++ b/gcc/fortran/array.cc
@@ -489,7 +489,20 @@ match_array_element_spec (gfc_array_spec *as)
}
if (gfc_match_char (':') == MATCH_YES)
- return AS_DEFERRED;
+ {
+ locus old_loc = gfc_current_locus;
+ if (gfc_match_char ('*') == MATCH_YES)
+ {
+ /* F2018:R821: "assumed-implied-spec is [ lower-bound : ] *". */
+ gfc_error ("A lower bound must precede colon in "
+ "assumed-size array specification at %L", &old_loc);
+ return AS_UNKNOWN;
+ }
+ else
+ {
+ return AS_DEFERRED;
+ }
+ }
m = gfc_match_expr (upper);
if (m == MATCH_NO)
@@ -591,6 +604,8 @@ gfc_match_array_spec (gfc_array_spec **asp, bool match_dim, bool match_codim)
{
as->rank++;
current_type = match_array_element_spec (as);
+ if (current_type == AS_UNKNOWN)
+ goto cleanup;
/* Note that current_type == AS_ASSUMED_SIZE for both assumed-size
and implied-shape specifications. If the rank is at least 2, we can
@@ -600,8 +615,6 @@ gfc_match_array_spec (gfc_array_spec **asp, bool match_dim, bool match_codim)
if (as->rank == 1)
{
- if (current_type == AS_UNKNOWN)
- goto cleanup;
as->type = current_type;
}
else
diff --git a/gcc/fortran/cpp.cc b/gcc/fortran/cpp.cc
index 364bd0d..0b5755e 100644
--- a/gcc/fortran/cpp.cc
+++ b/gcc/fortran/cpp.cc
@@ -605,7 +605,7 @@ gfc_cpp_init (void)
if (gfc_option.flag_preprocessed)
return;
- cpp_change_file (cpp_in, LC_RENAME, _("<built-in>"));
+ cpp_change_file (cpp_in, LC_RENAME, special_fname_builtin ());
if (!gfc_cpp_option.no_predefined)
{
/* Make sure all of the builtins about to be declared have
diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc
index 2f042ab..5ae72dc 100644
--- a/gcc/fortran/dump-parse-tree.cc
+++ b/gcc/fortran/dump-parse-tree.cc
@@ -1357,6 +1357,29 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n)
}
ns_iter = n->u2.ns;
}
+ if (list_type == OMP_LIST_ALLOCATE)
+ {
+ if (n->expr)
+ {
+ fputs ("allocator(", dumpfile);
+ show_expr (n->expr);
+ fputc (')', dumpfile);
+ }
+ if (n->expr && n->u.align)
+ fputc (',', dumpfile);
+ if (n->u.align)
+ {
+ fputs ("allocator(", dumpfile);
+ show_expr (n->u.align);
+ fputc (')', dumpfile);
+ }
+ if (n->expr || n->u.align)
+ fputc (':', dumpfile);
+ fputs (n->sym->name, dumpfile);
+ if (n->next)
+ fputs (") ALLOCATE(", dumpfile);
+ continue;
+ }
if (list_type == OMP_LIST_REDUCTION)
switch (n->u.reduction_op)
{
diff --git a/gcc/fortran/error.cc b/gcc/fortran/error.cc
index c9d6edb..214fb78 100644
--- a/gcc/fortran/error.cc
+++ b/gcc/fortran/error.cc
@@ -1147,7 +1147,7 @@ gfc_diagnostic_build_locus_prefix (diagnostic_context *context,
const char *locus_ce = colorize_stop (pp_show_color (pp));
return (s.file == NULL
? build_message_string ("%s%s:%s", locus_cs, progname, locus_ce )
- : !strcmp (s.file, N_("<built-in>"))
+ : !strcmp (s.file, special_fname_builtin ())
? build_message_string ("%s%s:%s", locus_cs, s.file, locus_ce)
: context->show_column
? build_message_string ("%s%s:%d:%d:%s", locus_cs, s.file, s.line,
@@ -1167,7 +1167,7 @@ gfc_diagnostic_build_locus_prefix (diagnostic_context *context,
return (s.file == NULL
? build_message_string ("%s%s:%s", locus_cs, progname, locus_ce )
- : !strcmp (s.file, N_("<built-in>"))
+ : !strcmp (s.file, special_fname_builtin ())
? build_message_string ("%s%s:%s", locus_cs, s.file, locus_ce)
: context->show_column
? build_message_string ("%s%s:%d:%d-%d:%s", locus_cs, s.file, s.line,
diff --git a/gcc/fortran/f95-lang.cc b/gcc/fortran/f95-lang.cc
index a6750be..0d83f3f 100644
--- a/gcc/fortran/f95-lang.cc
+++ b/gcc/fortran/f95-lang.cc
@@ -259,7 +259,7 @@ gfc_init (void)
if (!gfc_cpp_enabled ())
{
linemap_add (line_table, LC_ENTER, false, gfc_source_file, 1);
- linemap_add (line_table, LC_RENAME, false, "<built-in>", 0);
+ linemap_add (line_table, LC_RENAME, false, special_fname_builtin (), 0);
}
else
gfc_cpp_init_0 ();
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 6bd8800..5f8a81a 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1349,6 +1349,7 @@ typedef struct gfc_omp_namelist
gfc_omp_reduction_op reduction_op;
gfc_omp_depend_doacross_op depend_doacross_op;
gfc_omp_map_op map_op;
+ gfc_expr *align;
struct
{
ENUM_BITFIELD (gfc_omp_linear_op) op:4;
@@ -3207,7 +3208,6 @@ int gfc_at_eof (void);
int gfc_at_bol (void);
int gfc_at_eol (void);
void gfc_advance_line (void);
-int gfc_check_include (void);
int gfc_define_undef_line (void);
int gfc_wide_is_printable (gfc_char_t);
@@ -3573,7 +3573,7 @@ void gfc_free_iterator (gfc_iterator *, int);
void gfc_free_forall_iterator (gfc_forall_iterator *);
void gfc_free_alloc_list (gfc_alloc *);
void gfc_free_namelist (gfc_namelist *);
-void gfc_free_omp_namelist (gfc_omp_namelist *, bool);
+void gfc_free_omp_namelist (gfc_omp_namelist *, bool, bool);
void gfc_free_equiv (gfc_equiv *);
void gfc_free_equiv_until (gfc_equiv *, gfc_equiv *);
void gfc_free_data (gfc_data *);
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 4b4ecd5..60fac2e 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -3763,8 +3763,7 @@ is used for dummy arguments; with @code{VALUE}, those variables are
passed by value.
For @code{OPTIONAL} dummy arguments, an absent argument is denoted
-by a NULL pointer, except for scalar dummy arguments of type
-@code{INTEGER}, @code{LOGICAL}, @code{REAL} and @code{COMPLEX}
+by a NULL pointer, except for scalar dummy arguments of intrinsic type
which have the @code{VALUE} attribute. For those, a hidden Boolean
argument (@code{logical(kind=C_bool),value}) is used to indicate
whether the argument is present.
diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index d3e1995..7d8eeda 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -1334,6 +1334,12 @@ gfc_check_dummy_characteristics (gfc_symbol *s1, gfc_symbol *s2,
if (s1 == NULL || s2 == NULL)
return s1 == s2 ? true : false;
+ if (s1->attr.proc == PROC_ST_FUNCTION || s2->attr.proc == PROC_ST_FUNCTION)
+ {
+ strncpy (errmsg, "Statement function", err_len);
+ return false;
+ }
+
/* Check type and rank. */
if (type_must_agree)
{
@@ -3273,9 +3279,11 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
if (a->expr->ts.type == BT_CHARACTER
&& a->expr->ts.u.cl && a->expr->ts.u.cl->length
&& a->expr->ts.u.cl->length->expr_type == EXPR_CONSTANT
+ && a->expr->ts.u.cl->length->ts.type == BT_INTEGER
&& f->sym->ts.type == BT_CHARACTER && f->sym->ts.u.cl
&& f->sym->ts.u.cl->length
&& f->sym->ts.u.cl->length->expr_type == EXPR_CONSTANT
+ && f->sym->ts.u.cl->length->ts.type == BT_INTEGER
&& (f->sym->attr.pointer || f->sym->attr.allocatable
|| (f->sym->as && f->sym->as->type == AS_ASSUMED_SHAPE))
&& (mpz_cmp (a->expr->ts.u.cl->length->value.integer,
@@ -3477,25 +3485,39 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
goto match;
}
- if (a->expr->expr_type != EXPR_NULL
- && compare_pointer (f->sym, a->expr) == 0)
+ if (a->expr->expr_type != EXPR_NULL)
{
- if (where)
- gfc_error ("Actual argument for %qs must be a pointer at %L",
- f->sym->name, &a->expr->where);
- ok = false;
- goto match;
- }
+ int cmp = compare_pointer (f->sym, a->expr);
+ bool pre2008 = ((gfc_option.allow_std & GFC_STD_F2008) == 0);
- if (a->expr->expr_type != EXPR_NULL
- && (gfc_option.allow_std & GFC_STD_F2008) == 0
- && compare_pointer (f->sym, a->expr) == 2)
- {
- if (where)
- gfc_error ("Fortran 2008: Non-pointer actual argument at %L to "
- "pointer dummy %qs", &a->expr->where,f->sym->name);
- ok = false;
- goto match;
+ if (pre2008 && cmp == 0)
+ {
+ if (where)
+ gfc_error ("Actual argument for %qs at %L must be a pointer",
+ f->sym->name, &a->expr->where);
+ ok = false;
+ goto match;
+ }
+
+ if (pre2008 && cmp == 2)
+ {
+ if (where)
+ gfc_error ("Fortran 2008: Non-pointer actual argument at %L to "
+ "pointer dummy %qs", &a->expr->where, f->sym->name);
+ ok = false;
+ goto match;
+ }
+
+ if (!pre2008 && cmp == 0)
+ {
+ if (where)
+ gfc_error ("Actual argument for %qs at %L must be a pointer "
+ "or a valid target for the dummy pointer in a "
+ "pointer assignment statement",
+ f->sym->name, &a->expr->where);
+ ok = false;
+ goto match;
+ }
}
@@ -4146,6 +4168,14 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where)
return false;
}
+ if (a->expr && a->expr->expr_type == EXPR_NULL)
+ {
+ gfc_error ("Passing intrinsic NULL as actual argument at %L "
+ "requires an explicit interface", &a->expr->where);
+ a->expr->error = 1;
+ return false;
+ }
+
/* TS 29113, C407b. */
if (a->expr && a->expr->expr_type == EXPR_VARIABLE
&& symbol_rank (a->expr->symtree->n.sym) == -1)
diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi
index 55f53fc..7af1ca3 100644
--- a/gcc/fortran/intrinsic.texi
+++ b/gcc/fortran/intrinsic.texi
@@ -553,7 +553,7 @@ Elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{I} @tab The type shall be @code{INTEGER}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -920,7 +920,7 @@ Elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{A} @tab The type of the argument shall be @code{REAL}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -1202,7 +1202,7 @@ Elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{A} @tab The type of the argument shall be @code{REAL}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -3406,7 +3406,7 @@ Elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{A} @tab The type shall be @code{REAL}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -3452,7 +3452,7 @@ Elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{I} @tab The type shall be @code{INTEGER}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -3636,7 +3636,7 @@ Elemental function
or @code{COMPLEX}.
@item @var{Y} @tab (Optional; only allowed if @var{X} is not
@code{COMPLEX}.) May be @code{INTEGER} or @code{REAL}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -4527,7 +4527,7 @@ Transformational function
@multitable @columnfractions .15 .70
@item @var{MASK} @tab The type shall be @code{LOGICAL}.
@item @var{DIM} @tab (Optional) The type shall be @code{INTEGER}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -6186,7 +6186,7 @@ conformance with @var{ARRAY}.
inclusive. It may not be an optional dummy argument.
@item @var{MASK} @tab (Optional) Shall be of type @code{LOGICAL},
and conformable with @var{ARRAY}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@item @var{BACK} @tab (Optional) A scalar of type @code{LOGICAL}.
@end multitable
@@ -6215,7 +6215,7 @@ is of default kind.
@table @asis
@item @emph{Description}:
-@code{FLOOR(A)} returns the greatest integer less than or equal to @var{X}.
+@code{FLOOR(A)} returns the greatest integer less than or equal to @var{A}.
@item @emph{Standard}:
Fortran 95 and later
@@ -6229,7 +6229,7 @@ Elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{A} @tab The type shall be @code{REAL}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -7550,7 +7550,7 @@ Elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{C} @tab Shall be a scalar @code{CHARACTER}, with @code{INTENT(IN)}
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -8007,7 +8007,7 @@ Elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{C} @tab Shall be a scalar @code{CHARACTER}, with @code{INTENT(IN)}
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -8279,7 +8279,7 @@ Elemental function
@code{INTENT(IN)}
@item @var{BACK} @tab (Optional) Shall be a scalar @code{LOGICAL}, with
@code{INTENT(IN)}
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -8324,7 +8324,7 @@ Elemental function
@multitable @columnfractions .15 .70
@item @var{A} @tab Shall be of type @code{INTEGER},
@code{REAL}, or @code{COMPLEX} or a boz-literal-constant.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -9109,7 +9109,7 @@ Inquiry function
@multitable @columnfractions .15 .70
@item @var{ARRAY} @tab Shall be an array, of any type.
@item @var{DIM} @tab (Optional) Shall be a scalar @code{INTEGER}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -9152,7 +9152,7 @@ Inquiry function
@multitable @columnfractions .15 .70
@item @var{ARRAY} @tab Shall be an coarray, of any type.
@item @var{DIM} @tab (Optional) Shall be a scalar @code{INTEGER}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -9239,7 +9239,7 @@ Inquiry function
@multitable @columnfractions .15 .70
@item @var{STRING} @tab Shall be a scalar or array of type
@code{CHARACTER}, with @code{INTENT(IN)}
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -9285,7 +9285,7 @@ Elemental function
@multitable @columnfractions .15 .70
@item @var{STRING} @tab Shall be a scalar of type @code{CHARACTER},
with @code{INTENT(IN)}
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -9823,7 +9823,7 @@ Elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{L} @tab The type shall be @code{LOGICAL}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -10312,7 +10312,7 @@ Transformational function
inclusive. It may not be an optional dummy argument.
@item @var{MASK} @tab Shall be of type @code{LOGICAL},
and conformable with @var{ARRAY}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@item @var{BACK} @tab (Optional) A scalar of type @code{LOGICAL}.
@end multitable
@@ -10679,7 +10679,7 @@ Transformational function
inclusive. It may not be an optional dummy argument.
@item @var{MASK} @tab Shall be of type @code{LOGICAL},
and conformable with @var{ARRAY}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@item @var{BACK} @tab (Optional) A scalar of type @code{LOGICAL}.
@end multitable
@@ -11111,7 +11111,7 @@ Elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{A} @tab The type of the argument shall be @code{REAL}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -12216,7 +12216,7 @@ Elemental function
@multitable @columnfractions .15 .70
@item @var{A} @tab Shall be @code{INTEGER}, @code{REAL}, or
@code{COMPLEX}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -12594,7 +12594,7 @@ Elemental function
@item @var{STRING} @tab Shall be of type @code{CHARACTER}.
@item @var{SET} @tab Shall be of type @code{CHARACTER}.
@item @var{BACK} @tab (Optional) shall be of type @code{LOGICAL}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -12956,7 +12956,7 @@ Inquiry function
@item @var{SOURCE} @tab Shall be an array or scalar of any type.
If @var{SOURCE} is a pointer it must be associated and allocatable
arrays must be allocated.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -13417,7 +13417,7 @@ a pointer it must be associated and allocatable arrays must be allocated.
@item @var{DIM} @tab (Optional) shall be a scalar of type @code{INTEGER}
and its value shall be in the range from 1 to n, where n equals the rank
of @var{ARRAY}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -14680,8 +14680,8 @@ Inquiry function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{ARRAY} @tab Shall be an array, of any type.
-@item @var{DIM} @tab (Optional) Shall be a scalar @code{INTEGER}.
-@item @var{KIND}@tab (Optional) An @code{INTEGER} initialization
+@item @var{DIM} @tab (Optional) Shall be a scalar @code{INTEGER}.
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -14725,7 +14725,7 @@ Inquiry function
@multitable @columnfractions .15 .70
@item @var{ARRAY} @tab Shall be an coarray, of any type.
@item @var{DIM} @tab (Optional) Shall be a scalar @code{INTEGER}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
@@ -14900,7 +14900,7 @@ Elemental function
@item @var{STRING} @tab Shall be of type @code{CHARACTER}.
@item @var{SET} @tab Shall be of type @code{CHARACTER}.
@item @var{BACK} @tab (Optional) shall be of type @code{LOGICAL}.
-@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
+@item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
expression indicating the kind parameter of the result.
@end multitable
diff --git a/gcc/fortran/io.cc b/gcc/fortran/io.cc
index 902aa19..b898fd3 100644
--- a/gcc/fortran/io.cc
+++ b/gcc/fortran/io.cc
@@ -2513,7 +2513,7 @@ check_open_constraints (gfc_open *open, locus *where)
spec = "";
}
- warn_or_error (G_("%s specifier at %L not allowed in OPEN statement for "
+ warn_or_error (G_("%sspecifier at %L not allowed in OPEN statement for "
"unformatted I/O"), spec, loc);
}
diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc
index 8b8b6e7..89fb115 100644
--- a/gcc/fortran/match.cc
+++ b/gcc/fortran/match.cc
@@ -193,7 +193,7 @@ gfc_match_member_sep(gfc_symbol *sym)
if (gfc_match_name (name) != MATCH_YES)
{
gfc_error ("Expected structure component or operator name "
- "after '.' at %C");
+ "after %<.%> at %C");
goto error;
}
@@ -5524,13 +5524,15 @@ gfc_free_namelist (gfc_namelist *name)
/* Free an OpenMP namelist structure. */
void
-gfc_free_omp_namelist (gfc_omp_namelist *name, bool free_ns)
+gfc_free_omp_namelist (gfc_omp_namelist *name, bool free_ns, bool free_align)
{
gfc_omp_namelist *n;
for (; name; name = n)
{
gfc_free_expr (name->expr);
+ if (free_align)
+ gfc_free_expr (name->u.align);
if (free_ns)
gfc_free_namespace (name->u2.ns);
else if (name->u2.udr)
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 653c43f..686f924 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -187,7 +187,8 @@ gfc_free_omp_clauses (gfc_omp_clauses *c)
gfc_free_expr (c->vector_length_expr);
for (i = 0; i < OMP_LIST_NUM; i++)
gfc_free_omp_namelist (c->lists[i],
- i == OMP_LIST_AFFINITY || i == OMP_LIST_DEPEND);
+ i == OMP_LIST_AFFINITY || i == OMP_LIST_DEPEND,
+ i == OMP_LIST_ALLOCATE);
gfc_free_expr_list (c->wait_list);
gfc_free_expr_list (c->tile_list);
free (CONST_CAST (char *, c->critical_name));
@@ -542,7 +543,7 @@ syntax:
gfc_error ("Syntax error in OpenMP variable list at %C");
cleanup:
- gfc_free_omp_namelist (head, false);
+ gfc_free_omp_namelist (head, false, false);
gfc_current_locus = old_loc;
return MATCH_ERROR;
}
@@ -632,7 +633,7 @@ syntax:
gfc_error ("Syntax error in OpenMP variable list at %C");
cleanup:
- gfc_free_omp_namelist (head, false);
+ gfc_free_omp_namelist (head, false, false);
gfc_current_locus = old_loc;
return MATCH_ERROR;
}
@@ -741,7 +742,7 @@ syntax:
gfc_error ("Syntax error in OpenMP SINK dependence-type list at %C");
cleanup:
- gfc_free_omp_namelist (head, false);
+ gfc_free_omp_namelist (head, false, false);
gfc_current_locus = old_loc;
return MATCH_ERROR;
}
@@ -1467,7 +1468,7 @@ gfc_match_omp_clause_reduction (char pc, gfc_omp_clauses *c, bool openacc,
*head = NULL;
gfc_error_now ("!$OMP DECLARE REDUCTION %s not found at %L",
buffer, &old_loc);
- gfc_free_omp_namelist (n, false);
+ gfc_free_omp_namelist (n, false, false);
}
else
for (n = *head; n; n = n->next)
@@ -1785,7 +1786,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
if (end_colon && gfc_match (" %e )", &alignment) != MATCH_YES)
{
- gfc_free_omp_namelist (*head, false);
+ gfc_free_omp_namelist (*head, false, false);
gfc_current_locus = old_loc;
*head = NULL;
break;
@@ -1853,17 +1854,33 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
&& gfc_match ("allocate ( ") == MATCH_YES)
{
gfc_expr *allocator = NULL;
+ gfc_expr *align = NULL;
old_loc = gfc_current_locus;
- m = gfc_match_expr (&allocator);
- if (m == MATCH_YES && gfc_match (" : ") != MATCH_YES)
+ if ((m = gfc_match ("allocator ( %e )", &allocator)) == MATCH_YES)
+ gfc_match (" , align ( %e )", &align);
+ else if ((m = gfc_match ("align ( %e )", &align)) == MATCH_YES)
+ gfc_match (" , allocator ( %e )", &allocator);
+
+ if (m == MATCH_YES)
{
- /* If no ":" then there is no allocator, we backtrack
- and read the variable list. */
- gfc_free_expr (allocator);
- allocator = NULL;
- gfc_current_locus = old_loc;
+ if (gfc_match (" : ") != MATCH_YES)
+ {
+ gfc_error ("Expected %<:%> at %C");
+ goto error;
+ }
+ }
+ else
+ {
+ m = gfc_match_expr (&allocator);
+ if (m == MATCH_YES && gfc_match (" : ") != MATCH_YES)
+ {
+ /* If no ":" then there is no allocator, we backtrack
+ and read the variable list. */
+ gfc_free_expr (allocator);
+ allocator = NULL;
+ gfc_current_locus = old_loc;
+ }
}
-
gfc_omp_namelist **head = NULL;
m = gfc_match_omp_variable_list ("", &c->lists[OMP_LIST_ALLOCATE],
true, NULL, &head);
@@ -1871,16 +1888,18 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
if (m != MATCH_YES)
{
gfc_free_expr (allocator);
+ gfc_free_expr (align);
gfc_error ("Expected variable list at %C");
goto error;
}
for (gfc_omp_namelist *n = *head; n; n = n->next)
- if (allocator)
- n->expr = gfc_copy_expr (allocator);
- else
- n->expr = NULL;
+ {
+ n->expr = (allocator) ? gfc_copy_expr (allocator) : NULL;
+ n->u.align = (align) ? gfc_copy_expr (align) : NULL;
+ }
gfc_free_expr (allocator);
+ gfc_free_expr (align);
continue;
}
if ((mask & OMP_CLAUSE_AT)
@@ -2499,9 +2518,10 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
true) == MATCH_YES)
continue;
if ((mask & OMP_CLAUSE_FROM)
- && gfc_match_omp_variable_list ("from (",
+ && (gfc_match_omp_variable_list ("from (",
&c->lists[OMP_LIST_FROM], false,
- NULL, &head, true) == MATCH_YES)
+ NULL, &head, true, true)
+ == MATCH_YES))
continue;
break;
case 'g':
@@ -2708,7 +2728,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
end_colon = true;
else if (gfc_match (" )") != MATCH_YES)
{
- gfc_free_omp_namelist (*head, false);
+ gfc_free_omp_namelist (*head, false, false);
gfc_current_locus = old_loc;
*head = NULL;
break;
@@ -2719,7 +2739,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
{
if (gfc_match (" %e )", &step) != MATCH_YES)
{
- gfc_free_omp_namelist (*head, false);
+ gfc_free_omp_namelist (*head, false, false);
gfc_current_locus = old_loc;
*head = NULL;
goto error;
@@ -2816,7 +2836,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
}
if (has_error)
{
- gfc_free_omp_namelist (*head, false);
+ gfc_free_omp_namelist (*head, false, false);
*head = NULL;
goto error;
}
@@ -3436,9 +3456,10 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
continue;
}
else if ((mask & OMP_CLAUSE_TO)
- && gfc_match_omp_variable_list ("to (",
+ && (gfc_match_omp_variable_list ("to (",
&c->lists[OMP_LIST_TO], false,
- NULL, &head, true) == MATCH_YES)
+ NULL, &head, true, true)
+ == MATCH_YES))
continue;
break;
case 'u':
@@ -4038,7 +4059,7 @@ gfc_match_oacc_routine (void)
if (gfc_match_char (')') != MATCH_YES)
{
gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, expecting"
- " ')' after NAME");
+ " %<)%> after NAME");
gfc_current_locus = old_loc;
return MATCH_ERROR;
}
@@ -4171,17 +4192,19 @@ cleanup:
(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
| OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
| OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE \
- | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER | OMP_CLAUSE_ALLOCATE)
+ | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER | OMP_CLAUSE_ALLOCATE \
+ | OMP_CLAUSE_NOWAIT)
#define OMP_LOOP_CLAUSES \
(omp_mask (OMP_CLAUSE_BIND) | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_ORDER \
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
#define OMP_SCOPE_CLAUSES \
(omp_mask (OMP_CLAUSE_PRIVATE) |OMP_CLAUSE_FIRSTPRIVATE \
- | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE)
+ | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
#define OMP_SECTIONS_CLAUSES \
(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
- | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE)
+ | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
+ | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
#define OMP_SIMD_CLAUSES \
(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE \
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN \
@@ -4231,7 +4254,7 @@ cleanup:
| OMP_CLAUSE_ORDER | OMP_CLAUSE_ALLOCATE)
#define OMP_SINGLE_CLAUSES \
(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
- | OMP_CLAUSE_ALLOCATE)
+ | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_COPYPRIVATE)
#define OMP_ORDERED_CLAUSES \
(omp_mask (OMP_CLAUSE_THREADS) | OMP_CLAUSE_SIMD)
#define OMP_DECLARE_TARGET_CLAUSES \
@@ -4245,7 +4268,8 @@ cleanup:
(omp_mask (OMP_CLAUSE_FILTER))
#define OMP_ERROR_CLAUSES \
(omp_mask (OMP_CLAUSE_AT) | OMP_CLAUSE_MESSAGE | OMP_CLAUSE_SEVERITY)
-
+#define OMP_WORKSHARE_CLAUSES \
+ omp_mask (OMP_CLAUSE_NOWAIT)
static match
@@ -4456,8 +4480,8 @@ gfc_match_omp_distribute_parallel_do (void)
return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO,
(OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES)
- & ~(omp_mask (OMP_CLAUSE_ORDERED))
- & ~(omp_mask (OMP_CLAUSE_LINEAR)));
+ & ~(omp_mask (OMP_CLAUSE_ORDERED)
+ | OMP_CLAUSE_LINEAR | OMP_CLAUSE_NOWAIT));
}
@@ -4467,7 +4491,7 @@ gfc_match_omp_distribute_parallel_do_simd (void)
return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD,
(OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES | OMP_SIMD_CLAUSES)
- & ~(omp_mask (OMP_CLAUSE_ORDERED)));
+ & ~(omp_mask (OMP_CLAUSE_ORDERED) | OMP_CLAUSE_NOWAIT));
}
@@ -4622,14 +4646,14 @@ gfc_match_omp_flush (void)
{
gfc_error ("List specified together with memory order clause in FLUSH "
"directive at %C");
- gfc_free_omp_namelist (list, false);
+ gfc_free_omp_namelist (list, false, false);
gfc_free_omp_clauses (c);
return MATCH_ERROR;
}
if (gfc_match_omp_eos () != MATCH_YES)
{
gfc_error ("Unexpected junk after $OMP FLUSH statement at %C");
- gfc_free_omp_namelist (list, false);
+ gfc_free_omp_namelist (list, false, false);
gfc_free_omp_clauses (c);
return MATCH_ERROR;
}
@@ -5324,8 +5348,8 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss)
}
else
{
- gfc_error ("selector '%s' not allowed for context selector "
- "set '%s' at %C",
+ gfc_error ("selector %qs not allowed for context selector "
+ "set %qs at %C",
selector, oss->trait_set_selector_name);
return MATCH_ERROR;
}
@@ -5344,7 +5368,7 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss)
{
if (property_kind == CTX_PROPERTY_NONE)
{
- gfc_error ("selector '%s' does not accept any properties at %C",
+ gfc_error ("selector %qs does not accept any properties at %C",
selector);
return MATCH_ERROR;
}
@@ -5353,7 +5377,7 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss)
{
if (gfc_match (" (") != MATCH_YES)
{
- gfc_error ("expected '(' at %C");
+ gfc_error ("expected %<(%> at %C");
return MATCH_ERROR;
}
if (gfc_match_expr (&os->score) != MATCH_YES
@@ -5375,7 +5399,7 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss)
if (gfc_match (" )") != MATCH_YES)
{
- gfc_error ("expected ')' at %C");
+ gfc_error ("expected %<)%> at %C");
return MATCH_ERROR;
}
@@ -5488,7 +5512,7 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss)
if (gfc_match (" )") != MATCH_YES)
{
- gfc_error ("expected ')' at %C");
+ gfc_error ("expected %<)%> at %C");
return MATCH_ERROR;
}
}
@@ -5498,7 +5522,7 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss)
{
if (gfc_match (" (") != MATCH_YES)
{
- gfc_error ("expected '(' at %C");
+ gfc_error ("expected %<(%> at %C");
return MATCH_ERROR;
}
}
@@ -5544,22 +5568,22 @@ gfc_match_omp_context_selector_specification (gfc_omp_declare_variant *odv)
if (m != MATCH_YES || i == selector_set_count)
{
- gfc_error ("expected 'construct', 'device', 'implementation' or "
- "'user' at %C");
+ gfc_error ("expected %<construct%>, %<device%>, %<implementation%> "
+ "or %<user%> at %C");
return MATCH_ERROR;
}
m = gfc_match (" =");
if (m != MATCH_YES)
{
- gfc_error ("expected '=' at %C");
+ gfc_error ("expected %<=%> at %C");
return MATCH_ERROR;
}
m = gfc_match (" {");
if (m != MATCH_YES)
{
- gfc_error ("expected '{' at %C");
+ gfc_error ("expected %<{%> at %C");
return MATCH_ERROR;
}
@@ -5574,7 +5598,7 @@ gfc_match_omp_context_selector_specification (gfc_omp_declare_variant *odv)
m = gfc_match (" }");
if (m != MATCH_YES)
{
- gfc_error ("expected '}' at %C");
+ gfc_error ("expected %<}%> at %C");
return MATCH_ERROR;
}
@@ -5596,7 +5620,7 @@ gfc_match_omp_declare_variant (void)
if (gfc_match (" (") != MATCH_YES)
{
- gfc_error ("expected '(' at %C");
+ gfc_error ("expected %<(%> at %C");
return MATCH_ERROR;
}
@@ -5644,7 +5668,7 @@ gfc_match_omp_declare_variant (void)
if (gfc_match (" )") != MATCH_YES)
{
- gfc_error ("expected ')' at %C");
+ gfc_error ("expected %<)%> at %C");
return MATCH_ERROR;
}
@@ -5654,7 +5678,7 @@ gfc_match_omp_declare_variant (void)
{
if (first_p)
{
- gfc_error ("expected 'match' at %C");
+ gfc_error ("expected %<match%> at %C");
return MATCH_ERROR;
}
else
@@ -5663,7 +5687,7 @@ gfc_match_omp_declare_variant (void)
if (gfc_match (" (") != MATCH_YES)
{
- gfc_error ("expected '(' at %C");
+ gfc_error ("expected %<(%> at %C");
return MATCH_ERROR;
}
@@ -5672,7 +5696,7 @@ gfc_match_omp_declare_variant (void)
if (gfc_match (" )") != MATCH_YES)
{
- gfc_error ("expected ')' at %C");
+ gfc_error ("expected %<)%> at %C");
return MATCH_ERROR;
}
@@ -5768,7 +5792,8 @@ match
gfc_match_omp_parallel_do (void)
{
return match_omp (EXEC_OMP_PARALLEL_DO,
- OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES);
+ (OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES)
+ & ~(omp_mask (OMP_CLAUSE_NOWAIT)));
}
@@ -5776,7 +5801,8 @@ match
gfc_match_omp_parallel_do_simd (void)
{
return match_omp (EXEC_OMP_PARALLEL_DO_SIMD,
- OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES);
+ (OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES)
+ & ~(omp_mask (OMP_CLAUSE_NOWAIT)));
}
@@ -5832,7 +5858,8 @@ match
gfc_match_omp_parallel_sections (void)
{
return match_omp (EXEC_OMP_PARALLEL_SECTIONS,
- OMP_PARALLEL_CLAUSES | OMP_SECTIONS_CLAUSES);
+ (OMP_PARALLEL_CLAUSES | OMP_SECTIONS_CLAUSES)
+ & ~(omp_mask (OMP_CLAUSE_NOWAIT)));
}
@@ -6318,8 +6345,8 @@ gfc_match_omp_teams_distribute_parallel_do (void)
return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO,
(OMP_TEAMS_CLAUSES | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES)
- & ~(omp_mask (OMP_CLAUSE_ORDERED))
- & ~(omp_mask (OMP_CLAUSE_LINEAR)));
+ & ~(omp_mask (OMP_CLAUSE_ORDERED)
+ | OMP_CLAUSE_LINEAR | OMP_CLAUSE_NOWAIT));
}
@@ -6329,7 +6356,8 @@ gfc_match_omp_teams_distribute_parallel_do_simd (void)
return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
(OMP_TEAMS_CLAUSES | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES
- | OMP_SIMD_CLAUSES) & ~(omp_mask (OMP_CLAUSE_ORDERED)));
+ | OMP_SIMD_CLAUSES)
+ & ~(omp_mask (OMP_CLAUSE_ORDERED) | OMP_CLAUSE_NOWAIT));
}
@@ -6345,14 +6373,7 @@ gfc_match_omp_teams_distribute_simd (void)
match
gfc_match_omp_workshare (void)
{
- if (gfc_match_omp_eos () != MATCH_YES)
- {
- gfc_error ("Unexpected junk after $OMP WORKSHARE statement at %C");
- return MATCH_ERROR;
- }
- new_st.op = EXEC_OMP_WORKSHARE;
- new_st.ext.omp_clauses = gfc_get_omp_clauses ();
- return MATCH_YES;
+ return match_omp (EXEC_OMP_WORKSHARE, OMP_WORKSHARE_CLAUSES);
}
@@ -6656,14 +6677,8 @@ match
gfc_match_omp_end_single (void)
{
gfc_omp_clauses *c;
- if (gfc_match ("% nowait") == MATCH_YES)
- {
- new_st.op = EXEC_OMP_END_NOWAIT;
- new_st.ext.omp_bool = true;
- return MATCH_YES;
- }
- if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_COPYPRIVATE))
- != MATCH_YES)
+ if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_COPYPRIVATE)
+ | OMP_CLAUSE_NOWAIT) != MATCH_YES)
return MATCH_ERROR;
new_st.op = EXEC_OMP_END_SINGLE;
new_st.ext.omp_clauses = c;
@@ -7283,19 +7298,36 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
if (omp_clauses->lists[OMP_LIST_ALLOCATE])
{
for (n = omp_clauses->lists[OMP_LIST_ALLOCATE]; n; n = n->next)
- if (n->expr && (n->expr->ts.type != BT_INTEGER
- || n->expr->ts.kind != gfc_c_intptr_kind))
- {
- gfc_error ("Expected integer expression of the "
- "'omp_allocator_handle_kind' kind at %L",
- &n->expr->where);
- break;
- }
+ {
+ if (n->expr && (!gfc_resolve_expr (n->expr)
+ || n->expr->ts.type != BT_INTEGER
+ || n->expr->ts.kind != gfc_c_intptr_kind))
+ {
+ gfc_error ("Expected integer expression of the "
+ "%<omp_allocator_handle_kind%> kind at %L",
+ &n->expr->where);
+ break;
+ }
+ if (!n->u.align)
+ continue;
+ int alignment = 0;
+ if (!gfc_resolve_expr (n->u.align)
+ || n->u.align->ts.type != BT_INTEGER
+ || n->u.align->rank != 0
+ || gfc_extract_int (n->u.align, &alignment)
+ || alignment <= 0)
+ {
+ gfc_error ("ALIGN modifier requires a scalar positive "
+ "constant integer alignment expression at %L",
+ &n->u.align->where);
+ break;
+ }
+ }
/* Check for 2 things here.
- 1. There is no duplication of variable in allocate clause.
- 2. Variable in allocate clause are also present in some
- privatization clase (non-composite case). */
+ 1. There is no duplication of variable in allocate clause.
+ 2. Variable in allocate clause are also present in some
+ privatization clase (non-composite case). */
for (n = omp_clauses->lists[OMP_LIST_ALLOCATE]; n; n = n->next)
n->sym->mark = 0;
@@ -7312,7 +7344,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
{
prev->next = n->next;
n->next = NULL;
- gfc_free_omp_namelist (n, 0);
+ gfc_free_omp_namelist (n, false, true);
n = prev->next;
}
continue;
@@ -7346,7 +7378,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
for (n = omp_clauses->lists[OMP_LIST_ALLOCATE]; n; n = n->next)
if (n->sym->mark == 1)
- gfc_error ("%qs specified in 'allocate' clause at %L but not "
+ gfc_error ("%qs specified in %<allocate%> clause at %L but not "
"in an explicit privatization clause",
n->sym->name, &n->where);
}
@@ -7404,6 +7436,9 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
}
break;
case OMP_LIST_COPYPRIVATE:
+ if (omp_clauses->nowait)
+ gfc_error ("NOWAIT clause must not be used with COPYPRIVATE "
+ "clause at %L", &n->where);
for (; n != NULL; n = n->next)
{
if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc
index f04fd13..cdae43f 100644
--- a/gcc/fortran/parse.cc
+++ b/gcc/fortran/parse.cc
@@ -942,7 +942,8 @@ decode_omp_directive (void)
matchs ("end ordered", gfc_match_omp_eos_error, ST_OMP_END_ORDERED);
matchs ("end parallel do simd", gfc_match_omp_eos_error,
ST_OMP_END_PARALLEL_DO_SIMD);
- matcho ("end parallel do", gfc_match_omp_eos_error, ST_OMP_END_PARALLEL_DO);
+ matcho ("end parallel do", gfc_match_omp_eos_error,
+ ST_OMP_END_PARALLEL_DO);
matcho ("end parallel loop", gfc_match_omp_eos_error,
ST_OMP_END_PARALLEL_LOOP);
matcho ("end parallel masked taskloop simd", gfc_match_omp_eos_error,
@@ -5305,7 +5306,13 @@ parse_omp_do (gfc_statement omp_st)
if (st == omp_end_st)
{
if (new_st.op == EXEC_OMP_END_NOWAIT)
- cp->ext.omp_clauses->nowait |= new_st.ext.omp_bool;
+ {
+ if (cp->ext.omp_clauses->nowait && new_st.ext.omp_bool)
+ gfc_error_now ("Duplicated NOWAIT clause on %s and %s at %C",
+ gfc_ascii_statement (omp_st),
+ gfc_ascii_statement (omp_end_st));
+ cp->ext.omp_clauses->nowait |= new_st.ext.omp_bool;
+ }
else
gcc_assert (new_st.op == EXEC_NOP);
gfc_clear_new_st ();
@@ -5745,6 +5752,10 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only)
switch (new_st.op)
{
case EXEC_OMP_END_NOWAIT:
+ if (cp->ext.omp_clauses->nowait && new_st.ext.omp_bool)
+ gfc_error_now ("Duplicated NOWAIT clause on %s and %s at %C",
+ gfc_ascii_statement (omp_st),
+ gfc_ascii_statement (omp_end_st));
cp->ext.omp_clauses->nowait |= new_st.ext.omp_bool;
break;
case EXEC_OMP_END_CRITICAL:
@@ -5759,8 +5770,22 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only)
new_st.ext.omp_name = NULL;
break;
case EXEC_OMP_END_SINGLE:
- cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]
- = new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE];
+ if (cp->ext.omp_clauses->nowait && new_st.ext.omp_clauses->nowait)
+ gfc_error_now ("Duplicated NOWAIT clause on %s and %s at %C",
+ gfc_ascii_statement (omp_st),
+ gfc_ascii_statement (omp_end_st));
+ cp->ext.omp_clauses->nowait |= new_st.ext.omp_clauses->nowait;
+ if (cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE])
+ {
+ gfc_omp_namelist *nl;
+ for (nl = cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE];
+ nl->next; nl = nl->next)
+ ;
+ nl->next = new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE];
+ }
+ else
+ cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]
+ = new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE];
new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE] = NULL;
gfc_free_omp_clauses (new_st.ext.omp_clauses);
break;
diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 19f2e78..21a8eb7 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -586,7 +586,7 @@ match_real_constant (gfc_expr **result, int signflag)
if (c == 'q')
{
- if (!gfc_notify_std (GFC_STD_GNU, "exponent-letter 'q' in "
+ if (!gfc_notify_std (GFC_STD_GNU, "exponent-letter %<q%> in "
"real-literal-constant at %C"))
return MATCH_ERROR;
else if (warn_real_q_constant)
@@ -2070,8 +2070,8 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
|| (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
&& CLASS_DATA (sym)->attr.dimension))
{
- gfc_error ("Array section designator, e.g. '(:)', is required "
- "besides the coarray designator '[...]' at %C");
+ gfc_error ("Array section designator, e.g. %<(:)%>, is required "
+ "besides the coarray designator %<[...]%> at %C");
return MATCH_ERROR;
}
if ((sym->ts.type != BT_CLASS && !sym->attr.codimension)
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 9202e2f..0f5f1d2 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -514,7 +514,7 @@ gfc_resolve_formal_arglist (gfc_symbol *proc)
{
/* F03:C1263 (R1238) The function-name and each dummy-arg-name
shall be specified, explicitly or implicitly, to be scalar. */
- gfc_error ("Argument '%s' of statement function '%s' at %L "
+ gfc_error ("Argument %qs of statement function %qs at %L "
"must be scalar", sym->name, proc->name,
&proc->declared_at);
continue;
@@ -4381,8 +4381,8 @@ resolve_operator (gfc_expr *e)
guessed = lookup_uop_fuzzy (name, e->value.op.uop->ns->uop_root);
if (guessed)
snprintf (msg, sizeof (msg),
- _("Unknown operator %%<%s%%> at %%L; did you mean '%s'?"),
- name, guessed);
+ _("Unknown operator %%<%s%%> at %%L; did you mean "
+ "%%<%s%%>?"), name, guessed);
else
snprintf (msg, sizeof (msg), _("Unknown operator %%<%s%%> at %%L"),
name);
@@ -5005,8 +5005,9 @@ find_array_spec (gfc_expr *e)
case REF_ARRAY:
if (as == NULL)
{
+ locus loc = ref->u.ar.where.lb ? ref->u.ar.where : e->where;
gfc_error ("Invalid array reference of a non-array entity at %L",
- &ref->u.ar.where);
+ &loc);
return false;
}
@@ -7535,7 +7536,8 @@ derived_inaccessible (gfc_symbol *sym)
for (c = sym->components; c; c = c->next)
{
/* Prevent an infinite loop through this function. */
- if (c->ts.type == BT_DERIVED && c->attr.pointer
+ if (c->ts.type == BT_DERIVED
+ && (c->attr.pointer || c->attr.allocatable)
&& sym == c->ts.u.derived)
continue;
@@ -7569,7 +7571,7 @@ resolve_deallocate_expr (gfc_expr *e)
sym = e->symtree->n.sym;
unlimited = UNLIMITED_POLY(sym);
- if (sym->ts.type == BT_CLASS)
+ if (sym->ts.type == BT_CLASS && sym->attr.class_ok && CLASS_DATA (sym))
{
allocatable = CLASS_DATA (sym)->attr.allocatable;
pointer = CLASS_DATA (sym)->attr.class_pointer;
@@ -8211,7 +8213,7 @@ check_symbols:
{
if (i == (ar->dimen + ar->codimen - 1))
{
- gfc_error ("Expected '*' in coindex specification in ALLOCATE "
+ gfc_error ("Expected %<*%> in coindex specification in ALLOCATE "
"statement at %L", &e->where);
goto failure;
}
@@ -11185,7 +11187,7 @@ resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns)
{
gfc_error ("Nonallocatable variable must not be polymorphic in intrinsic "
"assignment at %L - check that there is a matching specific "
- "subroutine for '=' operator", &lhs->where);
+ "subroutine for %<=%> operator", &lhs->where);
return false;
}
@@ -12967,6 +12969,7 @@ resolve_fl_var_and_proc (gfc_symbol *sym, int mp_flag)
&& sym->ts.u.derived
&& !sym->attr.select_type_temporary
&& !UNLIMITED_POLY (sym)
+ && CLASS_DATA (sym)->ts.u.derived
&& !gfc_type_is_extensible (CLASS_DATA (sym)->ts.u.derived))
{
gfc_error ("Type %qs of CLASS variable %qs at %L is not extensible",
@@ -17218,6 +17221,7 @@ resolve_equivalence (gfc_equiv *eq)
"statement at %L with different type objects";
if ((object ==2
&& last_eq_type == SEQ_MIXED
+ && last_where
&& !gfc_notify_std (GFC_STD_GNU, msg, first_sym->name, last_where))
|| (eq_type == SEQ_MIXED
&& !gfc_notify_std (GFC_STD_GNU, msg, sym->name, &e->where)))
@@ -17227,6 +17231,7 @@ resolve_equivalence (gfc_equiv *eq)
"statement at %L with objects of different type";
if ((object ==2
&& last_eq_type == SEQ_NONDEFAULT
+ && last_where
&& !gfc_notify_std (GFC_STD_GNU, msg, first_sym->name, last_where))
|| (eq_type == SEQ_NONDEFAULT
&& !gfc_notify_std (GFC_STD_GNU, msg, sym->name, &e->where)))
diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc
index 9c2fea8..3d3aaba 100644
--- a/gcc/fortran/simplify.cc
+++ b/gcc/fortran/simplify.cc
@@ -3955,6 +3955,9 @@ gfc_simplify_ishftc (gfc_expr *e, gfc_expr *s, gfc_expr *sz)
return NULL;
gfc_extract_int (sz, &ssize);
+
+ if (ssize > isize || ssize <= 0)
+ return &gfc_bad_expr;
}
else
ssize = isize;
@@ -4913,7 +4916,22 @@ gfc_simplify_merge (gfc_expr *tsource, gfc_expr *fsource, gfc_expr *mask)
if (mask->expr_type == EXPR_CONSTANT)
{
- result = gfc_copy_expr (mask->value.logical ? tsource : fsource);
+ /* The standard requires evaluation of all function arguments.
+ Simplify only when the other dropped argument (FSOURCE or TSOURCE)
+ is a constant expression. */
+ if (mask->value.logical)
+ {
+ if (!gfc_is_constant_expr (fsource))
+ return NULL;
+ result = gfc_copy_expr (tsource);
+ }
+ else
+ {
+ if (!gfc_is_constant_expr (tsource))
+ return NULL;
+ result = gfc_copy_expr (fsource);
+ }
+
/* Parenthesis is needed to get lower bounds of 1. */
result = gfc_get_parentheses (result);
gfc_simplify_expr (result, 1);
@@ -8470,7 +8488,16 @@ gfc_simplify_unpack (gfc_expr *vector, gfc_expr *mask, gfc_expr *field)
}
}
else if (field->expr_type == EXPR_ARRAY)
- e = gfc_copy_expr (field_ctor->expr);
+ {
+ if (field_ctor)
+ e = gfc_copy_expr (field_ctor->expr);
+ else
+ {
+ /* Not enough elements in array FIELD. */
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
+ }
else
e = gfc_copy_expr (field);
diff --git a/gcc/fortran/st.cc b/gcc/fortran/st.cc
index 3c8ca66..8b4ca5e 100644
--- a/gcc/fortran/st.cc
+++ b/gcc/fortran/st.cc
@@ -286,7 +286,7 @@ gfc_free_statement (gfc_code *p)
break;
case EXEC_OMP_FLUSH:
- gfc_free_omp_namelist (p->ext.omp_namelist, false);
+ gfc_free_omp_namelist (p->ext.omp_namelist, false, false);
break;
case EXEC_OMP_BARRIER:
diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc
index 49fb378..e704e7a 100644
--- a/gcc/fortran/symbol.cc
+++ b/gcc/fortran/symbol.cc
@@ -1108,6 +1108,12 @@ gfc_add_contiguous (symbol_attribute *attr, const char *name, locus *where)
if (check_used (attr, name, where))
return false;
+ if (attr->contiguous)
+ {
+ duplicate_attr ("CONTIGUOUS", where);
+ return false;
+ }
+
attr->contiguous = 1;
return gfc_check_conflict (attr, name, where);
}
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 514cb05..b7d4c41 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -10527,7 +10527,6 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
tree offset;
tree jump_label1;
tree jump_label2;
- tree neq_size;
tree lbd;
tree class_expr2 = NULL_TREE;
int n;
@@ -10607,6 +10606,11 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
elemsize1 = expr1->ts.u.cl->backend_decl;
else
elemsize1 = lss->info->string_length;
+ tree unit_size = TYPE_SIZE_UNIT (gfc_get_char_type (expr1->ts.kind));
+ elemsize1 = fold_build2_loc (input_location, MULT_EXPR,
+ TREE_TYPE (elemsize1), elemsize1,
+ fold_convert (TREE_TYPE (elemsize1), unit_size));
+
}
else if (expr1->ts.type == BT_CLASS)
{
@@ -10699,19 +10703,7 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
/* Allocate if data is NULL. */
cond_null = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
array1, build_int_cst (TREE_TYPE (array1), 0));
-
- if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
- {
- tmp = fold_build2_loc (input_location, NE_EXPR,
- logical_type_node,
- lss->info->string_length,
- rss->info->string_length);
- cond_null = fold_build2_loc (input_location, TRUTH_OR_EXPR,
- logical_type_node, tmp, cond_null);
- cond_null= gfc_evaluate_now (cond_null, &fblock);
- }
- else
- cond_null= gfc_evaluate_now (cond_null, &fblock);
+ cond_null= gfc_evaluate_now (cond_null, &fblock);
tmp = build3_v (COND_EXPR, cond_null,
build1_v (GOTO_EXPR, jump_label1),
@@ -10778,19 +10770,6 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
tmp = build1_v (LABEL_EXPR, jump_label1);
gfc_add_expr_to_block (&fblock, tmp);
- /* If the lhs has not been allocated, its bounds will not have been
- initialized and so its size is set to zero. */
- size1 = gfc_create_var (gfc_array_index_type, NULL);
- gfc_init_block (&alloc_block);
- gfc_add_modify (&alloc_block, size1, gfc_index_zero_node);
- gfc_init_block (&realloc_block);
- gfc_add_modify (&realloc_block, size1,
- gfc_conv_descriptor_size (desc, expr1->rank));
- tmp = build3_v (COND_EXPR, cond_null,
- gfc_finish_block (&alloc_block),
- gfc_finish_block (&realloc_block));
- gfc_add_expr_to_block (&fblock, tmp);
-
/* Get the rhs size and fix it. */
size2 = gfc_index_one_node;
for (n = 0; n < expr2->rank; n++)
@@ -10807,16 +10786,6 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
}
size2 = gfc_evaluate_now (size2, &fblock);
- cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
- size1, size2);
-
- /* If the lhs is deferred length, assume that the element size
- changes and force a reallocation. */
- if (expr1->ts.deferred)
- neq_size = gfc_evaluate_now (logical_true_node, &fblock);
- else
- neq_size = gfc_evaluate_now (cond, &fblock);
-
/* Deallocation of allocatable components will have to occur on
reallocation. Fix the old descriptor now. */
if ((expr1->ts.type == BT_DERIVED)
@@ -11048,20 +11017,6 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
gfc_add_block_to_block (&realloc_block, &caf_se.post);
realloc_expr = gfc_finish_block (&realloc_block);
- /* Reallocate if sizes or dynamic types are different. */
- if (elemsize1)
- {
- tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
- elemsize1, elemsize2);
- tmp = gfc_evaluate_now (tmp, &fblock);
- neq_size = fold_build2_loc (input_location, TRUTH_OR_EXPR,
- logical_type_node, neq_size, tmp);
- }
- tmp = build3_v (COND_EXPR, neq_size, realloc_expr,
- build_empty_stmt (input_location));
-
- realloc_expr = tmp;
-
/* Malloc expression. */
gfc_init_block (&alloc_block);
if (!coarray)
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 63515b9..217de6b 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -2507,8 +2507,8 @@ create_function_arglist (gfc_symbol * sym)
{
tree fndecl;
gfc_formal_arglist *f;
- tree typelist, hidden_typelist;
- tree arglist, hidden_arglist;
+ tree typelist, hidden_typelist, optval_typelist;
+ tree arglist, hidden_arglist, optval_arglist;
tree type;
tree parm;
@@ -2518,6 +2518,7 @@ create_function_arglist (gfc_symbol * sym)
the new FUNCTION_DECL node. */
arglist = NULL_TREE;
hidden_arglist = NULL_TREE;
+ optval_arglist = NULL_TREE;
typelist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
if (sym->attr.entry_master)
@@ -2619,6 +2620,15 @@ create_function_arglist (gfc_symbol * sym)
if (f->sym != NULL) /* Ignore alternate returns. */
hidden_typelist = TREE_CHAIN (hidden_typelist);
+ /* Advance hidden_typelist over optional+value argument presence flags. */
+ optval_typelist = hidden_typelist;
+ for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
+ if (f->sym != NULL
+ && f->sym->attr.optional && f->sym->attr.value
+ && !f->sym->attr.dimension && f->sym->ts.type != BT_CLASS
+ && !gfc_bt_struct (f->sym->ts.type))
+ hidden_typelist = TREE_CHAIN (hidden_typelist);
+
for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
{
char name[GFC_MAX_SYMBOL_LEN + 2];
@@ -2698,28 +2708,30 @@ create_function_arglist (gfc_symbol * sym)
type = gfc_sym_type (f->sym);
}
}
- /* For noncharacter scalar intrinsic types, VALUE passes the value,
+ /* For scalar intrinsic types, VALUE passes the value,
hence, the optional status cannot be transferred via a NULL pointer.
Thus, we will use a hidden argument in that case. */
- else if (f->sym->attr.optional && f->sym->attr.value
- && !f->sym->attr.dimension && f->sym->ts.type != BT_CLASS
- && !gfc_bt_struct (f->sym->ts.type))
+ if (f->sym->attr.optional && f->sym->attr.value
+ && !f->sym->attr.dimension && f->sym->ts.type != BT_CLASS
+ && !gfc_bt_struct (f->sym->ts.type))
{
tree tmp;
strcpy (&name[1], f->sym->name);
- name[0] = '_';
+ name[0] = '.';
tmp = build_decl (input_location,
PARM_DECL, get_identifier (name),
boolean_type_node);
- hidden_arglist = chainon (hidden_arglist, tmp);
+ optval_arglist = chainon (optval_arglist, tmp);
DECL_CONTEXT (tmp) = fndecl;
DECL_ARTIFICIAL (tmp) = 1;
DECL_ARG_TYPE (tmp) = boolean_type_node;
TREE_READONLY (tmp) = 1;
gfc_finish_decl (tmp);
- hidden_typelist = TREE_CHAIN (hidden_typelist);
+ /* The presence flag must be boolean. */
+ gcc_assert (TREE_VALUE (optval_typelist) == boolean_type_node);
+ optval_typelist = TREE_CHAIN (optval_typelist);
}
/* For non-constant length array arguments, make sure they use
@@ -2863,6 +2875,9 @@ create_function_arglist (gfc_symbol * sym)
typelist = TREE_CHAIN (typelist);
}
+ /* Add hidden present status for optional+value arguments. */
+ arglist = chainon (arglist, optval_arglist);
+
/* Add the hidden string length parameters, unless the procedure
is bind(C). */
if (!sym->attr.is_bind_c)
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index e7b9211..b95c5cf 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -1985,15 +1985,14 @@ gfc_conv_expr_present (gfc_symbol * sym, bool use_saved_desc)
/* Intrinsic scalars with VALUE attribute which are passed by value
use a hidden argument to denote the present status. */
- if (sym->attr.value && sym->ts.type != BT_CHARACTER
- && sym->ts.type != BT_CLASS && sym->ts.type != BT_DERIVED
- && !sym->attr.dimension)
+ if (sym->attr.value && !sym->attr.dimension
+ && sym->ts.type != BT_CLASS && !gfc_bt_struct (sym->ts.type))
{
char name[GFC_MAX_SYMBOL_LEN + 2];
tree tree_name;
gcc_assert (TREE_CODE (decl) == PARM_DECL);
- name[0] = '_';
+ name[0] = '.';
strcpy (&name[1], sym->name);
tree_name = get_identifier (name);
@@ -6162,11 +6161,21 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
value, pass "0" and a hidden argument gives the optional
status. */
if (fsym && fsym->attr.optional && fsym->attr.value
- && !fsym->attr.dimension && fsym->ts.type != BT_CHARACTER
- && fsym->ts.type != BT_CLASS && fsym->ts.type != BT_DERIVED)
+ && !fsym->attr.dimension && fsym->ts.type != BT_CLASS
+ && !gfc_bt_struct (sym->ts.type))
{
- parmse.expr = fold_convert (gfc_sym_type (fsym),
- integer_zero_node);
+ if (fsym->ts.type == BT_CHARACTER)
+ {
+ /* Pass a NULL pointer for an absent CHARACTER arg
+ and a length of zero. */
+ parmse.expr = null_pointer_node;
+ parmse.string_length
+ = build_int_cst (gfc_charlen_type_node,
+ 0);
+ }
+ else
+ parmse.expr = fold_convert (gfc_sym_type (fsym),
+ integer_zero_node);
vec_safe_push (optionalargs, boolean_false_node);
}
else
@@ -11236,10 +11245,10 @@ alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
{
- /* Use the rhs string length and the lhs element size. */
+ /* Use the rhs string length and the lhs element size. Note that 'size' is
+ used below for the string-length comparison, only. */
size = string_length;
- tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
- tmp = TYPE_SIZE_UNIT (tmp);
+ tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr1->ts.kind));
size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
TREE_TYPE (tmp), tmp,
fold_convert (TREE_TYPE (tmp), size));
diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc
index bb93802..9342698 100644
--- a/gcc/fortran/trans-intrinsic.cc
+++ b/gcc/fortran/trans-intrinsic.cc
@@ -7557,6 +7557,9 @@ gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
&se->pre);
se->string_length = len;
}
+ tsource = gfc_evaluate_now (tsource, &se->pre);
+ fsource = gfc_evaluate_now (fsource, &se->pre);
+ mask = gfc_evaluate_now (mask, &se->pre);
type = TREE_TYPE (tsource);
se->expr = fold_build3_loc (input_location, COND_EXPR, type, mask, tsource,
fold_convert (type, fsource));
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 9bd4e6c..7a4a339 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -123,7 +123,7 @@ gfc_omp_check_optional_argument (tree decl, bool for_present_check)
char name[GFC_MAX_SYMBOL_LEN + 2];
tree tree_name;
- name[0] = '_';
+ name[0] = '.';
strcpy (&name[1], IDENTIFIER_POINTER (DECL_NAME (decl)));
tree_name = get_identifier (name);
@@ -2724,6 +2724,14 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
allocator_ = gfc_evaluate_now (se.expr, block);
OMP_CLAUSE_ALLOCATE_ALLOCATOR (node) = allocator_;
}
+ if (n->u.align)
+ {
+ tree align_;
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr (&se, n->u.align);
+ align_ = gfc_evaluate_now (se.expr, block);
+ OMP_CLAUSE_ALLOCATE_ALIGN (node) = align_;
+ }
omp_clauses = gfc_trans_add_clause (node, omp_clauses);
}
}
@@ -3626,7 +3634,10 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
gcc_unreachable ();
}
tree node = build_omp_clause (input_location, clause_code);
- if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL)
+ if (n->expr == NULL
+ || (n->expr->ref->type == REF_ARRAY
+ && n->expr->ref->u.ar.type == AR_FULL
+ && n->expr->ref->next == NULL))
{
tree decl = gfc_trans_omp_variable (n->sym, false);
if (gfc_omp_privatize_by_reference (decl))
@@ -3666,13 +3677,13 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
{
tree ptr;
gfc_init_se (&se, NULL);
- if (n->expr->ref->u.ar.type == AR_ELEMENT)
+ if (n->expr->rank == 0)
{
gfc_conv_expr_reference (&se, n->expr);
ptr = se.expr;
gfc_add_block_to_block (block, &se.pre);
OMP_CLAUSE_SIZE (node)
- = TYPE_SIZE_UNIT (TREE_TYPE (ptr));
+ = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ptr)));
}
else
{
diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index fd6d294..b288f1f 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -264,6 +264,7 @@ gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse,
if (e->expr_type == EXPR_VARIABLE
&& e->rank && fsym
&& fsym->attr.intent != INTENT_IN
+ && !fsym->attr.value
&& gfc_check_fncall_dependency (e, fsym->attr.intent,
sym, arg0, check_variable))
{
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index def7552..196f2ce 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -3105,6 +3105,7 @@ gfc_get_function_type (gfc_symbol * sym, gfc_actual_arglist *actual_args,
{
tree type;
vec<tree, va_gc> *typelist = NULL;
+ vec<tree, va_gc> *hidden_typelist = NULL;
gfc_formal_arglist *f;
gfc_symbol *arg;
int alternate_return = 0;
@@ -3222,17 +3223,17 @@ gfc_get_function_type (gfc_symbol * sym, gfc_actual_arglist *actual_args,
so that the value can be returned. */
type = build_pointer_type (gfc_charlen_type_node);
- vec_safe_push (typelist, type);
+ vec_safe_push (hidden_typelist, type);
}
- /* For noncharacter scalar intrinsic types, VALUE passes the value,
+ /* For scalar intrinsic types, VALUE passes the value,
hence, the optional status cannot be transferred via a NULL pointer.
Thus, we will use a hidden argument in that case. */
- else if (arg
- && arg->attr.optional
- && arg->attr.value
- && !arg->attr.dimension
- && arg->ts.type != BT_CLASS
- && !gfc_bt_struct (arg->ts.type))
+ if (arg
+ && arg->attr.optional
+ && arg->attr.value
+ && !arg->attr.dimension
+ && arg->ts.type != BT_CLASS
+ && !gfc_bt_struct (arg->ts.type))
vec_safe_push (typelist, boolean_type_node);
/* Coarrays which are descriptorless or assumed-shape pass with
-fcoarray=lib the token and the offset as hidden arguments. */
@@ -3245,11 +3246,15 @@ gfc_get_function_type (gfc_symbol * sym, gfc_actual_arglist *actual_args,
&& CLASS_DATA (arg)->attr.codimension
&& !CLASS_DATA (arg)->attr.allocatable)))
{
- vec_safe_push (typelist, pvoid_type_node); /* caf_token. */
- vec_safe_push (typelist, gfc_array_index_type); /* caf_offset. */
+ vec_safe_push (hidden_typelist, pvoid_type_node); /* caf_token. */
+ vec_safe_push (hidden_typelist, gfc_array_index_type); /* caf_offset. */
}
}
+ /* Put hidden character length, caf_token, caf_offset at the end. */
+ vec_safe_reserve (typelist, vec_safe_length (hidden_typelist));
+ vec_safe_splice (typelist, hidden_typelist);
+
if (!vec_safe_is_empty (typelist)
|| sym->attr.is_main_program
|| sym->attr.if_source != IFSRC_UNKNOWN)
diff --git a/gcc/function.cc b/gcc/function.cc
index d3da20e..dc333c2 100644
--- a/gcc/function.cc
+++ b/gcc/function.cc
@@ -2090,6 +2090,9 @@ aggregate_value_p (const_tree exp, const_tree fntype)
if (VOID_TYPE_P (type))
return 0;
+ if (error_operand_p (fntype))
+ return 0;
+
/* If a record should be passed the same as its first (and only) member
don't pass it as an aggregate. */
if (TREE_CODE (type) == RECORD_TYPE && TYPE_TRANSPARENT_AGGR (type))
@@ -4994,7 +4997,8 @@ init_function_start (tree subr)
/* Warn if this value is an aggregate type,
regardless of which calling convention we are using for it. */
if (AGGREGATE_TYPE_P (TREE_TYPE (DECL_RESULT (subr))))
- warning (OPT_Waggregate_return, "function returns an aggregate");
+ warning_at (DECL_SOURCE_LOCATION (DECL_RESULT (subr)),
+ OPT_Waggregate_return, "function returns an aggregate");
}
/* Expand code to verify the stack_protect_guard. This is invoked at
@@ -6546,7 +6550,7 @@ make_pass_leaf_regs (gcc::context *ctxt)
}
static unsigned int
-rest_of_handle_thread_prologue_and_epilogue (void)
+rest_of_handle_thread_prologue_and_epilogue (function *fun)
{
/* prepare_shrink_wrap is sensitive to the block structure of the control
flow graph, so clean it up first. */
@@ -6563,6 +6567,13 @@ rest_of_handle_thread_prologue_and_epilogue (void)
Fix that up. */
fixup_partitions ();
+ /* After prologue and epilogue generation, the judgement on whether
+ one memory access onto stack frame may trap or not could change,
+ since we get more exact stack information by now. So try to
+ remove any EH edges here, see PR90259. */
+ if (fun->can_throw_non_call_exceptions)
+ purge_all_dead_edges ();
+
/* Shrink-wrapping can result in unreachable edges in the epilogue,
see PR57320. */
cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0);
@@ -6631,9 +6642,9 @@ public:
{}
/* opt_pass methods: */
- unsigned int execute (function *) final override
+ unsigned int execute (function * fun) final override
{
- return rest_of_handle_thread_prologue_and_epilogue ();
+ return rest_of_handle_thread_prologue_and_epilogue (fun);
}
}; // class pass_thread_prologue_and_epilogue
diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index afb23cd..2568d54 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -706,6 +706,13 @@ proper position among the other output files. */
#define CPP_SPEC ""
#endif
+/* Operating systems can define OS_CC1_SPEC to provide extra args to cc1 and
+ cc1plus or extra switch-translations. The OS_CC1_SPEC is appended
+ to CC1_SPEC in the initialization of cc1_spec. */
+#ifndef OS_CC1_SPEC
+#define OS_CC1_SPEC ""
+#endif
+
/* config.h can define CC1_SPEC to provide extra args to cc1 and cc1plus
or extra switch-translations. */
#ifndef CC1_SPEC
@@ -877,7 +884,7 @@ proper position among the other output files. */
#endif
#ifdef HAVE_AS_DEBUG_PREFIX_MAP
-#define ASM_MAP " %{fdebug-prefix-map=*:--debug-prefix-map %*}"
+#define ASM_MAP " %{ffile-prefix-map=*:--debug-prefix-map %*} %{fdebug-prefix-map=*:--debug-prefix-map %*}"
#else
#define ASM_MAP ""
#endif
@@ -1174,7 +1181,7 @@ proper position among the other output files. */
static const char *asm_debug = ASM_DEBUG_SPEC;
static const char *asm_debug_option = ASM_DEBUG_OPTION_SPEC;
static const char *cpp_spec = CPP_SPEC;
-static const char *cc1_spec = CC1_SPEC;
+static const char *cc1_spec = CC1_SPEC OS_CC1_SPEC;
static const char *cc1plus_spec = CC1PLUS_SPEC;
static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
static const char *link_ssp_spec = LINK_SSP_SPEC;
@@ -1327,7 +1334,11 @@ static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
static const char *const driver_self_specs[] = {
"%{fdump-final-insns:-fdump-final-insns=.} %<fdump-final-insns",
- DRIVER_SELF_SPECS, CONFIGURE_SPECS, GOMP_SELF_SPECS, GTM_SELF_SPECS
+ DRIVER_SELF_SPECS, CONFIGURE_SPECS, GOMP_SELF_SPECS, GTM_SELF_SPECS,
+ /* This discards -fmultiflags at the end of self specs processing in the
+ driver, so that it is effectively Ignored, without actually marking it as
+ Ignored, which would get it discarded before self specs could remap it. */
+ "%<fmultiflags"
};
#ifndef OPTION_DEFAULT_SPECS
@@ -9288,12 +9299,15 @@ validate_switches (const char *start, bool user_spec, bool braced)
const char *atom;
size_t len;
int i;
- bool suffix = false;
- bool starred = false;
+ bool suffix;
+ bool starred;
#define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
next_member:
+ suffix = false;
+ starred = false;
+
SKIP_WHITE ();
if (*p == '!')
diff --git a/gcc/generic-match-head.cc b/gcc/generic-match-head.cc
index cb0fbd3..aed4dcc 100644
--- a/gcc/generic-match-head.cc
+++ b/gcc/generic-match-head.cc
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "dbgcnt.h"
#include "tm.h"
#include "tree-eh.h"
+#include "langhooks.h"
/* Routine to determine if the types T1 and T2 are effectively
the same for GENERIC. If T1 or T2 is not a type, the test
diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc
index 4a88024..b56c177 100644
--- a/gcc/genmatch.cc
+++ b/gcc/genmatch.cc
@@ -2927,8 +2927,16 @@ dt_node::gen_kids (FILE *f, int indent, bool gimple, int depth)
if (expr *e = dyn_cast <expr *> (op->op))
{
if (e->ops.length () == 0
+ /* In GIMPLE a CONSTRUCTOR always appears in a
+ separate definition. */
&& (!gimple || !(*e->operation == CONSTRUCTOR)))
- generic_exprs.safe_push (op);
+ {
+ generic_exprs.safe_push (op);
+ /* But ADDR_EXPRs can appear directly when invariant
+ and in a separate definition when not. */
+ if (gimple && *e->operation == ADDR_EXPR)
+ gimple_exprs.safe_push (op);
+ }
else if (e->operation->kind == id_base::FN)
{
if (gimple)
diff --git a/gcc/genmultilib b/gcc/genmultilib
index 1e387fb..c0c271e 100644
--- a/gcc/genmultilib
+++ b/gcc/genmultilib
@@ -250,6 +250,10 @@ if [ -n "${dirnames}" ]; then
for opts in `echo ${set} | sed -e 's|/| |'g`; do
patt="/"
for opt in `echo ${opts} | sed -e 's_|_ _'g`; do
+ if [ -z "$1" ]; then
+ echo 1>&2 "Error calling $0: No dirname for option: $opt"
+ exit 1
+ fi
if [ "$1" != "${opt}" ]; then
todirnames="${todirnames} -e s|/${opt}/|/${1}/|g"
patt="${patt}${1}/"
@@ -306,6 +310,10 @@ if [ -n "${osdirnames}" ]; then
for opts in `echo ${set} | sed -e 's|/| |'g`; do
patt="/"
for opt in `echo ${opts} | sed -e 's_|_ _'g`; do
+ if [ -z "$1" ]; then
+ echo 1>&2 "Error calling $0: No osdirname for option: $opt"
+ exit 1
+ fi
if [ "$1" != "${opt}" ]; then
toosdirnames="${toosdirnames} -e s|/${opt}/|/${1}/|g"
patt="${patt}${1}/"
diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
index e190b93..59bd9eb 100644
--- a/gcc/gimple-array-bounds.cc
+++ b/gcc/gimple-array-bounds.cc
@@ -46,9 +46,6 @@ array_bounds_checker::array_bounds_checker (struct function *func,
/* No-op. */
}
-// This purposely returns a value_range, not a value_range_equiv, to
-// break the dependency on equivalences for this pass.
-
const value_range *
array_bounds_checker::get_value_range (const_tree op, gimple *stmt)
{
@@ -78,14 +75,7 @@ get_base_decl (tree ref)
if (gimple_assign_single_p (def))
{
base = gimple_assign_rhs1 (def);
- if (TREE_CODE (base) != ASSERT_EXPR)
- return base;
-
- base = TREE_OPERAND (base, 0);
- if (TREE_CODE (base) != SSA_NAME)
- return base;
-
- continue;
+ return base;
}
if (!gimple_nop_p (def))
@@ -129,7 +119,7 @@ get_ref_size (tree arg, tree *pref)
}
/* Return true if REF is (likely) an ARRAY_REF to a trailing array member
- of a struct. It refines array_at_struct_end_p by detecting a pointer
+ of a struct. It refines array_ref_flexible_size_p by detecting a pointer
to an array and an array parameter declared using the [N] syntax (as
opposed to a pointer) and returning false. Set *PREF to the decl or
expression REF refers to. */
@@ -167,41 +157,20 @@ trailing_array (tree arg, tree *pref)
return false;
}
- return array_at_struct_end_p (arg);
+ return array_ref_flexible_size_p (arg);
}
-/* Checks one ARRAY_REF in REF, located at LOCUS. Ignores flexible
- arrays and "struct" hacks. If VRP can determine that the array
- subscript is a constant, check if it is outside valid range. If
- the array subscript is a RANGE, warn if it is non-overlapping with
- valid range. IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside
- a ADDR_EXPR. Return true if a warning has been issued or if
- no-warning is set. */
+/* Acquire the upper bound and upper bound plus one for the array
+ reference REF and record them into UP_BOUND and UP_BOUND_P1.
+ Set *DECL to the decl or expresssion REF refers to. */
-bool
-array_bounds_checker::check_array_ref (location_t location, tree ref,
- gimple *stmt, bool ignore_off_by_one)
+static void
+get_up_bounds_for_array_ref (tree ref, tree *decl,
+ tree *up_bound, tree *up_bound_p1)
{
- if (warning_suppressed_p (ref, OPT_Warray_bounds))
- /* Return true to have the caller prevent warnings for enclosing
- refs. */
- return true;
-
- tree low_sub = TREE_OPERAND (ref, 1);
- tree up_sub = low_sub;
- tree up_bound = array_ref_up_bound (ref);
-
- /* Referenced decl if one can be determined. */
- tree decl = NULL_TREE;
-
- /* Set for accesses to interior zero-length arrays. */
- special_array_member sam{ };
-
- tree up_bound_p1;
-
- if (!up_bound
- || TREE_CODE (up_bound) != INTEGER_CST
- || (warn_array_bounds < 2 && trailing_array (ref, &decl)))
+ if (!(*up_bound)
+ || TREE_CODE (*up_bound) != INTEGER_CST
+ || trailing_array (ref, decl))
{
/* Accesses to trailing arrays via pointers may access storage
beyond the types array bounds. For such arrays, or for flexible
@@ -213,8 +182,8 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
if (TREE_CODE (eltsize) != INTEGER_CST
|| integer_zerop (eltsize))
{
- up_bound = NULL_TREE;
- up_bound_p1 = NULL_TREE;
+ *up_bound = NULL_TREE;
+ *up_bound_p1 = NULL_TREE;
}
else
{
@@ -227,7 +196,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
{
/* Try to determine the size of the trailing array from
its initializer (if it has one). */
- if (tree refsize = component_ref_size (arg, &sam))
+ if (tree refsize = component_ref_size (arg))
if (TREE_CODE (refsize) == INTEGER_CST)
maxbound = refsize;
}
@@ -246,7 +215,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
{
/* Try to determine the size from a pointer to
an array if BASE is one. */
- if (tree size = get_ref_size (base, &decl))
+ if (tree size = get_ref_size (base, decl))
maxbound = size;
}
else if (!compref && DECL_P (base))
@@ -254,7 +223,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
if (TREE_CODE (basesize) == INTEGER_CST)
{
maxbound = basesize;
- decl = base;
+ *decl = base;
}
if (known_gt (off, 0))
@@ -266,41 +235,42 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
else
maxbound = fold_convert (sizetype, maxbound);
- up_bound_p1 = int_const_binop (TRUNC_DIV_EXPR, maxbound, eltsize);
+ *up_bound_p1 = int_const_binop (TRUNC_DIV_EXPR, maxbound, eltsize);
- if (up_bound_p1 != NULL_TREE)
- up_bound = int_const_binop (MINUS_EXPR, up_bound_p1,
+ if (*up_bound_p1 != NULL_TREE)
+ *up_bound = int_const_binop (MINUS_EXPR, *up_bound_p1,
build_int_cst (ptrdiff_type_node, 1));
else
- up_bound = NULL_TREE;
+ *up_bound = NULL_TREE;
}
}
else
- up_bound_p1 = int_const_binop (PLUS_EXPR, up_bound,
- build_int_cst (TREE_TYPE (up_bound), 1));
+ *up_bound_p1 = int_const_binop (PLUS_EXPR, *up_bound,
+ build_int_cst (TREE_TYPE (*up_bound), 1));
+ return;
+}
- tree low_bound = array_ref_low_bound (ref);
+/* Given the LOW_SUB_ORG, LOW_SUB and UP_SUB, and the computed UP_BOUND
+ and UP_BOUND_P1, check whether the array reference REF is out of bound.
+ Issue warnings if out of bound, return TRUE if warnings are issued. */
+static bool
+check_out_of_bounds_and_warn (location_t location, tree ref,
+ tree low_sub_org, tree low_sub, tree up_sub,
+ tree up_bound, tree up_bound_p1,
+ const value_range *vr,
+ bool ignore_off_by_one)
+{
+ tree low_bound = array_ref_low_bound (ref);
tree artype = TREE_TYPE (TREE_OPERAND (ref, 0));
bool warned = false;
/* Empty array. */
if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1))
- warned = warning_at (location, OPT_Warray_bounds,
+ warned = warning_at (location, OPT_Warray_bounds_,
"array subscript %E is outside array bounds of %qT",
- low_sub, artype);
-
- const value_range *vr = NULL;
- if (TREE_CODE (low_sub) == SSA_NAME)
- {
- vr = get_value_range (low_sub, stmt);
- if (!vr->undefined_p () && !vr->varying_p ())
- {
- low_sub = vr->kind () == VR_RANGE ? vr->max () : vr->min ();
- up_sub = vr->kind () == VR_RANGE ? vr->min () : vr->max ();
- }
- }
+ low_sub_org, artype);
if (warned)
; /* Do nothing. */
@@ -313,7 +283,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
: tree_int_cst_le (up_bound, up_sub))
&& TREE_CODE (low_sub) == INTEGER_CST
&& tree_int_cst_le (low_sub, low_bound))
- warned = warning_at (location, OPT_Warray_bounds,
+ warned = warning_at (location, OPT_Warray_bounds_,
"array subscript [%E, %E] is outside "
"array bounds of %qT",
low_sub, up_sub, artype);
@@ -323,14 +293,76 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
&& (ignore_off_by_one
? !tree_int_cst_le (up_sub, up_bound_p1)
: !tree_int_cst_le (up_sub, up_bound)))
- warned = warning_at (location, OPT_Warray_bounds,
+ warned = warning_at (location, OPT_Warray_bounds_,
"array subscript %E is above array bounds of %qT",
up_sub, artype);
else if (TREE_CODE (low_sub) == INTEGER_CST
&& tree_int_cst_lt (low_sub, low_bound))
- warned = warning_at (location, OPT_Warray_bounds,
+ warned = warning_at (location, OPT_Warray_bounds_,
"array subscript %E is below array bounds of %qT",
low_sub, artype);
+ return warned;
+}
+
+/* Checks one ARRAY_REF in REF, located at LOCUS. Ignores flexible
+ arrays and "struct" hacks. If VRP can determine that the array
+ subscript is a constant, check if it is outside valid range. If
+ the array subscript is a RANGE, warn if it is non-overlapping with
+ valid range. IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside
+ a ADDR_EXPR. Return true if a warning has been issued or if
+ no-warning is set. */
+
+bool
+array_bounds_checker::check_array_ref (location_t location, tree ref,
+ gimple *stmt, bool ignore_off_by_one)
+{
+ if (warning_suppressed_p (ref, OPT_Warray_bounds_))
+ /* Return true to have the caller prevent warnings for enclosing
+ refs. */
+ return true;
+
+ /* Upper bound and Upper bound plus one for -Warray-bounds. */
+ tree up_bound = array_ref_up_bound (ref);
+ tree up_bound_p1 = NULL_TREE;
+
+ /* Referenced decl if one can be determined. */
+ tree decl = NULL_TREE;
+
+ /* Set to the type of the special array member for a COMPONENT_REF. */
+ special_array_member sam{ };
+
+ tree arg = TREE_OPERAND (ref, 0);
+ const bool compref = TREE_CODE (arg) == COMPONENT_REF;
+
+ if (compref)
+ /* Try to determine special array member type for this COMPONENT_REF. */
+ sam = component_ref_sam_type (arg);
+
+ get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1);
+
+ bool warned = false;
+
+ tree artype = TREE_TYPE (TREE_OPERAND (ref, 0));
+ tree low_sub_org = TREE_OPERAND (ref, 1);
+ tree up_sub = low_sub_org;
+ tree low_sub = low_sub_org;
+
+ const value_range *vr = NULL;
+ if (TREE_CODE (low_sub_org) == SSA_NAME)
+ {
+ vr = get_value_range (low_sub_org, stmt);
+ if (!vr->undefined_p () && !vr->varying_p ())
+ {
+ low_sub = vr->kind () == VR_RANGE ? vr->max () : vr->min ();
+ up_sub = vr->kind () == VR_RANGE ? vr->min () : vr->max ();
+ }
+ }
+
+ warned = check_out_of_bounds_and_warn (location, ref,
+ low_sub_org, low_sub, up_sub,
+ up_bound, up_bound_p1, vr,
+ ignore_off_by_one);
+
if (!warned && sam == special_array_member::int_0)
warned = warning_at (location, OPT_Wzero_length_bounds,
@@ -353,7 +385,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
/* Avoid more warnings when checking more significant subscripts
of the same expression. */
ref = TREE_OPERAND (ref, 0);
- suppress_warning (ref, OPT_Warray_bounds);
+ suppress_warning (ref, OPT_Warray_bounds_);
if (decl)
ref = decl;
@@ -393,7 +425,7 @@ bool
array_bounds_checker::check_mem_ref (location_t location, tree ref,
bool ignore_off_by_one)
{
- if (warning_suppressed_p (ref, OPT_Warray_bounds))
+ if (warning_suppressed_p (ref, OPT_Warray_bounds_))
return false;
/* The statement used to allocate the array or null. */
@@ -493,12 +525,12 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
if (lboob)
{
if (offrange[0] == offrange[1])
- warned = warning_at (location, OPT_Warray_bounds,
+ warned = warning_at (location, OPT_Warray_bounds_,
"array subscript %wi is outside array bounds "
"of %qT",
offrange[0].to_shwi (), reftype);
else
- warned = warning_at (location, OPT_Warray_bounds,
+ warned = warning_at (location, OPT_Warray_bounds_,
"array subscript [%wi, %wi] is outside "
"array bounds of %qT",
offrange[0].to_shwi (),
@@ -513,7 +545,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
backtype = build_array_type_nelts (unsigned_char_type_node,
aref.sizrng[1].to_uhwi ());
- warned = warning_at (location, OPT_Warray_bounds,
+ warned = warning_at (location, OPT_Warray_bounds_,
"array subscript %<%T[%wi]%> is partly "
"outside array bounds of %qT",
axstype, offrange[0].to_shwi (), backtype);
@@ -523,7 +555,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
{
/* TODO: Determine the access from the statement and use it. */
aref.inform_access (access_none);
- suppress_warning (ref, OPT_Warray_bounds);
+ suppress_warning (ref, OPT_Warray_bounds_);
return true;
}
@@ -536,11 +568,11 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
{
HOST_WIDE_INT tmpidx = (aref.offmax[i] / eltsize).to_shwi ();
- if (warning_at (location, OPT_Warray_bounds,
+ if (warning_at (location, OPT_Warray_bounds_,
"intermediate array offset %wi is outside array bounds "
"of %qT", tmpidx, reftype))
{
- suppress_warning (ref, OPT_Warray_bounds);
+ suppress_warning (ref, OPT_Warray_bounds_);
return true;
}
}
@@ -572,7 +604,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
warned = check_mem_ref (location, t, ignore_off_by_one);
if (warned)
- suppress_warning (t, OPT_Warray_bounds);
+ suppress_warning (t, OPT_Warray_bounds_);
t = TREE_OPERAND (t, 0);
}
@@ -580,7 +612,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
if (TREE_CODE (t) != MEM_REF
|| TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR
- || warning_suppressed_p (t, OPT_Warray_bounds))
+ || warning_suppressed_p (t, OPT_Warray_bounds_))
return;
tree tem = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
@@ -615,7 +647,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
fprintf (dump_file, "\n");
}
- warned = warning_at (location, OPT_Warray_bounds,
+ warned = warning_at (location, OPT_Warray_bounds_,
"array subscript %wi is below "
"array bounds of %qT",
idx.to_shwi (), TREE_TYPE (tem));
@@ -629,7 +661,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
fprintf (dump_file, "\n");
}
- warned = warning_at (location, OPT_Warray_bounds,
+ warned = warning_at (location, OPT_Warray_bounds_,
"array subscript %wu is above "
"array bounds of %qT",
idx.to_uhwi (), TREE_TYPE (tem));
@@ -640,7 +672,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t,
if (DECL_P (t))
inform (DECL_SOURCE_LOCATION (t), "while referencing %qD", t);
- suppress_warning (t, OPT_Warray_bounds);
+ suppress_warning (t, OPT_Warray_bounds_);
}
}
@@ -740,7 +772,7 @@ array_bounds_checker::check_array_bounds (tree *tp, int *walk_subtree,
/* Propagate the no-warning bit to the outer statement to avoid also
issuing -Wstringop-overflow/-overread for the out-of-bounds accesses. */
if (warned)
- suppress_warning (wi->stmt, OPT_Warray_bounds);
+ suppress_warning (wi->stmt, OPT_Warray_bounds_);
return NULL_TREE;
}
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 9055cd8..c87e17f 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -68,6 +68,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-strlen.h"
#include "varasm.h"
#include "internal-fn.h"
+#include "gimple-range.h"
enum strlen_range_kind {
/* Compute the exact constant string length. */
@@ -590,7 +591,7 @@ fold_gimple_assign (gimple_stmt_iterator *si)
If the statement has a lhs the last stmt in the sequence is expected
to assign to that lhs. */
-static void
+void
gsi_replace_with_seq_vops (gimple_stmt_iterator *si_p, gimple_seq stmts)
{
gimple *stmt = gsi_stmt (*si_p);
@@ -1690,13 +1691,11 @@ get_range_strlen_tree (tree arg, bitmap visited, strlen_range_kind rkind,
/* Handle a MEM_REF into a DECL accessing an array of integers,
being conservative about references to extern structures with
flexible array members that can be initialized to arbitrary
- numbers of elements as an extension (static structs are okay).
- FIXME: Make this less conservative -- see
- component_ref_size in tree.cc. */
+ numbers of elements as an extension (static structs are okay). */
tree ref = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
if ((TREE_CODE (ref) == PARM_DECL || VAR_P (ref))
&& (decl_binds_to_current_def_p (ref)
- || !array_at_struct_end_p (arg)))
+ || !array_ref_flexible_size_p (arg)))
{
/* Fail if the offset is out of bounds. Such accesses
should be diagnosed at some point. */
@@ -5370,19 +5369,38 @@ arith_overflowed_p (enum tree_code code, const_tree type,
return wi::min_precision (wres, sign) > TYPE_PRECISION (type);
}
-/* If IFN_MASK_LOAD/STORE call CALL is unconditional, return a MEM_REF
+/* If IFN_{MASK,LEN}_LOAD/STORE call CALL is unconditional, return a MEM_REF
for the memory it references, otherwise return null. VECTYPE is the
- type of the memory vector. */
+ type of the memory vector. MASK_P indicates it's for MASK if true,
+ otherwise it's for LEN. */
static tree
-gimple_fold_mask_load_store_mem_ref (gcall *call, tree vectype)
+gimple_fold_partial_load_store_mem_ref (gcall *call, tree vectype, bool mask_p)
{
tree ptr = gimple_call_arg (call, 0);
tree alias_align = gimple_call_arg (call, 1);
- tree mask = gimple_call_arg (call, 2);
- if (!tree_fits_uhwi_p (alias_align) || !integer_all_onesp (mask))
+ if (!tree_fits_uhwi_p (alias_align))
return NULL_TREE;
+ if (mask_p)
+ {
+ tree mask = gimple_call_arg (call, 2);
+ if (!integer_all_onesp (mask))
+ return NULL_TREE;
+ }
+ else
+ {
+ tree basic_len = gimple_call_arg (call, 2);
+ if (!poly_int_tree_p (basic_len))
+ return NULL_TREE;
+ unsigned int nargs = gimple_call_num_args (call);
+ tree bias = gimple_call_arg (call, nargs - 1);
+ gcc_assert (TREE_CODE (bias) == INTEGER_CST);
+ if (maybe_ne (wi::to_poly_widest (basic_len) - wi::to_widest (bias),
+ GET_MODE_SIZE (TYPE_MODE (vectype))))
+ return NULL_TREE;
+ }
+
unsigned HOST_WIDE_INT align = tree_to_uhwi (alias_align);
if (TYPE_ALIGN (vectype) != align)
vectype = build_aligned_type (vectype, align);
@@ -5390,16 +5408,18 @@ gimple_fold_mask_load_store_mem_ref (gcall *call, tree vectype)
return fold_build2 (MEM_REF, vectype, ptr, offset);
}
-/* Try to fold IFN_MASK_LOAD call CALL. Return true on success. */
+/* Try to fold IFN_{MASK,LEN}_LOAD call CALL. Return true on success.
+ MASK_P indicates it's for MASK if true, otherwise it's for LEN. */
static bool
-gimple_fold_mask_load (gimple_stmt_iterator *gsi, gcall *call)
+gimple_fold_partial_load (gimple_stmt_iterator *gsi, gcall *call, bool mask_p)
{
tree lhs = gimple_call_lhs (call);
if (!lhs)
return false;
- if (tree rhs = gimple_fold_mask_load_store_mem_ref (call, TREE_TYPE (lhs)))
+ if (tree rhs
+ = gimple_fold_partial_load_store_mem_ref (call, TREE_TYPE (lhs), mask_p))
{
gassign *new_stmt = gimple_build_assign (lhs, rhs);
gimple_set_location (new_stmt, gimple_location (call));
@@ -5410,13 +5430,16 @@ gimple_fold_mask_load (gimple_stmt_iterator *gsi, gcall *call)
return false;
}
-/* Try to fold IFN_MASK_STORE call CALL. Return true on success. */
+/* Try to fold IFN_{MASK,LEN}_STORE call CALL. Return true on success.
+ MASK_P indicates it's for MASK if true, otherwise it's for LEN. */
static bool
-gimple_fold_mask_store (gimple_stmt_iterator *gsi, gcall *call)
+gimple_fold_partial_store (gimple_stmt_iterator *gsi, gcall *call,
+ bool mask_p)
{
tree rhs = gimple_call_arg (call, 3);
- if (tree lhs = gimple_fold_mask_load_store_mem_ref (call, TREE_TYPE (rhs)))
+ if (tree lhs
+ = gimple_fold_partial_load_store_mem_ref (call, TREE_TYPE (rhs), mask_p))
{
gassign *new_stmt = gimple_build_assign (lhs, rhs);
gimple_set_location (new_stmt, gimple_location (call));
@@ -5635,10 +5658,16 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
cplx_result = true;
break;
case IFN_MASK_LOAD:
- changed |= gimple_fold_mask_load (gsi, stmt);
+ changed |= gimple_fold_partial_load (gsi, stmt, true);
break;
case IFN_MASK_STORE:
- changed |= gimple_fold_mask_store (gsi, stmt);
+ changed |= gimple_fold_partial_store (gsi, stmt, true);
+ break;
+ case IFN_LEN_LOAD:
+ changed |= gimple_fold_partial_load (gsi, stmt, false);
+ break;
+ case IFN_LEN_STORE:
+ changed |= gimple_fold_partial_store (gsi, stmt, false);
break;
default:
break;
@@ -6887,6 +6916,7 @@ and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
}
static basic_block fosa_bb;
+static vec<std::pair<tree, void *> > *fosa_unwind;
static tree
follow_outer_ssa_edges (tree val)
{
@@ -6900,7 +6930,21 @@ follow_outer_ssa_edges (tree val)
&& (def_bb == fosa_bb
|| dominated_by_p (CDI_DOMINATORS, fosa_bb, def_bb))))
return val;
- return NULL_TREE;
+ /* We cannot temporarily rewrite stmts with undefined overflow
+ behavior, so avoid expanding them. */
+ if ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (val))
+ || POINTER_TYPE_P (TREE_TYPE (val)))
+ && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (val)))
+ return NULL_TREE;
+ /* If the definition does not dominate fosa_bb temporarily reset
+ flow-sensitive info. */
+ if (val->ssa_name.info.range_info)
+ {
+ fosa_unwind->safe_push (std::make_pair
+ (val, val->ssa_name.info.range_info));
+ val->ssa_name.info.range_info = NULL;
+ }
+ return val;
}
return val;
}
@@ -6959,9 +7003,14 @@ maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code,
type, gimple_assign_lhs (stmt1),
gimple_assign_lhs (stmt2));
fosa_bb = outer_cond_bb;
+ auto_vec<std::pair<tree, void *>, 8> unwind_stack;
+ fosa_unwind = &unwind_stack;
if (op.resimplify (NULL, (!outer_cond_bb
? follow_all_ssa_edges : follow_outer_ssa_edges)))
{
+ fosa_unwind = NULL;
+ for (auto p : unwind_stack)
+ p.first->ssa_name.info.range_info = p.second;
if (gimple_simplified_result_is_gimple_val (&op))
{
tree res = op.ops[0];
@@ -6983,6 +7032,9 @@ maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code,
return build2 ((enum tree_code)op.code, op.type, op0, op1);
}
}
+ fosa_unwind = NULL;
+ for (auto p : unwind_stack)
+ p.first->ssa_name.info.range_info = p.second;
return NULL_TREE;
}
@@ -9182,6 +9234,15 @@ bool
gimple_stmt_nonnegative_warnv_p (gimple *stmt, bool *strict_overflow_p,
int depth)
{
+ tree type = gimple_range_type (stmt);
+ if (type && frange::supports_p (type))
+ {
+ frange r;
+ bool sign;
+ if (get_global_range_query ()->range_of_stmt (r, stmt)
+ && r.signbit_p (sign))
+ return !sign;
+ }
switch (gimple_code (stmt))
{
case GIMPLE_ASSIGN:
diff --git a/gcc/gimple-fold.h b/gcc/gimple-fold.h
index 7d29ee9..87ed4e5 100644
--- a/gcc/gimple-fold.h
+++ b/gcc/gimple-fold.h
@@ -63,6 +63,7 @@ extern bool arith_code_with_undefined_signed_overflow (tree_code);
extern gimple_seq rewrite_to_defined_overflow (gimple *, bool = false);
extern void replace_call_with_value (gimple_stmt_iterator *, tree);
extern tree tree_vec_extract (gimple_stmt_iterator *, tree, tree, tree, tree);
+extern void gsi_replace_with_seq_vops (gimple_stmt_iterator *, gimple_seq);
/* gimple_build, functionally matching fold_buildN, outputs stmts
int the provided sequence, matching and simplifying them on-the-fly.
diff --git a/gcc/gimple-low.cc b/gcc/gimple-low.cc
index 512aa9f..53df2e7 100644
--- a/gcc/gimple-low.cc
+++ b/gcc/gimple-low.cc
@@ -84,6 +84,7 @@ static void lower_try_catch (gimple_stmt_iterator *, struct lower_data *);
static void lower_gimple_return (gimple_stmt_iterator *, struct lower_data *);
static void lower_builtin_setjmp (gimple_stmt_iterator *);
static void lower_builtin_posix_memalign (gimple_stmt_iterator *);
+static void lower_builtin_assume_aligned (gimple_stmt_iterator *);
/* Lower the body of current_function_decl from High GIMPLE into Low
@@ -768,6 +769,14 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
lower_builtin_posix_memalign (gsi);
return;
}
+ else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_ASSUME_ALIGNED
+ && !optimize)
+ {
+ lower_builtin_assume_aligned (gsi);
+ data->cannot_fallthru = false;
+ gsi_next (gsi);
+ return;
+ }
}
if (decl && (flags_from_decl_or_type (decl) & ECF_NORETURN))
@@ -1310,6 +1319,38 @@ lower_builtin_posix_memalign (gimple_stmt_iterator *gsi)
gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
gsi_insert_after (gsi, gimple_build_label (noalign_label), GSI_NEW_STMT);
}
+
+/* Lower calls to __builtin_assume_aligned when not optimizing. */
+
+static void
+lower_builtin_assume_aligned (gimple_stmt_iterator *gsi)
+{
+ gcall *call = as_a <gcall *> (gsi_stmt (*gsi));
+
+ tree lhs = gimple_call_lhs (call);
+ if (!lhs || !POINTER_TYPE_P (TREE_TYPE (lhs)) || TREE_CODE (lhs) != SSA_NAME)
+ return;
+
+ tree align = gimple_call_arg (call, 1);
+ tree misalign = (gimple_call_num_args (call) > 2
+ ? gimple_call_arg (call, 2) : NULL_TREE);
+ if (!tree_fits_uhwi_p (align)
+ || (misalign && !tree_fits_uhwi_p (misalign)))
+ return;
+
+ unsigned aligni = TREE_INT_CST_LOW (align);
+ unsigned misaligni = misalign ? TREE_INT_CST_LOW (misalign) : 0;
+ if (aligni <= 1
+ || (aligni & (aligni - 1)) != 0
+ || (misaligni & ~(aligni - 1)) != 0)
+ return;
+
+ /* For lowering we simply transfer alignment information to the
+ result and leave the call otherwise unchanged, it will be elided
+ at RTL expansion time. */
+ ptr_info_def *pi = get_ptr_info (lhs);
+ set_ptr_info_alignment (pi, aligni, misaligni);
+}
/* Record the variables in VARS into function FN. */
diff --git a/gcc/gimple-match-head.cc b/gcc/gimple-match-head.cc
index 4c80d77..9986e34 100644
--- a/gcc/gimple-match-head.cc
+++ b/gcc/gimple-match-head.cc
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "dbgcnt.h"
#include "tm.h"
#include "gimple-range.h"
+#include "langhooks.h"
/* Forward declarations of the private auto-generated matchers.
They expect valueized operands in canonical order and do not
diff --git a/gcc/gimple-predicate-analysis.cc b/gcc/gimple-predicate-analysis.cc
index 5013a44..afe01e7 100644
--- a/gcc/gimple-predicate-analysis.cc
+++ b/gcc/gimple-predicate-analysis.cc
@@ -42,6 +42,7 @@
#include "value-query.h"
#include "cfganal.h"
#include "tree-eh.h"
+#include "gimple-fold.h"
#include "gimple-predicate-analysis.h"
@@ -1174,7 +1175,9 @@ compute_control_dep_chain (basic_block dom_bb, const_basic_block dep_bb,
/* Implemented simplifications:
- 1) ((x IOR y) != 0) AND (x != 0) is equivalent to (x != 0);
+ 1a) ((x IOR y) != 0) AND (x != 0) is equivalent to (x != 0);
+ 1b) [!](X rel y) AND [!](X rel y') where y == y' or both constant
+ can possibly be simplified
2) (X AND Y) OR (!X AND Y) is equivalent to Y;
3) X OR (!X AND Y) is equivalent to (X OR Y);
4) ((x IAND y) != 0) || (x != 0 AND y != 0)) is equivalent to
@@ -1184,11 +1187,11 @@ compute_control_dep_chain (basic_block dom_bb, const_basic_block dep_bb,
PREDS is the predicate chains, and N is the number of chains. */
-/* Implement rule 1 above. PREDS is the AND predicate to simplify
+/* Implement rule 1a above. PREDS is the AND predicate to simplify
in place. */
static void
-simplify_1 (pred_chain &chain)
+simplify_1a (pred_chain &chain)
{
bool simplified = false;
pred_chain s_chain = vNULL;
@@ -1245,6 +1248,68 @@ simplify_1 (pred_chain &chain)
chain = s_chain;
}
+/* Implement rule 1b above. PREDS is the AND predicate to simplify
+ in place. Returns true if CHAIN simplifies to true or false. */
+
+static bool
+simplify_1b (pred_chain &chain)
+{
+ for (unsigned i = 0; i < chain.length (); i++)
+ {
+ pred_info &a_pred = chain[i];
+
+ for (unsigned j = i + 1; j < chain.length (); ++j)
+ {
+ pred_info &b_pred = chain[j];
+
+ if (!operand_equal_p (a_pred.pred_lhs, b_pred.pred_lhs)
+ || (!operand_equal_p (a_pred.pred_rhs, b_pred.pred_rhs)
+ && !(CONSTANT_CLASS_P (a_pred.pred_rhs)
+ && CONSTANT_CLASS_P (b_pred.pred_rhs))))
+ continue;
+
+ tree_code a_code = a_pred.cond_code;
+ if (a_pred.invert)
+ a_code = invert_tree_comparison (a_code, false);
+ tree_code b_code = b_pred.cond_code;
+ if (b_pred.invert)
+ b_code = invert_tree_comparison (b_code, false);
+ /* Try to combine X a_code Y && X b_code Y'. */
+ tree comb = maybe_fold_and_comparisons (boolean_type_node,
+ a_code,
+ a_pred.pred_lhs,
+ a_pred.pred_rhs,
+ b_code,
+ b_pred.pred_lhs,
+ b_pred.pred_rhs, NULL);
+ if (!comb)
+ ;
+ else if (integer_zerop (comb))
+ return true;
+ else if (integer_truep (comb))
+ {
+ chain.ordered_remove (j);
+ chain.ordered_remove (i);
+ if (chain.is_empty ())
+ return true;
+ i--;
+ break;
+ }
+ else if (COMPARISON_CLASS_P (comb)
+ && operand_equal_p (a_pred.pred_lhs, TREE_OPERAND (comb, 0)))
+ {
+ chain.ordered_remove (j);
+ a_pred.cond_code = TREE_CODE (comb);
+ a_pred.pred_rhs = TREE_OPERAND (comb, 1);
+ a_pred.invert = false;
+ j--;
+ }
+ }
+ }
+
+ return false;
+}
+
/* Implements rule 2 for the OR predicate PREDS:
2) (X AND Y) OR (!X AND Y) is equivalent to Y. */
@@ -1257,64 +1322,49 @@ predicate::simplify_2 ()
/* (X AND Y) OR (!X AND Y) is equivalent to Y.
(X AND Y) OR (X AND !Y) is equivalent to X. */
- unsigned n = m_preds.length ();
- for (unsigned i = 0; i < n; i++)
+ for (unsigned i = 0; i < m_preds.length (); i++)
{
pred_chain &a_chain = m_preds[i];
- if (a_chain.length () != 2)
- continue;
- /* Create copies since the chain may be released below before
- the copy is added to the other chain. */
- const pred_info x = a_chain[0];
- const pred_info y = a_chain[1];
-
- for (unsigned j = 0; j < n; j++)
+ for (unsigned j = i + 1; j < m_preds.length (); j++)
{
- if (j == i)
- continue;
-
pred_chain &b_chain = m_preds[j];
- if (b_chain.length () != 2)
+ if (b_chain.length () != a_chain.length ())
continue;
- const pred_info &x2 = b_chain[0];
- const pred_info &y2 = b_chain[1];
-
- if (pred_equal_p (x, x2) && pred_neg_p (y, y2))
+ unsigned neg_idx = -1U;
+ for (unsigned k = 0; k < a_chain.length (); ++k)
{
- /* Kill a_chain. */
- b_chain.release ();
- a_chain.release ();
- b_chain.safe_push (x);
- simplified = true;
- break;
+ if (pred_equal_p (a_chain[k], b_chain[k]))
+ continue;
+ if (neg_idx != -1U)
+ {
+ neg_idx = -1U;
+ break;
+ }
+ if (pred_neg_p (a_chain[k], b_chain[k]))
+ neg_idx = k;
+ else
+ break;
}
- if (pred_neg_p (x, x2) && pred_equal_p (y, y2))
+ /* If we found equal chains with one negated predicate
+ simplify. */
+ if (neg_idx != -1U)
{
- /* Kill a_chain. */
- a_chain.release ();
- b_chain.release ();
- b_chain.safe_push (y);
+ a_chain.ordered_remove (neg_idx);
+ m_preds.ordered_remove (j);
simplified = true;
+ if (a_chain.is_empty ())
+ {
+ /* A && !A simplifies to true, wipe the whole predicate. */
+ for (unsigned k = 0; k < m_preds.length (); ++k)
+ m_preds[k].release ();
+ m_preds.truncate (0);
+ }
break;
}
}
}
- /* Now clean up the chain. */
- if (simplified)
- {
- pred_chain_union s_preds = vNULL;
- for (unsigned i = 0; i < n; i++)
- {
- if (m_preds[i].is_empty ())
- continue;
- s_preds.safe_push (m_preds[i]);
- }
- m_preds.release ();
- m_preds = s_preds;
- s_preds = vNULL;
- }
return simplified;
}
@@ -1450,11 +1500,18 @@ predicate::simplify (gimple *use_or_def, bool is_use)
dump (dump_file, use_or_def, is_use ? "[USE]:\n" : "[DEF]:\n");
}
- unsigned n = m_preds.length ();
- for (unsigned i = 0; i < n; i++)
- ::simplify_1 (m_preds[i]);
+ for (unsigned i = 0; i < m_preds.length (); i++)
+ {
+ ::simplify_1a (m_preds[i]);
+ if (::simplify_1b (m_preds[i]))
+ {
+ m_preds[i].release ();
+ m_preds.ordered_remove (i);
+ i--;
+ }
+ }
- if (n < 2)
+ if (m_preds.length () < 2)
return;
bool changed;
@@ -1665,10 +1722,11 @@ predicate::normalize (const pred_chain &chain)
while (!work_list.is_empty ())
{
pred_info pi = work_list.pop ();
- predicate pred;
/* The predicate object is not modified here, only NORM_CHAIN and
WORK_LIST are appended to. */
- pred.normalize (&norm_chain, pi, BIT_AND_EXPR, &work_list, &mark_set);
+ unsigned oldlen = m_preds.length ();
+ normalize (&norm_chain, pi, BIT_AND_EXPR, &work_list, &mark_set);
+ gcc_assert (m_preds.length () == oldlen);
}
m_preds.safe_push (norm_chain);
@@ -1686,7 +1744,7 @@ predicate::normalize (gimple *use_or_def, bool is_use)
dump (dump_file, use_or_def, is_use ? "[USE]:\n" : "[DEF]:\n");
}
- predicate norm_preds;
+ predicate norm_preds (empty_val ());
for (unsigned i = 0; i < m_preds.length (); i++)
{
if (m_preds[i].length () != 1)
@@ -2022,6 +2080,8 @@ predicate::operator= (const predicate &rhs)
if (this == &rhs)
return *this;
+ m_cval = rhs.m_cval;
+
unsigned n = m_preds.length ();
for (unsigned i = 0; i != n; ++i)
m_preds[i].release ();
@@ -2150,11 +2210,15 @@ uninit_analysis::is_use_guarded (gimple *use_stmt, basic_block use_bb,
/* Try to build the predicate expression under which the PHI flows
into its use. This will be empty if the PHI is defined and used
in the same bb. */
- predicate use_preds;
+ predicate use_preds (true);
if (!init_use_preds (use_preds, def_bb, use_bb))
return false;
use_preds.simplify (use_stmt, /*is_use=*/true);
+ if (use_preds.is_false ())
+ return true;
+ if (use_preds.is_true ())
+ return false;
use_preds.normalize (use_stmt, /*is_use=*/true);
/* Try to prune the dead incoming phi edges. */
@@ -2173,6 +2237,10 @@ uninit_analysis::is_use_guarded (gimple *use_stmt, basic_block use_bb,
return false;
m_phi_def_preds.simplify (phi);
+ if (m_phi_def_preds.is_false ())
+ return false;
+ if (m_phi_def_preds.is_true ())
+ return true;
m_phi_def_preds.normalize (phi);
}
diff --git a/gcc/gimple-predicate-analysis.h b/gcc/gimple-predicate-analysis.h
index 972af5e..c4a7ed5 100644
--- a/gcc/gimple-predicate-analysis.h
+++ b/gcc/gimple-predicate-analysis.h
@@ -45,7 +45,7 @@ class predicate
{
public:
/* Construct with the specified EVAL object. */
- predicate () : m_preds (vNULL) { }
+ predicate (bool empty_val) : m_preds (vNULL), m_cval (empty_val) { }
/* Copy. */
predicate (const predicate &rhs) : m_preds (vNULL) { *this = rhs; }
@@ -60,6 +60,21 @@ class predicate
return m_preds.is_empty ();
}
+ bool is_true () const
+ {
+ return is_empty () && m_cval;
+ }
+
+ bool is_false () const
+ {
+ return is_empty () && !m_cval;
+ }
+
+ bool empty_val () const
+ {
+ return m_cval;
+ }
+
const pred_chain_union chain () const
{
return m_preds;
@@ -92,8 +107,10 @@ private:
bool simplify_3 ();
bool simplify_4 ();
- /* Representation of the predicate expression(s). */
+ /* Representation of the predicate expression(s). The predicate is
+ m_cval || m_preds[0] || ... */
pred_chain_union m_preds;
+ bool m_cval;
};
/* Represents a complex Boolean predicate expression. */
@@ -119,7 +136,7 @@ class uninit_analysis
/* Construct with the specified EVAL object. */
uninit_analysis (func_t &eval)
- : m_phi_def_preds (), m_eval (eval) { }
+ : m_phi_def_preds (false), m_eval (eval) { }
/* Copy. */
uninit_analysis (const uninit_analysis &rhs) = delete;
diff --git a/gcc/gimple-pretty-print.cc b/gcc/gimple-pretty-print.cc
index 7ec079f..af70425 100644
--- a/gcc/gimple-pretty-print.cc
+++ b/gcc/gimple-pretty-print.cc
@@ -339,7 +339,6 @@ dump_unary_rhs (pretty_printer *buffer, const gassign *gs, int spc,
switch (rhs_code)
{
case VIEW_CONVERT_EXPR:
- case ASSERT_EXPR:
dump_generic_node (buffer, rhs, spc, flags, false);
break;
diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index 89e2403..ce5a0c8 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -1544,8 +1544,27 @@ ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb,
return true;
}
-// This routine is used during a block walk to move the state of non-null for
-// any operands on stmt S to nonnull.
+// This routine will register an inferred value in block BB, and possibly
+// update the on-entry cache if appropriate.
+
+void
+ranger_cache::register_inferred_value (const vrange &ir, tree name,
+ basic_block bb)
+{
+ Value_Range r (TREE_TYPE (name));
+ if (!m_on_entry.get_bb_range (r, name, bb))
+ exit_range (r, name, bb, RFD_READ_ONLY);
+ if (r.intersect (ir))
+ {
+ m_on_entry.set_bb_range (name, bb, r);
+ // If this range was invariant before, remove invariance.
+ if (!m_gori.has_edge_range_p (name))
+ m_gori.set_range_invariant (name, false);
+ }
+}
+
+// This routine is used during a block walk to adjust any inferred ranges
+// of operands on stmt S.
void
ranger_cache::apply_inferred_ranges (gimple *s)
@@ -1574,17 +1593,6 @@ ranger_cache::apply_inferred_ranges (gimple *s)
tree name = infer.name (x);
m_exit.add_range (name, bb, infer.range (x));
if (update)
- {
- Value_Range r (TREE_TYPE (name));
- if (!m_on_entry.get_bb_range (r, name, bb))
- exit_range (r, name, bb, RFD_READ_ONLY);
- if (r.intersect (infer.range (x)))
- {
- m_on_entry.set_bb_range (name, bb, r);
- // If this range was invariant before, remove invariance.
- if (!m_gori.has_edge_range_p (name))
- m_gori.set_range_invariant (name, false);
- }
- }
+ register_inferred_value (infer.range (x), name, bb);
}
}
diff --git a/gcc/gimple-range-cache.h b/gcc/gimple-range-cache.h
index 45053b5..8e3ae8f 100644
--- a/gcc/gimple-range-cache.h
+++ b/gcc/gimple-range-cache.h
@@ -87,6 +87,7 @@ public:
void propagate_updated_value (tree name, basic_block bb);
+ void register_inferred_value (const vrange &r, tree name, basic_block bb);
void apply_inferred_ranges (gimple *s);
gori_compute m_gori;
infer_range_manager m_exit;
diff --git a/gcc/gimple-range-infer.cc b/gcc/gimple-range-infer.cc
index 010b34a..8714ef2 100644
--- a/gcc/gimple-range-infer.cc
+++ b/gcc/gimple-range-infer.cc
@@ -252,6 +252,17 @@ infer_range_manager::get_nonzero (tree name)
return *(m_nonzero[v]);
}
+// Return TRUE if there are any range inferences in block BB.
+
+bool
+infer_range_manager::has_range_p (basic_block bb)
+{
+ if (bb->index >= (int)m_on_exit.length ())
+ return false;
+ bitmap b = m_on_exit[bb->index].m_names;
+ return b && !bitmap_empty_p (b);
+}
+
// Return TRUE if NAME has a range inference in block BB.
bool
diff --git a/gcc/gimple-range-infer.h b/gcc/gimple-range-infer.h
index adfe1fd..10705e0 100644
--- a/gcc/gimple-range-infer.h
+++ b/gcc/gimple-range-infer.h
@@ -62,6 +62,7 @@ public:
void add_range (tree name, basic_block bb, const vrange &r);
void add_nonzero (tree name, basic_block bb);
bool has_range_p (tree name, basic_block bb);
+ bool has_range_p (basic_block bb);
bool maybe_adjust_range (vrange &r, tree name, basic_block bb);
private:
class exit_range_head
diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc
index 7764166..1206854 100644
--- a/gcc/gimple-range-op.cc
+++ b/gcc/gimple-range-op.cc
@@ -148,6 +148,9 @@ gimple_range_op_handler::gimple_range_op_handler (gimple *s)
case GIMPLE_COND:
m_op1 = gimple_cond_lhs (m_stmt);
m_op2 = gimple_cond_rhs (m_stmt);
+ // Check that operands are supported types. One check is enough.
+ if (!Value_Range::supports_type_p (TREE_TYPE (m_op1)))
+ m_valid = false;
return;
case GIMPLE_ASSIGN:
m_op1 = gimple_range_base_of_assignment (m_stmt);
@@ -164,6 +167,9 @@ gimple_range_op_handler::gimple_range_op_handler (gimple *s)
}
if (gimple_num_ops (m_stmt) >= 3)
m_op2 = gimple_assign_rhs2 (m_stmt);
+ // Check that operands are supported types. One check is enough.
+ if ((m_op1 && !Value_Range::supports_type_p (TREE_TYPE (m_op1))))
+ m_valid = false;
return;
default:
gcc_unreachable ();
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 110cf57..8c05582 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -422,18 +422,20 @@ gimple_ranger::prefill_stmt_dependencies (tree ssa)
else
{
gimple_range_op_handler handler (stmt);
- gcc_checking_assert (handler);
- tree op = handler.operand2 ();
- if (op)
+ if (handler)
{
- Value_Range r (TREE_TYPE (op));
- prefill_name (r, op);
- }
- op = handler.operand1 ();
- if (op)
- {
- Value_Range r (TREE_TYPE (op));
- prefill_name (r, op);
+ tree op = handler.operand2 ();
+ if (op)
+ {
+ Value_Range r (TREE_TYPE (op));
+ prefill_name (r, op);
+ }
+ op = handler.operand1 ();
+ if (op)
+ {
+ Value_Range r (TREE_TYPE (op));
+ prefill_name (r, op);
+ }
}
}
}
@@ -482,6 +484,88 @@ gimple_ranger::register_inferred_ranges (gimple *s)
m_cache.apply_inferred_ranges (s);
}
+// This function will walk the statements in BB to determine if any
+// discovered inferred ranges in the block have any transitive effects,
+// and if so, register those effects in BB.
+
+void
+gimple_ranger::register_transitive_inferred_ranges (basic_block bb)
+{
+ // Return if there are no inferred ranges in BB.
+ infer_range_manager &infer = m_cache.m_exit;
+ if (!infer.has_range_p (bb))
+ return;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Checking for transitive inferred ranges in BB %d\n",
+ bb->index);
+
+ for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si);
+ gsi_next (&si))
+ {
+ gimple *s = gsi_stmt (si);
+ tree lhs = gimple_get_lhs (s);
+ // If the LHS alreayd has an inferred effect, leave it be.
+ if (!gimple_range_ssa_p (lhs) || infer.has_range_p (lhs, bb))
+ continue;
+ // Pick up global value.
+ Value_Range g (TREE_TYPE (lhs));
+ range_of_expr (g, lhs);
+
+ // If either dependency has an inferred range, check if recalculating
+ // the LHS is different than the global value. If so, register it as
+ // an inferred range as well.
+ Value_Range r (TREE_TYPE (lhs));
+ r.set_undefined ();
+ tree name1 = gori ().depend1 (lhs);
+ tree name2 = gori ().depend2 (lhs);
+ if ((name1 && infer.has_range_p (name1, bb))
+ || (name2 && infer.has_range_p (name2, bb)))
+ {
+ // Check if folding S produces a different result.
+ if (fold_range (r, s, this) && g != r)
+ {
+ infer.add_range (lhs, bb, r);
+ m_cache.register_inferred_value (r, lhs, bb);
+ }
+ }
+ }
+}
+
+// When a statement S has changed since the result was cached, re-evaluate
+// and update the global cache.
+
+void
+gimple_ranger::update_stmt (gimple *s)
+{
+ tree lhs = gimple_get_lhs (s);
+ if (!lhs || !gimple_range_ssa_p (lhs))
+ return;
+ Value_Range r (TREE_TYPE (lhs));
+ // Only update if it already had a value.
+ if (m_cache.get_global_range (r, lhs))
+ {
+ // Re-calculate a new value using just cache values.
+ Value_Range tmp (TREE_TYPE (lhs));
+ fold_using_range f;
+ fur_stmt src (s, &m_cache);
+ f.fold_stmt (tmp, s, src, lhs);
+
+ // Combine the new value with the old value to check for a change.
+ if (r.intersect (tmp))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ print_generic_expr (dump_file, lhs, TDF_SLIM);
+ fprintf (dump_file, " : global value re-evaluated to ");
+ r.dump (dump_file);
+ fputc ('\n', dump_file);
+ }
+ m_cache.set_global_range (lhs, r);
+ }
+ }
+}
+
// This routine will export whatever global ranges are known to GCC
// SSA_RANGE_NAME_INFO and SSA_NAME_PTR_INFO fields.
diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h
index 4800bfb..dfe8199b 100644
--- a/gcc/gimple-range.h
+++ b/gcc/gimple-range.h
@@ -51,6 +51,7 @@ public:
virtual bool range_of_stmt (vrange &r, gimple *, tree name = NULL) override;
virtual bool range_of_expr (vrange &r, tree name, gimple * = NULL) override;
virtual bool range_on_edge (vrange &r, edge e, tree name) override;
+ virtual void update_stmt (gimple *) override;
void range_on_entry (vrange &r, basic_block bb, tree name);
void range_on_exit (vrange &r, basic_block bb, tree name);
void export_global_ranges ();
@@ -61,6 +62,7 @@ public:
auto_edge_flag non_executable_edge_flag;
bool fold_stmt (gimple_stmt_iterator *gsi, tree (*) (tree));
void register_inferred_ranges (gimple *s);
+ void register_transitive_inferred_ranges (basic_block bb);
protected:
bool fold_range_internal (vrange &r, gimple *s, tree name);
void prefill_name (vrange &r, tree name);
diff --git a/gcc/gimple-ssa-sprintf.cc b/gcc/gimple-ssa-sprintf.cc
index a888b5a..1dd9b0d 100644
--- a/gcc/gimple-ssa-sprintf.cc
+++ b/gcc/gimple-ssa-sprintf.cc
@@ -535,6 +535,8 @@ fmtresult::type_max_digits (tree type, int base)
unsigned prec = TYPE_PRECISION (type);
switch (base)
{
+ case 2:
+ return prec;
case 8:
return (prec + 2) / 3;
case 10:
@@ -804,9 +806,9 @@ ilog (unsigned HOST_WIDE_INT x, int base)
/* Return the number of bytes resulting from converting into a string
the INTEGER_CST tree node X in BASE with a minimum of PREC digits.
PLUS indicates whether 1 for a plus sign should be added for positive
- numbers, and PREFIX whether the length of an octal ('O') or hexadecimal
- ('0x') prefix should be added for nonzero numbers. Return -1 if X cannot
- be represented. */
+ numbers, and PREFIX whether the length of an octal ('0') or hexadecimal
+ ('0x') or binary ('0b') prefix should be added for nonzero numbers.
+ Return -1 if X cannot be represented. */
static HOST_WIDE_INT
tree_digits (tree x, int base, HOST_WIDE_INT prec, bool plus, bool prefix)
@@ -857,11 +859,11 @@ tree_digits (tree x, int base, HOST_WIDE_INT prec, bool plus, bool prefix)
/* Adjust a non-zero value for the base prefix, either hexadecimal,
or, unless precision has resulted in a leading zero, also octal. */
- if (prefix && absval && (base == 16 || prec <= ndigs))
+ if (prefix && absval)
{
- if (base == 8)
+ if (base == 8 && prec <= ndigs)
res += 1;
- else if (base == 16)
+ else if (base == 16 || base == 2) /* 0x...(0X...) or 0b...(0B...). */
res += 2;
}
@@ -1209,7 +1211,7 @@ format_integer (const directive &dir, tree arg, pointer_query &ptr_qry)
/* True when a conversion is preceded by a prefix indicating the base
of the argument (octal or hexadecimal). */
- bool maybebase = dir.get_flag ('#');
+ const bool maybebase = dir.get_flag ('#');
/* True when a signed conversion is preceded by a sign or space. */
bool maybesign = false;
@@ -1229,6 +1231,10 @@ format_integer (const directive &dir, tree arg, pointer_query &ptr_qry)
case 'u':
base = 10;
break;
+ case 'b':
+ case 'B':
+ base = 2;
+ break;
case 'o':
base = 8;
break;
@@ -1240,6 +1246,8 @@ format_integer (const directive &dir, tree arg, pointer_query &ptr_qry)
gcc_unreachable ();
}
+ const unsigned adj = (sign | maybebase) + (base == 2 || base == 16);
+
/* The type of the "formal" argument expected by the directive. */
tree dirtype = NULL_TREE;
@@ -1350,11 +1358,9 @@ format_integer (const directive &dir, tree arg, pointer_query &ptr_qry)
res.range.unlikely = res.range.max;
/* Bump up the counters if WIDTH is greater than LEN. */
- res.adjust_for_width_or_precision (dir.width, dirtype, base,
- (sign | maybebase) + (base == 16));
+ res.adjust_for_width_or_precision (dir.width, dirtype, base, adj);
/* Bump up the counters again if PRECision is greater still. */
- res.adjust_for_width_or_precision (dir.prec, dirtype, base,
- (sign | maybebase) + (base == 16));
+ res.adjust_for_width_or_precision (dir.prec, dirtype, base, adj);
return res;
}
@@ -1503,17 +1509,15 @@ format_integer (const directive &dir, tree arg, pointer_query &ptr_qry)
if (res.range.min == 1)
res.range.likely += base == 8 ? 1 : 2;
else if (res.range.min == 2
- && base == 16
+ && (base == 16 || base == 2)
&& (dir.width[0] == 2 || dir.prec[0] == 2))
++res.range.likely;
}
}
res.range.unlikely = res.range.max;
- res.adjust_for_width_or_precision (dir.width, dirtype, base,
- (sign | maybebase) + (base == 16));
- res.adjust_for_width_or_precision (dir.prec, dirtype, base,
- (sign | maybebase) + (base == 16));
+ res.adjust_for_width_or_precision (dir.width, dirtype, base, adj);
+ res.adjust_for_width_or_precision (dir.prec, dirtype, base, adj);
return res;
}
@@ -3725,6 +3729,11 @@ parse_directive (call_info &info,
dir.fmtfunc = format_integer;
break;
+ case 'b':
+ case 'B':
+ dir.fmtfunc = format_integer;
+ break;
+
case 'p':
/* The %p output is implementation-defined. It's possible
to determine this format but due to extensions (especially
diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
index 59a7053..854e47c 100644
--- a/gcc/gimple-ssa-warn-access.cc
+++ b/gcc/gimple-ssa-warn-access.cc
@@ -2127,7 +2127,6 @@ private:
/* Return the argument that a call returns. */
tree gimple_call_return_arg (gcall *);
- tree gimple_call_return_arg_ref (gcall *);
/* Check a call for uses of a dangling pointer arguments. */
void check_call_dangling (gcall *);
@@ -4460,24 +4459,6 @@ pass_waccess::gimple_call_return_arg (gcall *call)
return gimple_call_arg (call, argno);
}
-/* Return the decl referenced by the argument that the call STMT to
- a built-in function returns (including with an offset) or null if
- it doesn't. */
-
-tree
-pass_waccess::gimple_call_return_arg_ref (gcall *call)
-{
- if (tree arg = gimple_call_return_arg (call))
- {
- access_ref aref;
- if (m_ptr_qry.get_ref (arg, call, &aref, 0)
- && DECL_P (aref.ref))
- return aref.ref;
- }
-
- return NULL_TREE;
-}
-
/* Check for and diagnose all uses of the dangling pointer VAR to the auto
object DECL whose lifetime has ended. OBJREF is true when VAR denotes
an access to a DECL that may have been clobbered. */
@@ -4646,11 +4627,10 @@ pass_waccess::check_dangling_uses ()
unsigned i;
FOR_EACH_SSA_NAME (i, var, m_func)
{
- /* For each SSA_NAME pointer VAR find the DECL it points to.
- If the DECL is a clobbered local variable, check to see
+ /* For each SSA_NAME pointer VAR find the object it points to.
+ If the object is a clobbered local variable, check to see
if any of VAR's uses (or those of other pointers derived
from VAR) happens after the clobber. If so, warn. */
- tree decl = NULL_TREE;
gimple *def_stmt = SSA_NAME_DEF_STMT (var);
if (is_gimple_assign (def_stmt))
@@ -4660,23 +4640,30 @@ pass_waccess::check_dangling_uses ()
{
if (!POINTER_TYPE_P (TREE_TYPE (var)))
continue;
- decl = TREE_OPERAND (rhs, 0);
+ check_dangling_uses (var, TREE_OPERAND (rhs, 0));
}
else
{
/* For other expressions, check the base DECL to see
if it's been clobbered, most likely as a result of
inlining a reference to it. */
- decl = get_base_address (rhs);
+ tree decl = get_base_address (rhs);
if (DECL_P (decl))
check_dangling_uses (var, decl, false, true);
- continue;
}
}
else if (POINTER_TYPE_P (TREE_TYPE (var)))
{
if (gcall *call = dyn_cast<gcall *>(def_stmt))
- decl = gimple_call_return_arg_ref (call);
+ {
+ if (tree arg = gimple_call_return_arg (call))
+ {
+ access_ref aref;
+ if (m_ptr_qry.get_ref (arg, call, &aref, 0)
+ && aref.deref < 0)
+ check_dangling_uses (var, aref.ref);
+ }
+ }
else if (gphi *phi = dyn_cast <gphi *>(def_stmt))
{
unsigned nargs = gimple_phi_num_args (phi);
@@ -4684,19 +4671,12 @@ pass_waccess::check_dangling_uses ()
{
access_ref aref;
tree arg = gimple_phi_arg_def (phi, i);
- if (!m_ptr_qry.get_ref (arg, phi, &aref, 0)
- || (aref.deref == 0
- && POINTER_TYPE_P (TREE_TYPE (aref.ref))))
- continue;
- check_dangling_uses (var, aref.ref, true);
+ if (m_ptr_qry.get_ref (arg, phi, &aref, 0)
+ && aref.deref < 0)
+ check_dangling_uses (var, aref.ref, true);
}
- continue;
}
- else
- continue;
}
-
- check_dangling_uses (var, decl);
}
}
diff --git a/gcc/gimple-ssa-warn-alloca.cc b/gcc/gimple-ssa-warn-alloca.cc
index 83a241a..dcc62ca 100644
--- a/gcc/gimple-ssa-warn-alloca.cc
+++ b/gcc/gimple-ssa-warn-alloca.cc
@@ -217,6 +217,7 @@ alloca_call_type (gimple *stmt, bool is_vla)
int_range_max r;
if (warn_limit_specified_p (is_vla)
&& TREE_CODE (len) == SSA_NAME
+ && types_compatible_p (TREE_TYPE (len), size_type_node)
&& get_range_query (cfun)->range_of_expr (r, len, stmt)
&& !r.varying_p ())
{
diff --git a/gcc/gimple-ssa-warn-restrict.cc b/gcc/gimple-ssa-warn-restrict.cc
index b7ed15c..107ba27 100644
--- a/gcc/gimple-ssa-warn-restrict.cc
+++ b/gcc/gimple-ssa-warn-restrict.cc
@@ -296,8 +296,9 @@ builtin_memref::builtin_memref (pointer_query &ptrqry, gimple *stmt, tree expr,
tree basetype = TREE_TYPE (base);
if (TREE_CODE (basetype) == ARRAY_TYPE)
{
- if (ref && array_at_struct_end_p (ref))
- ; /* Use the maximum possible offset for last member arrays. */
+ if (ref && array_ref_flexible_size_p (ref))
+ ; /* Use the maximum possible offset for an array that might
+ have flexible size. */
else if (tree basesize = TYPE_SIZE_UNIT (basetype))
if (TREE_CODE (basesize) == INTEGER_CST)
/* Size could be non-constant for a variable-length type such
@@ -1733,7 +1734,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict,
if (!oobref)
return no_warning;
- const opt_code opt = OPT_Warray_bounds;
+ const opt_code opt = OPT_Warray_bounds_;
/* Return true without issuing a warning. */
if (!do_warn)
return opt;
diff --git a/gcc/gimple.cc b/gcc/gimple.cc
index 6c23dd7..dd054e1 100644
--- a/gcc/gimple.cc
+++ b/gcc/gimple.cc
@@ -2408,7 +2408,6 @@ get_gimple_rhs_num_ops (enum tree_code code)
|| (SYM) == BIT_INSERT_EXPR) ? GIMPLE_TERNARY_RHS \
: ((SYM) == CONSTRUCTOR \
|| (SYM) == OBJ_TYPE_REF \
- || (SYM) == ASSERT_EXPR \
|| (SYM) == ADDR_EXPR \
|| (SYM) == WITH_SIZE_EXPR \
|| (SYM) == SSA_NAME) ? GIMPLE_SINGLE_RHS \
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index f06ce3c..250782b 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -3272,6 +3272,8 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
fallback | fb_lvalue);
ret = MIN (ret, tret);
+ if (ret == GS_ERROR)
+ return GS_ERROR;
/* Step 2a: if we have component references we do not support on
registers then make sure the base isn't a register. Of course
@@ -3709,6 +3711,9 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
is_gimple_call_addr, fb_rvalue);
+ if (ret == GS_ERROR)
+ return GS_ERROR;
+
nargs = call_expr_nargs (*expr_p);
/* Get argument types for verification. */
@@ -6049,6 +6054,9 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
location_t loc = EXPR_LOCATION (*expr_p);
gimple_stmt_iterator gsi;
+ if (error_operand_p (*from_p) || error_operand_p (*to_p))
+ return GS_ERROR;
+
gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
|| TREE_CODE (*expr_p) == INIT_EXPR);
@@ -15225,6 +15233,7 @@ computable_teams_clause (tree *tp, int *walk_subtrees, void *)
0 stands for clause not specified at all, use implementation default
-1 stands for value that can't be determined easily before entering
the target construct.
+ -2 means that no explicit teams construct was specified
If teams construct is not present at all, use 1 for num_teams
and 0 for thread_limit (only one team is involved, and the thread
limit is implementation defined. */
@@ -15243,7 +15252,7 @@ optimize_target_teams (tree target, gimple_seq *pre_p)
struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
if (teams == NULL_TREE)
- num_teams_upper = integer_one_node;
+ num_teams_upper = build_int_cst (integer_type_node, -2);
else
for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
{
diff --git a/gcc/ginclude/float.h b/gcc/ginclude/float.h
index bc5439d..172b9de 100644
--- a/gcc/ginclude/float.h
+++ b/gcc/ginclude/float.h
@@ -624,4 +624,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#endif /* __DEC32_MANT_DIG__ */
+#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
+#define __STDC_VERSION_FLOAT_H__ 202311L
+#endif
+
#endif /* _FLOAT_H___ */
diff --git a/gcc/ginclude/stdarg.h b/gcc/ginclude/stdarg.h
index c704c9f..5149f7b 100644
--- a/gcc/ginclude/stdarg.h
+++ b/gcc/ginclude/stdarg.h
@@ -125,6 +125,10 @@ typedef __gnuc_va_list va_list;
#endif /* not __svr4__ */
+#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
+#define __STDC_VERSION_STDARG_H__ 202311L
+#endif
+
#endif /* _STDARG_H */
#endif /* not _ANSI_STDARG_H_ */
diff --git a/gcc/ginclude/stdatomic.h b/gcc/ginclude/stdatomic.h
index a56ba5d..e16b072 100644
--- a/gcc/ginclude/stdatomic.h
+++ b/gcc/ginclude/stdatomic.h
@@ -248,4 +248,8 @@ extern void atomic_flag_clear (volatile atomic_flag *);
extern void atomic_flag_clear_explicit (volatile atomic_flag *, memory_order);
#define atomic_flag_clear_explicit(PTR, MO) __atomic_clear ((PTR), (MO))
+#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
+#define __STDC_VERSION_STDATOMIC_H__ 202311L
+#endif
+
#endif /* _STDATOMIC_H */
diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h
index 2767edf..7980045 100644
--- a/gcc/ginclude/stddef.h
+++ b/gcc/ginclude/stddef.h
@@ -454,6 +454,7 @@ typedef struct {
#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
#define unreachable() (__builtin_unreachable ())
+#define __STDC_VERSION_STDDEF_H__ 202311L
#endif
#endif /* _STDDEF_H was defined this time */
diff --git a/gcc/ginclude/stdint-gcc.h b/gcc/ginclude/stdint-gcc.h
index 6be01ae..eab651d 100644
--- a/gcc/ginclude/stdint-gcc.h
+++ b/gcc/ginclude/stdint-gcc.h
@@ -362,4 +362,8 @@ typedef __UINTMAX_TYPE__ uintmax_t;
#endif
+#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
+#define __STDC_VERSION_STDINT_H__ 202311L
+#endif
+
#endif /* _GCC_STDINT_H */
diff --git a/gcc/glimits.h b/gcc/glimits.h
index 8d74c8b..994f7e3 100644
--- a/gcc/glimits.h
+++ b/gcc/glimits.h
@@ -156,6 +156,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
# define BOOL_MAX 1
# undef BOOL_WIDTH
# define BOOL_WIDTH 1
+
+# define __STDC_VERSION_LIMITS_H__ 202311L
#endif
#endif /* _LIMITS_H___ */
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index 43cc2e0..93ad7af 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,160 @@
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/c-interoperability.rst: New file.
+ * doc/c-type-interoperability.rst: New file.
+ * doc/compiler-directives.rst: New file.
+ * doc/conf.py: New file.
+ * doc/copyright.rst: New file.
+ * doc/function-names.rst: New file.
+ * doc/general-public-license-3.rst: New file.
+ * doc/gnu-free-documentation-license.rst: New file.
+ * doc/import-and-export.rst: New file.
+ * doc/index.rst: New file.
+ * doc/indices-and-tables.rst: New file.
+ * doc/introduction.rst: New file.
+ * doc/invoking-gccgo.rst: New file.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support Sphinx based documentation.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * gccgo.texi: Removed.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support --with-sphinx-build.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in:
+ Support installation if sphinx-build is missing.
+ Support installation if sphinx-build is missing.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/c-interoperability.rst:
+ Add trailing newline.
+ * doc/c-type-interoperability.rst:
+ Add trailing newline.
+ * doc/compiler-directives.rst:
+ Add trailing newline.
+ * doc/copyright.rst:
+ Add trailing newline.
+ * doc/function-names.rst:
+ Add trailing newline.
+ * doc/general-public-license-3.rst:
+ Add trailing newline.
+ * doc/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/import-and-export.rst:
+ Add trailing newline.
+ * doc/index.rst:
+ Add trailing newline.
+ * doc/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/introduction.rst:
+ Add trailing newline.
+ * doc/invoking-gccgo.rst:
+ Add trailing newline.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/conf.py: Add newline at last line.
+
+2022-11-10 Martin Liska <mliska@suse.cz>
+
+ * doc/conf.py: Add newline at last line.
+
+2022-11-10 Ian Lance Taylor <iant@golang.org>
+
+ PR target/107581
+ * go-gcc.cc (Gcc_backend::Gcc_backend): Define
+ __atomic_fetch_add_{4,8}.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/c-interoperability.rst:
+ Add trailing newline.
+ * doc/c-type-interoperability.rst:
+ Add trailing newline.
+ * doc/compiler-directives.rst:
+ Add trailing newline.
+ * doc/copyright.rst:
+ Add trailing newline.
+ * doc/function-names.rst:
+ Add trailing newline.
+ * doc/general-public-license-3.rst:
+ Add trailing newline.
+ * doc/gnu-free-documentation-license.rst:
+ Add trailing newline.
+ * doc/import-and-export.rst:
+ Add trailing newline.
+ * doc/index.rst:
+ Add trailing newline.
+ * doc/indices-and-tables.rst:
+ Add trailing newline.
+ * doc/introduction.rst:
+ Add trailing newline.
+ * doc/invoking-gccgo.rst:
+ Add trailing newline.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in:
+ Support installation if sphinx-build is missing.
+ Support installation if sphinx-build is missing.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support --with-sphinx-build.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * gccgo.texi: Removed.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support Sphinx based documentation.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/c-interoperability.rst: New file.
+ * doc/c-type-interoperability.rst: New file.
+ * doc/compiler-directives.rst: New file.
+ * doc/conf.py: New file.
+ * doc/copyright.rst: New file.
+ * doc/function-names.rst: New file.
+ * doc/general-public-license-3.rst: New file.
+ * doc/gnu-free-documentation-license.rst: New file.
+ * doc/import-and-export.rst: New file.
+ * doc/index.rst: New file.
+ * doc/indices-and-tables.rst: New file.
+ * doc/introduction.rst: New file.
+ * doc/invoking-gccgo.rst: New file.
+
2022-09-15 Richard Biener <rguenther@suse.de>
* go-lang.cc (go_langhook_init): Do not initialize
@@ -6,7 +163,7 @@
2022-09-02 Martin Liska <mliska@suse.cz>
* go-lang.cc (go_langhook_pushdecl): Remove -gstabs option support, DBX-related
- macros and DBX debugging info support.
+ macros and DBX debugging info support.
* gospec.cc (lang_specific_driver): Likewise.
2022-07-16 Ian Lance Taylor <iant@golang.org>
@@ -79,7 +236,7 @@
2021-09-27 Martin Liska <mliska@suse.cz>
* go-lang.c (go_langhook_init_options_struct): Set also
- x_flag_default_complex_method.
+ x_flag_default_complex_method.
2021-06-29 Ian Lance Taylor <iant@golang.org>
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 1ba7206..6e5887a 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -886,16 +886,20 @@ Gcc_backend::Gcc_backend()
uint32_type_node,
integer_type_node,
NULL_TREE);
- this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_4, "__atomic_add_fetch_4", NULL,
- t, 0);
+ this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_4, "__atomic_add_fetch_4",
+ NULL, t, 0);
+ this->define_builtin(BUILT_IN_ATOMIC_FETCH_ADD_4, "__atomic_fetch_add_4",
+ NULL, t, 0);
t = build_function_type_list(uint64_type_node,
ptr_type_node,
uint64_type_node,
integer_type_node,
NULL_TREE);
- this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_8, "__atomic_add_fetch_8", NULL,
- t, 0);
+ this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_8, "__atomic_add_fetch_8",
+ NULL, t, 0);
+ this->define_builtin(BUILT_IN_ATOMIC_FETCH_ADD_8, "__atomic_fetch_add_8",
+ NULL, t, 0);
t = build_function_type_list(unsigned_char_type_node,
ptr_type_node,
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 7e531c3..d8c4e02 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-5e658f4659c551330ea68f5667e4f951b218f32d
+9906861dc86c1733bb304d3d45b1534adb32712c
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/graphite-sese-to-poly.cc b/gcc/graphite-sese-to-poly.cc
index 51ba3af..7eb24c1 100644
--- a/gcc/graphite-sese-to-poly.cc
+++ b/gcc/graphite-sese-to-poly.cc
@@ -536,9 +536,9 @@ bounds_are_valid (tree ref, tree low, tree high)
|| !tree_fits_shwi_p (high))
return false;
- /* 1-element arrays at end of structures may extend over
+ /* An array that has flexible size may extend over
their declared size. */
- if (array_at_struct_end_p (ref)
+ if (array_ref_flexible_size_p (ref)
&& operand_equal_p (low, high, 0))
return false;
diff --git a/gcc/input.cc b/gcc/input.cc
index a28abfa..18777a8 100644
--- a/gcc/input.cc
+++ b/gcc/input.cc
@@ -29,6 +29,12 @@ along with GCC; see the file COPYING3. If not see
#define HAVE_ICONV 0
#endif
+const char *
+special_fname_builtin ()
+{
+ return _("<built-in>");
+}
+
/* Input charset configuration. */
static const char *default_charset_callback (const char *)
{
@@ -275,7 +281,7 @@ expand_location_1 (location_t loc,
xloc.data = block;
if (loc <= BUILTINS_LOCATION)
- xloc.file = loc == UNKNOWN_LOCATION ? NULL : _("<built-in>");
+ xloc.file = loc == UNKNOWN_LOCATION ? NULL : special_fname_builtin ();
return xloc;
}
@@ -949,6 +955,98 @@ location_get_source_line (const char *file_path, int line)
return char_span (buffer, len);
}
+/* Return a NUL-terminated copy of the source text between two locations, or
+ NULL if the arguments are invalid. The caller is responsible for freeing
+ the return value. */
+
+char *
+get_source_text_between (location_t start, location_t end)
+{
+ expanded_location expstart =
+ expand_location_to_spelling_point (start, LOCATION_ASPECT_START);
+ expanded_location expend =
+ expand_location_to_spelling_point (end, LOCATION_ASPECT_FINISH);
+
+ /* If the locations are in different files or the end comes before the
+ start, give up and return nothing. */
+ if (!expstart.file || !expend.file)
+ return NULL;
+ if (strcmp (expstart.file, expend.file) != 0)
+ return NULL;
+ if (expstart.line > expend.line)
+ return NULL;
+ if (expstart.line == expend.line
+ && expstart.column > expend.column)
+ return NULL;
+ /* These aren't real column numbers, give up. */
+ if (expstart.column == 0 || expend.column == 0)
+ return NULL;
+
+ /* For a single line we need to trim both edges. */
+ if (expstart.line == expend.line)
+ {
+ char_span line = location_get_source_line (expstart.file, expstart.line);
+ if (line.length () < 1)
+ return NULL;
+ int s = expstart.column - 1;
+ int len = expend.column - s;
+ if (line.length () < (size_t)expend.column)
+ return NULL;
+ return line.subspan (s, len).xstrdup ();
+ }
+
+ struct obstack buf_obstack;
+ obstack_init (&buf_obstack);
+
+ /* Loop through all lines in the range and append each to buf; may trim
+ parts of the start and end lines off depending on column values. */
+ for (int lnum = expstart.line; lnum <= expend.line; ++lnum)
+ {
+ char_span line = location_get_source_line (expstart.file, lnum);
+ if (line.length () < 1 && (lnum != expstart.line && lnum != expend.line))
+ continue;
+
+ /* For the first line in the range, only start at expstart.column */
+ if (lnum == expstart.line)
+ {
+ unsigned off = expstart.column - 1;
+ if (line.length () < off)
+ return NULL;
+ line = line.subspan (off, line.length() - off);
+ }
+ /* For the last line, don't go past expend.column */
+ else if (lnum == expend.line)
+ {
+ if (line.length () < (size_t)expend.column)
+ return NULL;
+ line = line.subspan (0, expend.column);
+ }
+
+ /* Combine spaces at the beginning of later lines. */
+ if (lnum > expstart.line)
+ {
+ unsigned off;
+ for (off = 0; off < line.length(); ++off)
+ if (line[off] != ' ' && line[off] != '\t')
+ break;
+ if (off > 0)
+ {
+ obstack_1grow (&buf_obstack, ' ');
+ line = line.subspan (off, line.length() - off);
+ }
+ }
+
+ /* This does not include any trailing newlines. */
+ obstack_grow (&buf_obstack, line.get_buffer (), line.length ());
+ }
+
+ /* NUL-terminate and finish the buf obstack. */
+ obstack_1grow (&buf_obstack, 0);
+ const char *buf = (const char *) obstack_finish (&buf_obstack);
+
+ return xstrdup (buf);
+}
+
/* Determine if FILE_PATH missing a trailing newline on its final line.
Only valid to call once all of the file has been loaded, by
requesting a line number beyond the end of the file. */
@@ -2102,7 +2200,7 @@ test_unknown_location ()
static void
test_builtins ()
{
- assert_loceq (_("<built-in>"), 0, 0, BUILTINS_LOCATION);
+ assert_loceq (special_fname_builtin (), 0, 0, BUILTINS_LOCATION);
ASSERT_PRED1 (is_location_from_builtin_token, BUILTINS_LOCATION);
}
diff --git a/gcc/input.h b/gcc/input.h
index 11c571d..2173a39 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -32,6 +32,9 @@ extern GTY(()) class line_maps *saved_line_table;
/* The location for declarations in "<built-in>" */
#define BUILTINS_LOCATION ((location_t) 1)
+/* Returns the translated string referring to the special location. */
+const char *special_fname_builtin ();
+
/* line-map.cc reserves RESERVED_LOCATION_COUNT to the user. Ensure
both UNKNOWN_LOCATION and BUILTINS_LOCATION fit into that. */
STATIC_ASSERT (BUILTINS_LOCATION < RESERVED_LOCATION_COUNT);
@@ -111,6 +114,7 @@ class char_span
};
extern char_span location_get_source_line (const char *file_path, int line);
+extern char *get_source_text_between (location_t, location_t);
extern bool location_missing_trailing_newline (const char *file_path);
diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index d2bcd5e..cc031eb 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -4225,7 +4225,7 @@ ipcp_propagate_stage (class ipa_topo_info *topo)
for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
{
profile_count count = cs->count.ipa ();
- if (!(count > profile_count::zero ()))
+ if (!count.nonzero_p ())
continue;
enum availability avail;
@@ -5752,14 +5752,16 @@ push_agg_values_for_index_from_edge (struct cgraph_edge *cs, int index,
description of ultimate callee of CS or the one it was cloned from (the
summary where lattices are). If INTERIM is non-NULL, it contains the
current interim state of collected aggregate values which can be used to
- compute values passed over self-recursive edges and to skip values which
- clearly will not be part of intersection with INTERIM. */
+ compute values passed over self-recursive edges (if OPTIMIZE_SELF_RECURSION
+ is true) and to skip values which clearly will not be part of intersection
+ with INTERIM. */
static void
push_agg_values_from_edge (struct cgraph_edge *cs,
ipa_node_params *dest_info,
vec<ipa_argagg_value> *res,
- const ipa_argagg_value_list *interim)
+ const ipa_argagg_value_list *interim,
+ bool optimize_self_recursion)
{
ipa_edge_args *args = ipa_edge_args_sum->get (cs);
if (!args)
@@ -5783,9 +5785,12 @@ push_agg_values_from_edge (struct cgraph_edge *cs,
}
ipcp_param_lattices *plats = ipa_get_parm_lattices (dest_info, index);
- if (plats->aggs_bottom)
+ if (!ipa_is_param_used (dest_info, index)
+ || plats->aggs_bottom)
continue;
- push_agg_values_for_index_from_edge (cs, index, res, interim);
+ push_agg_values_for_index_from_edge (cs, index, res,
+ optimize_self_recursion ? interim
+ : NULL);
}
}
@@ -5804,7 +5809,7 @@ find_aggregate_values_for_callers_subset (struct cgraph_node *node,
/* gather_edges_for_value puts a non-recursive call into the first element of
callers if it can. */
auto_vec<ipa_argagg_value, 32> interim;
- push_agg_values_from_edge (callers[0], dest_info, &interim, NULL);
+ push_agg_values_from_edge (callers[0], dest_info, &interim, NULL, true);
unsigned valid_entries = interim.length ();
if (!valid_entries)
@@ -5815,7 +5820,7 @@ find_aggregate_values_for_callers_subset (struct cgraph_node *node,
{
auto_vec<ipa_argagg_value, 32> last;
ipa_argagg_value_list avs (&interim);
- push_agg_values_from_edge (callers[i], dest_info, &last, &avs);
+ push_agg_values_from_edge (callers[i], dest_info, &last, &avs, true);
valid_entries = intersect_argaggs_with (interim, last);
if (!valid_entries)
@@ -5882,7 +5887,7 @@ cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs,
ipa_node_params *dest_info = ipa_node_params_sum->get (node);
gcc_checking_assert (dest_info->ipcp_orig_node);
dest_info = ipa_node_params_sum->get (dest_info->ipcp_orig_node);
- push_agg_values_from_edge (cs, dest_info, &edge_values, &existing);
+ push_agg_values_from_edge (cs, dest_info, &edge_values, &existing, false);
const ipa_argagg_value_list avl (&edge_values);
return avl.superset_of_p (existing);
}
@@ -6147,6 +6152,9 @@ decide_whether_version_node (struct cgraph_node *node)
for (i = 0; i < count;i++)
{
+ if (!ipa_is_param_used (info, i))
+ continue;
+
class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
ipcp_lattice<tree> *lat = &plats->itself;
ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc
index 23a8cb8..cee0e23 100644
--- a/gcc/ipa-param-manipulation.cc
+++ b/gcc/ipa-param-manipulation.cc
@@ -1378,7 +1378,6 @@ ipa_param_body_adjustments::common_initialization (tree old_fndecl,
if (apm->op == IPA_PARAM_OP_SPLIT)
{
- m_split_modifications_p = true;
split[prev_index] = true;
register_replacement (apm, new_parm);
}
@@ -1472,10 +1471,10 @@ ipa_param_body_adjustments
::ipa_param_body_adjustments (vec<ipa_adjusted_param, va_gc> *adj_params,
tree fndecl)
: m_adj_params (adj_params), m_adjustments (NULL), m_reset_debug_decls (),
- m_split_modifications_p (false), m_dead_stmts (), m_dead_ssas (),
- m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl),
- m_id (NULL), m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
- m_removed_decls (), m_removed_map (), m_method2func (false)
+ m_dead_stmts (), m_dead_ssas (), m_dead_ssa_debug_equiv (),
+ m_dead_stmt_debug_equiv (), m_fndecl (fndecl), m_id (NULL), m_oparms (),
+ m_new_decls (), m_new_types (), m_replacements (), m_removed_decls (),
+ m_removed_map (), m_method2func (false)
{
common_initialization (fndecl, NULL, NULL);
}
@@ -1489,11 +1488,10 @@ ipa_param_body_adjustments
::ipa_param_body_adjustments (ipa_param_adjustments *adjustments,
tree fndecl)
: m_adj_params (adjustments->m_adj_params), m_adjustments (adjustments),
- m_reset_debug_decls (), m_split_modifications_p (false), m_dead_stmts (),
- m_dead_ssas (), m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (),
- m_fndecl (fndecl), m_id (NULL), m_oparms (), m_new_decls (),
- m_new_types (), m_replacements (), m_removed_decls (), m_removed_map (),
- m_method2func (false)
+ m_reset_debug_decls (), m_dead_stmts (), m_dead_ssas (),
+ m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl),
+ m_id (NULL), m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
+ m_removed_decls (), m_removed_map (), m_method2func (false)
{
common_initialization (fndecl, NULL, NULL);
}
@@ -1513,11 +1511,10 @@ ipa_param_body_adjustments
copy_body_data *id, tree *vars,
vec<ipa_replace_map *, va_gc> *tree_map)
: m_adj_params (adjustments->m_adj_params), m_adjustments (adjustments),
- m_reset_debug_decls (), m_split_modifications_p (false), m_dead_stmts (),
- m_dead_ssas (), m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (),
- m_fndecl (fndecl), m_id (id), m_oparms (), m_new_decls (), m_new_types (),
- m_replacements (), m_removed_decls (), m_removed_map (),
- m_method2func (false)
+ m_reset_debug_decls (), m_dead_stmts (), m_dead_ssas (),
+ m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl),
+ m_id (id), m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
+ m_removed_decls (), m_removed_map (), m_method2func (false)
{
common_initialization (old_fndecl, vars, tree_map);
}
@@ -1979,7 +1976,7 @@ ipa_param_body_adjustments::modify_call_stmt (gcall **stmt_p,
&& m_dead_ssas.contains (t))
recreate = true;
- if (!m_split_modifications_p)
+ if (m_replacements.is_empty ())
continue;
tree base;
diff --git a/gcc/ipa-param-manipulation.h b/gcc/ipa-param-manipulation.h
index a9ad2b2..e5654f4 100644
--- a/gcc/ipa-param-manipulation.h
+++ b/gcc/ipa-param-manipulation.h
@@ -350,10 +350,6 @@ public:
auto_vec<tree, 16> m_reset_debug_decls;
- /* Set to true if there are any IPA_PARAM_OP_SPLIT adjustments among stored
- adjustments. */
- bool m_split_modifications_p;
-
/* Sets of statements and SSA_NAMEs that only manipulate data from parameters
removed because they are not necessary. */
hash_set<gimple *> m_dead_stmts;
diff --git a/gcc/ipa-pure-const.cc b/gcc/ipa-pure-const.cc
index 572a6da..0b748ee 100644
--- a/gcc/ipa-pure-const.cc
+++ b/gcc/ipa-pure-const.cc
@@ -1526,8 +1526,9 @@ ipa_make_function_pure (struct cgraph_node *node, bool looping, bool local)
{
bool cdtor = false;
- if (DECL_PURE_P (node->decl)
- && (looping || !DECL_LOOPING_CONST_OR_PURE_P (node->decl)))
+ if (TREE_READONLY (node->decl)
+ || (DECL_PURE_P (node->decl)
+ && (looping || !DECL_LOOPING_CONST_OR_PURE_P (node->decl))))
return false;
warn_function_pure (node->decl, !looping);
if (local && skip_function_for_local_pure_const (node))
diff --git a/gcc/ipa-sra.cc b/gcc/ipa-sra.cc
index 2237ac6..718201d 100644
--- a/gcc/ipa-sra.cc
+++ b/gcc/ipa-sra.cc
@@ -2805,13 +2805,10 @@ ipa_sra_dump_all_summaries (FILE *f)
if (!ifs)
fprintf (f, " Function does not have any associated IPA-SRA "
"summary\n");
+ else if (!ifs->m_candidate)
+ fprintf (f, " Not a candidate function\n");
else
{
- if (!ifs->m_candidate)
- {
- fprintf (f, " Not a candidate function\n");
- continue;
- }
if (ifs->m_returns_value)
fprintf (f, " Returns value\n");
if (vec_safe_is_empty (ifs->m_parameters))
diff --git a/gcc/ira-build.cc b/gcc/ira-build.cc
index 3bf117c..6bb7c30 100644
--- a/gcc/ira-build.cc
+++ b/gcc/ira-build.cc
@@ -1832,7 +1832,7 @@ static basic_block curr_bb;
/* This recursive function creates allocnos corresponding to
pseudo-registers containing in X. True OUTPUT_P means that X is
- an lvalue. PARENT corresponds to the parent expression of X. */
+ an lvalue. OUTER corresponds to the parent expression of X. */
static void
create_insn_allocnos (rtx x, rtx outer, bool output_p)
{
diff --git a/gcc/ira-color.cc b/gcc/ira-color.cc
index 4a1a325..f5f76e8 100644
--- a/gcc/ira-color.cc
+++ b/gcc/ira-color.cc
@@ -1961,7 +1961,6 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
aclass = ALLOCNO_CLASS (a);
class_size = ira_class_hard_regs_num[aclass];
best_hard_regno = -1;
- memset (full_costs, 0, sizeof (int) * class_size);
mem_cost = 0;
memset (costs, 0, sizeof (int) * class_size);
memset (full_costs, 0, sizeof (int) * class_size);
@@ -2209,8 +2208,8 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
restore_costs_from_copies (a);
ALLOCNO_HARD_REGNO (a) = best_hard_regno;
ALLOCNO_ASSIGNED_P (a) = true;
- if (best_hard_regno >= 0)
- update_costs_from_copies (a, true, ! retry_p);
+ if (best_hard_regno >= 0 && !retry_p)
+ update_costs_from_copies (a, true, true);
ira_assert (ALLOCNO_CLASS (a) == aclass);
/* We don't need updated costs anymore. */
ira_free_allocno_updated_costs (a);
diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog
index 602cda3..ef10d78 100644
--- a/gcc/jit/ChangeLog
+++ b/gcc/jit/ChangeLog
@@ -1,3 +1,330 @@
+2022-12-07 Antoni Boucher <bouanto@zoho.com>
+ Guillaume Gomez <guillaume1.gomez@gmail.com>
+
+ PR jit/107770
+ * jit-playback.cc: Fix vector float comparison
+ * jit-playback.h: Update comparison function signature
+ * jit-recording.cc: Update call for "new_comparison" function
+ * jit-recording.h: Fix vector float comparison
+
+2022-11-20 Jeff Law <jlaw@ventanamicro.com>
+
+ PR other/104044
+ * jit-playback.cc (playback::lvale::mark_addressable): Remove
+ extraeous semicolon
+
+2022-11-19 Jonathan Wakely <jwakely@redhat.com>
+ LIU Hao <lh_mouse@126.com>
+
+ * jit-playback.cc (playback::context::scoped_lock): Define RAII
+ lock type.
+ (playback::context::compile): Use scoped_lock to acquire mutex
+ for the active playback context.
+ (jit_mutex): Change to std::mutex.
+ (playback::context::acquire_mutex): Rename to ...
+ (playback::context::lock): ... this.
+ (playback::context::release_mutex): Rename to ...
+ (playback::context::unlock): ... this.
+ * jit-playback.h (playback::context): Rename members and declare
+ scoped_lock.
+ * jit-recording.cc (INCLUDE_PTHREAD_H): Remove unused define.
+ * libgccjit.cc (version_mutex): Change to std::mutex.
+ (struct jit_version_info): Use std::lock_guard to acquire and
+ release mutex.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in:
+ * docs/cp/index.rst: Moved to...
+ * doc/cp/index.rst: ...here.
+ * docs/cp/intro/index.rst: Moved to...
+ * doc/cp/intro/index.rst: ...here.
+ * docs/cp/intro/tutorial01.rst: Moved to...
+ * doc/cp/intro/tutorial01.rst: ...here.
+ * docs/cp/intro/tutorial02.rst: Moved to...
+ * doc/cp/intro/tutorial02.rst: ...here.
+ * docs/cp/intro/tutorial03.rst: Moved to...
+ * doc/cp/intro/tutorial03.rst: ...here.
+ * docs/cp/intro/tutorial04.rst: Moved to...
+ * doc/cp/intro/tutorial04.rst: ...here.
+ * docs/cp/topics/asm.rst: Moved to...
+ * doc/cp/topics/asm.rst: ...here.
+ * docs/cp/topics/compilation.rst: Moved to...
+ * doc/cp/topics/compilation.rst: ...here.
+ * docs/cp/topics/contexts.rst: Moved to...
+ * doc/cp/topics/contexts.rst: ...here.
+ * docs/cp/topics/expressions.rst: Moved to...
+ * doc/cp/topics/expressions.rst: ...here.
+ * docs/cp/topics/functions.rst: Moved to...
+ * doc/cp/topics/functions.rst: ...here.
+ * docs/cp/topics/index.rst: Moved to...
+ * doc/cp/topics/index.rst: ...here.
+ * docs/cp/topics/locations.rst: Moved to...
+ * doc/cp/topics/locations.rst: ...here.
+ * docs/cp/topics/objects.rst: Moved to...
+ * doc/cp/topics/objects.rst: ...here.
+ * docs/cp/topics/types.rst: Moved to...
+ * doc/cp/topics/types.rst: ...here.
+ * docs/examples/emit-alphabet.bf: Moved to...
+ * doc/examples/emit-alphabet.bf: ...here.
+ * docs/examples/tut01-hello-world.c: Moved to...
+ * doc/examples/tut01-hello-world.c: ...here.
+ * docs/examples/tut01-hello-world.cc: Moved to...
+ * doc/examples/tut01-hello-world.cc: ...here.
+ * docs/examples/tut02-square.c: Moved to...
+ * doc/examples/tut02-square.c: ...here.
+ * docs/examples/tut02-square.cc: Moved to...
+ * doc/examples/tut02-square.cc: ...here.
+ * docs/examples/tut03-sum-of-squares.c: Moved to...
+ * doc/examples/tut03-sum-of-squares.c: ...here.
+ * docs/examples/tut03-sum-of-squares.cc: Moved to...
+ * doc/examples/tut03-sum-of-squares.cc: ...here.
+ * docs/examples/tut04-toyvm/Makefile: Moved to...
+ * doc/examples/tut04-toyvm/Makefile: ...here.
+ * docs/examples/tut04-toyvm/factorial.toy: Moved to...
+ * doc/examples/tut04-toyvm/factorial.toy: ...here.
+ * docs/examples/tut04-toyvm/fibonacci.toy: Moved to...
+ * doc/examples/tut04-toyvm/fibonacci.toy: ...here.
+ * docs/examples/tut04-toyvm/toyvm.c: Moved to...
+ * doc/examples/tut04-toyvm/toyvm.c: ...here.
+ * docs/examples/tut04-toyvm/toyvm.cc: Moved to...
+ * doc/examples/tut04-toyvm/toyvm.cc: ...here.
+ * docs/examples/tut05-bf.c: Moved to...
+ * doc/examples/tut05-bf.c: ...here.
+ * docs/index.rst: Moved to...
+ * doc/index.rst: ...here.
+ * docs/internals/index.rst: Moved to...
+ * doc/internals/index.rst: ...here.
+ * docs/internals/test-hello-world.exe.log.txt: Moved to...
+ * doc/internals/test-hello-world.exe.log.txt: ...here.
+ * docs/_build/texinfo/libgccjit-figures/factorial.png: Moved to...
+ * doc/intro/factorial.png: ...here.
+ * docs/intro/index.rst: Moved to...
+ * doc/intro/index.rst: ...here.
+ * docs/_build/texinfo/libgccjit-figures/sum-of-squares.png: Moved to...
+ * doc/intro/sum-of-squares.png: ...here.
+ * docs/intro/tutorial01.rst: Moved to...
+ * doc/intro/tutorial01.rst: ...here.
+ * docs/intro/tutorial02.rst: Moved to...
+ * doc/intro/tutorial02.rst: ...here.
+ * docs/intro/tutorial03.rst: Moved to...
+ * doc/intro/tutorial03.rst: ...here.
+ * docs/intro/tutorial04.rst: Moved to...
+ * doc/intro/tutorial04.rst: ...here.
+ * docs/intro/tutorial05.rst: Moved to...
+ * doc/intro/tutorial05.rst: ...here.
+ * docs/topics/asm.rst: Moved to...
+ * doc/topics/asm.rst: ...here.
+ * docs/topics/compatibility.rst: Moved to...
+ * doc/topics/compatibility.rst: ...here.
+ * docs/topics/compilation.rst: Moved to...
+ * doc/topics/compilation.rst: ...here.
+ * docs/topics/contexts.rst: Moved to...
+ * doc/topics/contexts.rst: ...here.
+ * docs/topics/expressions.rst: Moved to...
+ * doc/topics/expressions.rst: ...here.
+ * docs/topics/function-pointers.rst: Moved to...
+ * doc/topics/function-pointers.rst: ...here.
+ * docs/topics/functions.rst: Moved to...
+ * doc/topics/functions.rst: ...here.
+ * docs/topics/index.rst: Moved to...
+ * doc/topics/index.rst: ...here.
+ * docs/topics/locations.rst: Moved to...
+ * doc/topics/locations.rst: ...here.
+ * docs/topics/objects.rst: Moved to...
+ * doc/topics/objects.rst: ...here.
+ * docs/topics/performance.rst: Moved to...
+ * doc/topics/performance.rst: ...here.
+ * docs/topics/types.rst: Moved to...
+ * doc/topics/types.rst: ...here.
+ * docs/Makefile: Removed.
+ * docs/_build/texinfo/Makefile: Removed.
+ * docs/_build/texinfo/libgccjit-figures/factorial1.png: Removed.
+ * docs/_build/texinfo/libgccjit-figures/sum-of-squares1.png: Removed.
+ * docs/_build/texinfo/libgccjit.texi: Removed.
+ * docs/conf.py: Removed.
+ * docs/intro/factorial.png: Removed.
+ * docs/intro/sum-of-squares.png: Removed.
+ * doc/conf.py: New file.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support --with-sphinx-build.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/internals/index.rst: Fix cross manual refs.
+ * doc/topics/contexts.rst: Likewise.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in:
+ Support installation if sphinx-build is missing.
+
+2022-11-14 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-14 Martin Liska <mliska@suse.cz>
+
+ * doc/cp/index.rst: Remove trailing .rst in toctree.
+ * doc/cp/intro/index.rst: Likewise.
+ * doc/cp/topics/index.rst: Likewise.
+ * doc/index.rst: Likewise.
+ * doc/intro/index.rst: Likewise.
+ * doc/topics/index.rst: Likewise.
+ * doc/indices-and-tables.rst: New file.
+
+2022-11-11 Martin Liska <mliska@suse.cz>
+
+ * doc/cp/index.rst: Remove trailing .rst in toctree.
+ * doc/cp/intro/index.rst: Likewise.
+ * doc/cp/topics/index.rst: Likewise.
+ * doc/index.rst: Likewise.
+ * doc/intro/index.rst: Likewise.
+ * doc/topics/index.rst: Likewise.
+ * doc/indices-and-tables.rst: New file.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in:
+ Support installation if sphinx-build is missing.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * doc/internals/index.rst: Fix cross manual refs.
+ * doc/topics/contexts.rst: Likewise.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in: Support --with-sphinx-build.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ * Make-lang.in:
+ * docs/cp/index.rst: Moved to...
+ * doc/cp/index.rst: ...here.
+ * docs/cp/intro/index.rst: Moved to...
+ * doc/cp/intro/index.rst: ...here.
+ * docs/cp/intro/tutorial01.rst: Moved to...
+ * doc/cp/intro/tutorial01.rst: ...here.
+ * docs/cp/intro/tutorial02.rst: Moved to...
+ * doc/cp/intro/tutorial02.rst: ...here.
+ * docs/cp/intro/tutorial03.rst: Moved to...
+ * doc/cp/intro/tutorial03.rst: ...here.
+ * docs/cp/intro/tutorial04.rst: Moved to...
+ * doc/cp/intro/tutorial04.rst: ...here.
+ * docs/cp/topics/asm.rst: Moved to...
+ * doc/cp/topics/asm.rst: ...here.
+ * docs/cp/topics/compilation.rst: Moved to...
+ * doc/cp/topics/compilation.rst: ...here.
+ * docs/cp/topics/contexts.rst: Moved to...
+ * doc/cp/topics/contexts.rst: ...here.
+ * docs/cp/topics/expressions.rst: Moved to...
+ * doc/cp/topics/expressions.rst: ...here.
+ * docs/cp/topics/functions.rst: Moved to...
+ * doc/cp/topics/functions.rst: ...here.
+ * docs/cp/topics/index.rst: Moved to...
+ * doc/cp/topics/index.rst: ...here.
+ * docs/cp/topics/locations.rst: Moved to...
+ * doc/cp/topics/locations.rst: ...here.
+ * docs/cp/topics/objects.rst: Moved to...
+ * doc/cp/topics/objects.rst: ...here.
+ * docs/cp/topics/types.rst: Moved to...
+ * doc/cp/topics/types.rst: ...here.
+ * docs/examples/emit-alphabet.bf: Moved to...
+ * doc/examples/emit-alphabet.bf: ...here.
+ * docs/examples/tut01-hello-world.c: Moved to...
+ * doc/examples/tut01-hello-world.c: ...here.
+ * docs/examples/tut01-hello-world.cc: Moved to...
+ * doc/examples/tut01-hello-world.cc: ...here.
+ * docs/examples/tut02-square.c: Moved to...
+ * doc/examples/tut02-square.c: ...here.
+ * docs/examples/tut02-square.cc: Moved to...
+ * doc/examples/tut02-square.cc: ...here.
+ * docs/examples/tut03-sum-of-squares.c: Moved to...
+ * doc/examples/tut03-sum-of-squares.c: ...here.
+ * docs/examples/tut03-sum-of-squares.cc: Moved to...
+ * doc/examples/tut03-sum-of-squares.cc: ...here.
+ * docs/examples/tut04-toyvm/Makefile: Moved to...
+ * doc/examples/tut04-toyvm/Makefile: ...here.
+ * docs/examples/tut04-toyvm/factorial.toy: Moved to...
+ * doc/examples/tut04-toyvm/factorial.toy: ...here.
+ * docs/examples/tut04-toyvm/fibonacci.toy: Moved to...
+ * doc/examples/tut04-toyvm/fibonacci.toy: ...here.
+ * docs/examples/tut04-toyvm/toyvm.c: Moved to...
+ * doc/examples/tut04-toyvm/toyvm.c: ...here.
+ * docs/examples/tut04-toyvm/toyvm.cc: Moved to...
+ * doc/examples/tut04-toyvm/toyvm.cc: ...here.
+ * docs/examples/tut05-bf.c: Moved to...
+ * doc/examples/tut05-bf.c: ...here.
+ * docs/index.rst: Moved to...
+ * doc/index.rst: ...here.
+ * docs/internals/index.rst: Moved to...
+ * doc/internals/index.rst: ...here.
+ * docs/internals/test-hello-world.exe.log.txt: Moved to...
+ * doc/internals/test-hello-world.exe.log.txt: ...here.
+ * docs/_build/texinfo/libgccjit-figures/factorial.png: Moved to...
+ * doc/intro/factorial.png: ...here.
+ * docs/intro/index.rst: Moved to...
+ * doc/intro/index.rst: ...here.
+ * docs/_build/texinfo/libgccjit-figures/sum-of-squares.png: Moved to...
+ * doc/intro/sum-of-squares.png: ...here.
+ * docs/intro/tutorial01.rst: Moved to...
+ * doc/intro/tutorial01.rst: ...here.
+ * docs/intro/tutorial02.rst: Moved to...
+ * doc/intro/tutorial02.rst: ...here.
+ * docs/intro/tutorial03.rst: Moved to...
+ * doc/intro/tutorial03.rst: ...here.
+ * docs/intro/tutorial04.rst: Moved to...
+ * doc/intro/tutorial04.rst: ...here.
+ * docs/intro/tutorial05.rst: Moved to...
+ * doc/intro/tutorial05.rst: ...here.
+ * docs/topics/asm.rst: Moved to...
+ * doc/topics/asm.rst: ...here.
+ * docs/topics/compatibility.rst: Moved to...
+ * doc/topics/compatibility.rst: ...here.
+ * docs/topics/compilation.rst: Moved to...
+ * doc/topics/compilation.rst: ...here.
+ * docs/topics/contexts.rst: Moved to...
+ * doc/topics/contexts.rst: ...here.
+ * docs/topics/expressions.rst: Moved to...
+ * doc/topics/expressions.rst: ...here.
+ * docs/topics/function-pointers.rst: Moved to...
+ * doc/topics/function-pointers.rst: ...here.
+ * docs/topics/functions.rst: Moved to...
+ * doc/topics/functions.rst: ...here.
+ * docs/topics/index.rst: Moved to...
+ * doc/topics/index.rst: ...here.
+ * docs/topics/locations.rst: Moved to...
+ * doc/topics/locations.rst: ...here.
+ * docs/topics/objects.rst: Moved to...
+ * doc/topics/objects.rst: ...here.
+ * docs/topics/performance.rst: Moved to...
+ * doc/topics/performance.rst: ...here.
+ * docs/topics/types.rst: Moved to...
+ * doc/topics/types.rst: ...here.
+ * docs/Makefile: Removed.
+ * docs/_build/texinfo/Makefile: Removed.
+ * docs/_build/texinfo/libgccjit-figures/factorial1.png: Removed.
+ * docs/_build/texinfo/libgccjit-figures/sum-of-squares1.png: Removed.
+ * docs/_build/texinfo/libgccjit.texi: Removed.
+ * docs/conf.py: Removed.
+ * docs/intro/factorial.png: Removed.
+ * docs/intro/sum-of-squares.png: Removed.
+ * doc/conf.py: New file.
+
2022-09-15 Richard Biener <rguenther@suse.de>
* dummy-frontend.cc (jit_langhook_init): Do not initialize
@@ -627,10 +954,10 @@
2021-09-10 Petter Tomner <tomner@kth.se>
* jit-playback.c: Moved global var processing to after loc handling.
- Setting TYPE_NAME for fundamental types.
- Using common functions for finalizing globals.
+ Setting TYPE_NAME for fundamental types.
+ Using common functions for finalizing globals.
* jit-playback.h: New method init_types().
- Changed get_tree_node_for_type() to method.
+ Changed get_tree_node_for_type() to method.
2021-08-19 Iain Sandoe <iain@sandoe.co.uk>
@@ -1385,7 +1712,7 @@
(memento_of_get_vector::write_reproducer): New method.
* jit-recording.h: In namespace gcc::jit::recording::
(type::get_vector): New
- method.
+ method.
(class memento_of_get_vector): New class.
* libgccjit++.h (gccjit::type::get_vector): New method.
* libgccjit.c (gcc_jit_type_get_vector): New public entrypoint.
diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc
index d227d36..96e9227 100644
--- a/gcc/jit/jit-playback.cc
+++ b/gcc/jit/jit-playback.cc
@@ -19,7 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
-#define INCLUDE_PTHREAD_H
+#define INCLUDE_MUTEX
#include "system.h"
#include "coretypes.h"
#include "target.h"
@@ -1213,7 +1213,7 @@ playback::rvalue *
playback::context::
new_comparison (location *loc,
enum gcc_jit_comparison op,
- rvalue *a, rvalue *b)
+ rvalue *a, rvalue *b, type *vec_result_type)
{
// FIXME: type-checking, or coercion?
enum tree_code inner_op;
@@ -1252,10 +1252,27 @@ new_comparison (location *loc,
tree node_b = b->as_tree ();
node_b = fold_const_var (node_b);
- tree inner_expr = build2 (inner_op,
- boolean_type_node,
- node_a,
- node_b);
+ tree inner_expr;
+ tree a_type = TREE_TYPE (node_a);
+ if (VECTOR_TYPE_P (a_type))
+ {
+ /* Build a vector comparison. See build_vec_cmp in c-typeck.cc for
+ reference. */
+ tree t_vec_result_type = vec_result_type->as_tree ();
+ tree zero_vec = build_zero_cst (t_vec_result_type);
+ tree minus_one_vec = build_minus_one_cst (t_vec_result_type);
+ tree cmp_type = truth_type_for (a_type);
+ tree cmp = build2 (inner_op, cmp_type, node_a, node_b);
+ inner_expr = build3 (VEC_COND_EXPR, t_vec_result_type, cmp, minus_one_vec,
+ zero_vec);
+ }
+ else
+ {
+ inner_expr = build2 (inner_op,
+ boolean_type_node,
+ node_a,
+ node_b);
+ }
/* Try to fold. */
inner_expr = fold (inner_expr);
@@ -1647,7 +1664,7 @@ bool
playback::lvalue::
mark_addressable (location *loc)
{
- tree x = as_tree ();;
+ tree x = as_tree ();
while (1)
switch (TREE_CODE (x))
@@ -2302,6 +2319,20 @@ block (function *func,
m_label_expr = NULL;
}
+// This is basically std::lock_guard but it can call the private lock/unlock
+// members of playback::context.
+struct playback::context::scoped_lock
+{
+ scoped_lock (context &ctx) : m_ctx (&ctx) { m_ctx->lock (); }
+ ~scoped_lock () { m_ctx->unlock (); }
+
+ context *m_ctx;
+
+ // Not movable or copyable.
+ scoped_lock (scoped_lock &&) = delete;
+ scoped_lock &operator= (scoped_lock &&) = delete;
+};
+
/* Compile a playback::context:
- Use the context's options to cconstruct command-line options, and
@@ -2353,15 +2384,12 @@ compile ()
m_recording_ctxt->get_all_requested_dumps (&requested_dumps);
/* Acquire the JIT mutex and set "this" as the active playback ctxt. */
- acquire_mutex ();
+ scoped_lock lock(*this);
auto_string_vec fake_args;
make_fake_args (&fake_args, ctxt_progname, &requested_dumps);
if (errors_occurred ())
- {
- release_mutex ();
- return;
- }
+ return;
/* This runs the compiler. */
toplev toplev (get_timer (), /* external_timer */
@@ -2388,10 +2416,7 @@ compile ()
followup activities use timevars, which are global state. */
if (errors_occurred ())
- {
- release_mutex ();
- return;
- }
+ return;
if (get_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE))
dump_generated_code ();
@@ -2403,8 +2428,6 @@ compile ()
convert the .s file to the requested output format, and copy it to a
given file (playback::compile_to_file). */
postprocess (ctxt_progname);
-
- release_mutex ();
}
/* Implementation of class gcc::jit::playback::compile_to_memory,
@@ -2662,18 +2685,18 @@ playback::compile_to_file::copy_file (const char *src_path,
/* This mutex guards gcc::jit::recording::context::compile, so that only
one thread can be accessing the bulk of GCC's state at once. */
-static pthread_mutex_t jit_mutex = PTHREAD_MUTEX_INITIALIZER;
+static std::mutex jit_mutex;
/* Acquire jit_mutex and set "this" as the active playback ctxt. */
void
-playback::context::acquire_mutex ()
+playback::context::lock ()
{
auto_timevar tv (get_timer (), TV_JIT_ACQUIRING_MUTEX);
/* Acquire the big GCC mutex. */
JIT_LOG_SCOPE (get_logger ());
- pthread_mutex_lock (&jit_mutex);
+ jit_mutex.lock ();
gcc_assert (active_playback_ctxt == NULL);
active_playback_ctxt = this;
}
@@ -2681,13 +2704,13 @@ playback::context::acquire_mutex ()
/* Release jit_mutex and clear the active playback ctxt. */
void
-playback::context::release_mutex ()
+playback::context::unlock ()
{
/* Release the big GCC mutex. */
JIT_LOG_SCOPE (get_logger ());
gcc_assert (active_playback_ctxt == this);
active_playback_ctxt = NULL;
- pthread_mutex_unlock (&jit_mutex);
+ jit_mutex.unlock ();
}
/* Callback used by gcc::jit::playback::context::make_fake_args when
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index 3ba02a0..214f399 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -162,7 +162,7 @@ public:
rvalue *
new_comparison (location *loc,
enum gcc_jit_comparison op,
- rvalue *a, rvalue *b);
+ rvalue *a, rvalue *b, type *vec_result_type);
rvalue *
new_call (location *loc,
@@ -314,8 +314,9 @@ private:
/* Functions for implementing "compile". */
- void acquire_mutex ();
- void release_mutex ();
+ void lock ();
+ void unlock ();
+ struct scoped_lock;
void
make_fake_args (vec <char *> *argvec,
diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index f78daed..2ce2722 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -19,7 +19,6 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
-#define INCLUDE_PTHREAD_H
#include "system.h"
#include "coretypes.h"
#include "tm.h"
@@ -5837,7 +5836,8 @@ recording::comparison::replay_into (replayer *r)
set_playback_obj (r->new_comparison (playback_location (r, m_loc),
m_op,
m_a->playback_rvalue (),
- m_b->playback_rvalue ()));
+ m_b->playback_rvalue (),
+ m_type->playback_type ()));
}
/* Implementation of pure virtual hook recording::rvalue::visit_children
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 8610ea9..5d7c717 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -1683,7 +1683,23 @@ public:
m_op (op),
m_a (a),
m_b (b)
- {}
+ {
+ type *a_type = a->get_type ();
+ vector_type *vec_type = a_type->dyn_cast_vector_type ();
+ if (vec_type != NULL)
+ {
+ type *element_type = vec_type->get_element_type ();
+ type *inner_type;
+ /* Vectors of floating-point values return a vector of integers of the
+ same size. */
+ if (element_type->is_float ())
+ inner_type = ctxt->get_int_type (element_type->get_size (), false);
+ else
+ inner_type = element_type;
+ m_type = new vector_type (inner_type, vec_type->get_num_units ());
+ ctxt->record (m_type);
+ }
+ }
void replay_into (replayer *r) final override;
diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
index ca86266..8884128 100644
--- a/gcc/jit/libgccjit.cc
+++ b/gcc/jit/libgccjit.cc
@@ -19,7 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
-#define INCLUDE_PTHREAD_H
+#define INCLUDE_MUTEX
#include "system.h"
#include "coretypes.h"
#include "timevar.h"
@@ -4060,7 +4060,7 @@ gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt,
Ideally this would be within parse_basever, but the mutex is only needed
by libgccjit. */
-static pthread_mutex_t version_mutex = PTHREAD_MUTEX_INITIALIZER;
+static std::mutex version_mutex;
struct jit_version_info
{
@@ -4068,9 +4068,8 @@ struct jit_version_info
guarded by version_mutex. */
jit_version_info ()
{
- pthread_mutex_lock (&version_mutex);
+ std::lock_guard<std::mutex> g (version_mutex);
parse_basever (&major, &minor, &patchlevel);
- pthread_mutex_unlock (&version_mutex);
}
int major;
diff --git a/gcc/json.cc b/gcc/json.cc
index 974f8c3..3a79cac 100644
--- a/gcc/json.cc
+++ b/gcc/json.cc
@@ -190,6 +190,15 @@ string::string (const char *utf8)
{
gcc_assert (utf8);
m_utf8 = xstrdup (utf8);
+ m_len = strlen (utf8);
+}
+
+string::string (const char *utf8, size_t len)
+{
+ gcc_assert (utf8);
+ m_utf8 = XNEWVEC (char, len);
+ m_len = len;
+ memcpy (m_utf8, utf8, len);
}
/* Implementation of json::value::print for json::string. */
@@ -198,9 +207,9 @@ void
string::print (pretty_printer *pp) const
{
pp_character (pp, '"');
- for (const char *ptr = m_utf8; *ptr; ptr++)
+ for (size_t i = 0; i != m_len; ++i)
{
- char ch = *ptr;
+ char ch = m_utf8[i];
switch (ch)
{
case '"':
@@ -224,7 +233,9 @@ string::print (pretty_printer *pp) const
case '\t':
pp_string (pp, "\\t");
break;
-
+ case '\0':
+ pp_string (pp, "\\0");
+ break;
default:
pp_character (pp, ch);
}
@@ -341,6 +352,12 @@ test_writing_strings ()
string contains_quotes ("before \"quoted\" after");
assert_print_eq (contains_quotes, "\"before \\\"quoted\\\" after\"");
+
+ const char data[] = {'a', 'b', 'c', 'd', '\0', 'e', 'f'};
+ string not_terminated (data, 3);
+ assert_print_eq (not_terminated, "\"abc\"");
+ string embedded_null (data, sizeof data);
+ assert_print_eq (embedded_null, "\"abcd\\0ef\"");
}
/* Verify that JSON literals are written correctly. */
diff --git a/gcc/json.h b/gcc/json.h
index f272981..f7afd84 100644
--- a/gcc/json.h
+++ b/gcc/json.h
@@ -156,16 +156,19 @@ class integer_number : public value
class string : public value
{
public:
- string (const char *utf8);
+ explicit string (const char *utf8);
+ string (const char *utf8, size_t len);
~string () { free (m_utf8); }
enum kind get_kind () const final override { return JSON_STRING; }
void print (pretty_printer *pp) const final override;
const char *get_string () const { return m_utf8; }
+ size_t get_length () const { return m_len; }
private:
char *m_utf8;
+ size_t m_len;
};
/* Subclass of value for the three JSON literals "true", "false",
diff --git a/gcc/loop-init.cc b/gcc/loop-init.cc
index b9e0797..f03c077 100644
--- a/gcc/loop-init.cc
+++ b/gcc/loop-init.cc
@@ -567,7 +567,8 @@ public:
/* opt_pass methods: */
bool gate (function *) final override
{
- return (flag_unroll_loops || flag_unroll_all_loops || cfun->has_unroll);
+ return (flag_unroll_loops || flag_unroll_all_loops
+ || cfun->has_unroll);
}
unsigned int execute (function *) final override;
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index d92ab76..02b5ab4 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -4582,7 +4582,18 @@ curr_insn_transform (bool check_only_p)
|| (partial_subreg_p (mode, GET_MODE (reg))
&& known_le (GET_MODE_SIZE (GET_MODE (reg)),
UNITS_PER_WORD)
- && WORD_REGISTER_OPERATIONS)))
+ && WORD_REGISTER_OPERATIONS))
+ /* Avoid the situation when there are no available hard regs
+ for the pseudo mode but there are ones for the subreg
+ mode: */
+ && !(goal_alt[i] != NO_REGS
+ && REGNO (reg) >= FIRST_PSEUDO_REGISTER
+ && (prohibited_class_reg_set_mode_p
+ (goal_alt[i], reg_class_contents[goal_alt[i]],
+ GET_MODE (reg)))
+ && !(prohibited_class_reg_set_mode_p
+ (goal_alt[i], reg_class_contents[goal_alt[i]],
+ mode))))
{
/* An OP_INOUT is required when reloading a subreg of a
mode wider than a word to ensure that data beyond the
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index 3ede467..a0f0b9e 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,9 @@
+2022-11-25 Martin Liska <mliska@suse.cz>
+
+ PR lto/107829
+ * lto.cc (materialize_cgraph): Call timevar_push before
+ materialization starts.
+
2022-10-29 Thomas Schwinge <thomas@codesourcery.com>
* lang.opt: Better separate 'LTO' vs. 'LTODump'.
@@ -130,7 +136,7 @@
2021-09-27 Martin Liska <mliska@suse.cz>
* lto-lang.c (lto_init_options_struct): Set also
- x_flag_default_complex_method.
+ x_flag_default_complex_method.
2021-09-03 Jakub Jelinek <jakub@redhat.com>
@@ -672,7 +678,7 @@
2018-10-30 Michael Ploujnikov <michael.ploujnikov@oracle.com>
* lto-partition.c (privatize_symbol_name_1): Use
- clone_function_name_numbered.
+ clone_function_name_numbered.
2018-10-26 Jan Hubicka <jh@suse.cz>
@@ -2139,7 +2145,7 @@
(lto_fixup_prevailing_decls): Handle fixing up CONSTRUCTOR values.
2014-02-04 Jan Hubicka <hubicka@ucw.cz>
- Markus Trippelsdorf
+ Markus Trippelsdorf
PR ipa/59469
* lto-symtab.c (lto_cgraph_replace_node, lto_varpool_replace_node):
@@ -3457,7 +3463,7 @@
2010-10-03 Andi Kleen <ak@linux.intel.com>
* lto.c (lto_file_finalize): Replace gcc_assert for missing section
- with fatal_error.
+ with fatal_error.
2010-09-28 Jan Hubicka <jh@suse.cz>
@@ -5944,10 +5950,10 @@
2007-11-06 Alon Dayan <alond@il.ibm.com>
Kenneth Zadeck <zadeck@naturalbridge.com>
- * lto-read.c (process_flags, lto_static_init_local):
- read flags of VAR_DECL and FUNCTION_DECL of size>1.
- change global array num_flags_for_code to flags_length_for_code.
- (set_line_info): Make decls work in USE_MAPPED_LOCATION mode.
+ * lto-read.c (process_flags, lto_static_init_local):
+ read flags of VAR_DECL and FUNCTION_DECL of size>1.
+ change global array num_flags_for_code to flags_length_for_code.
+ (set_line_info): Make decls work in USE_MAPPED_LOCATION mode.
2007-11-05 Nathan Froyd <froydnj@codesourcery.com>
diff --git a/gcc/lto/lto.cc b/gcc/lto/lto.cc
index 3a9147b..3265a1d 100644
--- a/gcc/lto/lto.cc
+++ b/gcc/lto/lto.cc
@@ -137,6 +137,12 @@ materialize_cgraph (void)
fprintf (stderr,
flag_wpa ? "Materializing decls:" : "Reading function bodies:");
+ /* Start the appropriate timer depending on the mode that we are
+ operating in. */
+ lto_timer = (flag_wpa) ? TV_WHOPR_WPA
+ : (flag_ltrans) ? TV_WHOPR_LTRANS
+ : TV_LTO;
+ timevar_push (lto_timer);
FOR_EACH_FUNCTION (node)
{
@@ -147,14 +153,6 @@ materialize_cgraph (void)
}
}
-
- /* Start the appropriate timer depending on the mode that we are
- operating in. */
- lto_timer = (flag_wpa) ? TV_WHOPR_WPA
- : (flag_ltrans) ? TV_WHOPR_LTRANS
- : TV_LTO;
- timevar_push (lto_timer);
-
current_function_decl = NULL;
set_cfun (NULL);
diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog
new file mode 100644
index 0000000..d1f979ea
--- /dev/null
+++ b/gcc/m2/ChangeLog
@@ -0,0 +1,5 @@
+Copyright (C) 2022 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc/make-unique.h b/gcc/make-unique.h
new file mode 100644
index 0000000..c9a7d6e
--- /dev/null
+++ b/gcc/make-unique.h
@@ -0,0 +1,44 @@
+/* Minimal implementation of make_unique for C++11 compatibility.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_MAKE_UNIQUE
+#define GCC_MAKE_UNIQUE
+
+/* This header uses std::unique_ptr, but <memory> can't be directly
+ included due to issues with macros. Hence <memory> must be included
+ from system.h by defining INCLUDE_MEMORY in any source file using
+ make-unique.h. */
+
+#ifndef INCLUDE_MEMORY
+# error "You must define INCLUDE_MEMORY before including system.h to use make-unique.h"
+#endif
+
+#include <type_traits>
+
+/* Minimal implementation of make_unique for C++11 compatibility
+ (std::make_unique is C++14). */
+
+template<typename T, typename... Args>
+inline typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Args&&... args)
+{
+ return std::unique_ptr<T> (new T (std::forward<Args> (args)...));
+}
+
+#endif /* ! GCC_MAKE_UNIQUE */
diff --git a/gcc/match.pd b/gcc/match.pd
index 194ba8f..c48fe2d 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -354,7 +354,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
Only for unsigned A. For signed A, this would not preserve rounding
toward zero.
For example: (-1 / ( 1 << B)) != -1 >> B.
- Also also widening conversions, like:
+ Also handle widening conversions, like:
(A / (unsigned long long) (1U << B)) -> (A >> B)
or
(A / (unsigned long long) (1 << B)) -> (A >> B).
@@ -1285,8 +1285,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* ~x | x -> -1 */
/* ~x ^ x -> -1 */
-/* ~x + x -> -1 */
-(for op (bit_ior bit_xor plus)
+(for op (bit_ior bit_xor)
(simplify
(op:c (convert? @0) (convert? (bit_not @0)))
(convert { build_all_ones_cst (TREE_TYPE (@0)); })))
@@ -1907,6 +1906,61 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (INTEGRAL_TYPE_P (type))
(bit_and @0 @1)))
+(for cmp (tcc_comparison)
+ icmp (inverted_tcc_comparison)
+ /* Fold (((a < b) & c) | ((a >= b) & d)) into (a < b ? c : d) & 1. */
+ (simplify
+ (bit_ior
+ (bit_and:c (convert? (cmp@0 @01 @02)) @3)
+ (bit_and:c (convert? (icmp@4 @01 @02)) @5))
+ (if (INTEGRAL_TYPE_P (type)
+ /* The scalar version has to be canonicalized after vectorization
+ because it makes unconditional loads conditional ones, which
+ means we lose vectorization because the loads may trap. */
+ && canonicalize_math_after_vectorization_p ())
+ (bit_and (cond @0 @3 @5) { build_one_cst (type); })))
+
+ /* Fold ((-(a < b) & c) | (-(a >= b) & d)) into a < b ? c : d. This is
+ canonicalized further and we recognize the conditional form:
+ (a < b ? c : 0) | (a >= b ? d : 0) into a < b ? c : d. */
+ (simplify
+ (bit_ior
+ (cond (cmp@0 @01 @02) @3 zerop)
+ (cond (icmp@4 @01 @02) @5 zerop))
+ (if (INTEGRAL_TYPE_P (type)
+ /* The scalar version has to be canonicalized after vectorization
+ because it makes unconditional loads conditional ones, which
+ means we lose vectorization because the loads may trap. */
+ && canonicalize_math_after_vectorization_p ())
+ (cond @0 @3 @5)))
+
+ /* Vector Fold (((a < b) & c) | ((a >= b) & d)) into a < b ? c : d.
+ and ((~(a < b) & c) | (~(a >= b) & d)) into a < b ? c : d. */
+ (simplify
+ (bit_ior
+ (bit_and:c (vec_cond:s (cmp@0 @6 @7) @4 @5) @2)
+ (bit_and:c (vec_cond:s (icmp@1 @6 @7) @4 @5) @3))
+ (if (integer_zerop (@5))
+ (switch
+ (if (integer_onep (@4))
+ (bit_and (vec_cond @0 @2 @3) @4))
+ (if (integer_minus_onep (@4))
+ (vec_cond @0 @2 @3)))
+ (if (integer_zerop (@4))
+ (switch
+ (if (integer_onep (@5))
+ (bit_and (vec_cond @0 @3 @2) @5))
+ (if (integer_minus_onep (@5))
+ (vec_cond @0 @3 @2))))))
+
+ /* Scalar Vectorized Fold ((-(a < b) & c) | (-(a >= b) & d))
+ into a < b ? d : c. */
+ (simplify
+ (bit_ior
+ (vec_cond:s (cmp@0 @4 @5) @2 integer_zerop)
+ (vec_cond:s (icmp@1 @4 @5) @3 integer_zerop))
+ (vec_cond @0 @2 @3)))
+
/* Transform X & -Y into X * Y when Y is { 0 or 1 }. */
(simplify
(bit_and:c (convert? (negate zero_one_valued_p@0)) @1)
@@ -2000,6 +2054,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& TYPE_PRECISION (TREE_TYPE (@0)) == 1)
(convert (eq @0 @1))))
+/* (~a) == b is a ^ b for truth valued a and b. */
+(simplify
+ (eq:c (bit_not:s truth_valued_p@0) truth_valued_p@1)
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && TYPE_PRECISION (TREE_TYPE (@0)) == 1)
+ (convert (bit_xor @0 @1))))
+
/* (x & ~m) | (y & m) -> ((x ^ y) & m) ^ x */
(simplify
(bit_ior:c (bit_and:cs @0 (bit_not @2)) (bit_and:cs @1 @2))
@@ -2254,6 +2315,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& (CONSTANT_CLASS_P (@1) || (single_use (@2) && single_use (@3))))
(op @1 { build_zero_cst (TREE_TYPE (@1)); }))))
+/* (&a + b) !=/== (&a[1] + c) -> (&a[0] - &a[1]) + b !=/== c */
+(for neeq (ne eq)
+ (simplify
+ (neeq:c ADDR_EXPR@0 (pointer_plus @2 @3))
+ (with { poly_int64 diff; tree inner_type = TREE_TYPE (@3);}
+ (if (ptr_difference_const (@0, @2, &diff))
+ (neeq { build_int_cst_type (inner_type, diff); } @3))))
+ (simplify
+ (neeq (pointer_plus ADDR_EXPR@0 @1) (pointer_plus ADDR_EXPR@2 @3))
+ (with { poly_int64 diff; tree inner_type = TREE_TYPE (@1);}
+ (if (ptr_difference_const (@0, @2, &diff))
+ (neeq (plus { build_int_cst_type (inner_type, diff); } @1) @3)))))
+
/* X - Y < X is the same as Y > 0 when there is no overflow.
For equality, this is also true with wrapping overflow. */
(for op (simple_comparison)
@@ -2432,14 +2506,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(with { poly_int64 diff; }
(if (ptr_difference_const (@0, @2, &diff))
(plus { build_int_cst_type (type, diff); } (convert (minus @1 @3))))))
-
-/* (&a+b) !=/== (&a[1] + c) -> sizeof(a[0]) + b !=/== c */
-(for neeq (ne eq)
- (simplify
- (neeq (pointer_plus ADDR_EXPR@0 @1) (pointer_plus ADDR_EXPR@2 @3))
- (with { poly_int64 diff; tree inner_type = TREE_TYPE (@1);}
- (if (ptr_difference_const (@0, @2, &diff))
- (neeq (plus { build_int_cst_type (inner_type, diff); } @1) @3)))))
+/* (p + b) - &p->d -> offsetof (*p, d) + b */
+(simplify
+ (pointer_diff (pointer_plus @0 @1) ADDR_EXPR@2)
+ (with { poly_int64 diff; }
+ (if (ptr_difference_const (@0, @2, &diff))
+ (plus { build_int_cst_type (type, diff); } (convert @1)))))
+(simplify
+ (pointer_diff ADDR_EXPR@0 (pointer_plus @1 @2))
+ (with { poly_int64 diff; }
+ (if (ptr_difference_const (@0, @1, &diff))
+ (minus { build_int_cst_type (type, diff); } (convert @2)))))
/* Canonicalize (T *)(ptr - ptr-cst) to &MEM[ptr + -ptr-cst]. */
(simplify
@@ -2939,9 +3016,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* ~A + A -> -1 */
(simplify
- (plus:c (bit_not @0) @0)
+ (plus:c (convert? (bit_not @0)) (convert? @0))
(if (!TYPE_OVERFLOW_TRAPS (type))
- { build_all_ones_cst (type); }))
+ (convert { build_all_ones_cst (TREE_TYPE (@0)); })))
/* ~A + 1 -> -A */
(simplify
@@ -3486,6 +3563,30 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(cond (le @0 integer_zerop@1) (negate@2 @0) integer_zerop@1)
(max @2 @1))
+/* ((x & 0x1) == 0) ? y : z <op> y -> (-(typeof(y))(x & 0x1) & z) <op> y */
+(for op (bit_xor bit_ior)
+ (simplify
+ (cond (eq zero_one_valued_p@0
+ integer_zerop)
+ @1
+ (op:c @2 @1))
+ (if (INTEGRAL_TYPE_P (type)
+ && TYPE_PRECISION (type) > 1
+ && (INTEGRAL_TYPE_P (TREE_TYPE (@0))))
+ (op (bit_and (negate (convert:type @0)) @2) @1))))
+
+/* ((x & 0x1) == 0) ? z <op> y : y -> (-(typeof(y))(x & 0x1) & z) <op> y */
+(for op (bit_xor bit_ior)
+ (simplify
+ (cond (ne zero_one_valued_p@0
+ integer_zerop)
+ (op:c @2 @1)
+ @1)
+ (if (INTEGRAL_TYPE_P (type)
+ && TYPE_PRECISION (type) > 1
+ && (INTEGRAL_TYPE_P (TREE_TYPE (@0))))
+ (op (bit_and (negate (convert:type @0)) @2) @1))))
+
/* Simplifications of shift and rotates. */
(for rotate (lrotate rrotate)
@@ -5103,34 +5204,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(scmp @0 (bit_not @1)))))
(for cmp (simple_comparison)
- /* Fold (double)float1 CMP (double)float2 into float1 CMP float2. */
- (simplify
- (cmp (convert@2 @0) (convert? @1))
- (if (FLOAT_TYPE_P (TREE_TYPE (@0))
- && (DECIMAL_FLOAT_TYPE_P (TREE_TYPE (@2))
- == DECIMAL_FLOAT_TYPE_P (TREE_TYPE (@0)))
- && (DECIMAL_FLOAT_TYPE_P (TREE_TYPE (@2))
- == DECIMAL_FLOAT_TYPE_P (TREE_TYPE (@1))))
- (with
- {
- tree type1 = TREE_TYPE (@1);
- if (TREE_CODE (@1) == REAL_CST && !DECIMAL_FLOAT_TYPE_P (type1))
- {
- REAL_VALUE_TYPE orig = TREE_REAL_CST (@1);
- if (TYPE_PRECISION (type1) > TYPE_PRECISION (float_type_node)
- && exact_real_truncate (TYPE_MODE (float_type_node), &orig))
- type1 = float_type_node;
- if (TYPE_PRECISION (type1) > TYPE_PRECISION (double_type_node)
- && exact_real_truncate (TYPE_MODE (double_type_node), &orig))
- type1 = double_type_node;
- }
- tree newtype
- = (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (type1)
- ? TREE_TYPE (@0) : type1);
- }
- (if (TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (newtype))
- (cmp (convert:newtype @0) (convert:newtype @1))))))
-
(simplify
(cmp @0 REAL_CST@1)
/* IEEE doesn't distinguish +0 and -0 in comparisons. */
@@ -5144,12 +5217,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(cmp { build_real (TREE_TYPE (@0), dconst0); } @1))
/* x != NaN is always true, other ops are always false. */
(if (REAL_VALUE_ISNAN (TREE_REAL_CST (@1))
+ && (cmp == EQ_EXPR || cmp == NE_EXPR || !flag_trapping_math)
&& !tree_expr_signaling_nan_p (@1)
&& !tree_expr_maybe_signaling_nan_p (@0))
{ constant_boolean_node (cmp == NE_EXPR, type); })
/* NaN != y is always true, other ops are always false. */
(if (TREE_CODE (@0) == REAL_CST
&& REAL_VALUE_ISNAN (TREE_REAL_CST (@0))
+ && (cmp == EQ_EXPR || cmp == NE_EXPR || !flag_trapping_math)
&& !tree_expr_signaling_nan_p (@0)
&& !tree_expr_signaling_nan_p (@1))
{ constant_boolean_node (cmp == NE_EXPR, type); })
@@ -5683,26 +5758,56 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (cmp == LT_EXPR || cmp == LE_EXPR)
{ constant_boolean_node (above ? true : false, type); }
(if (cmp == GT_EXPR || cmp == GE_EXPR)
- { constant_boolean_node (above ? false : true, type); }))))))))))))
+ { constant_boolean_node (above ? false : true, type); })))))))))
+ /* Fold (double)float1 CMP (double)float2 into float1 CMP float2. */
+ (if (FLOAT_TYPE_P (TREE_TYPE (@00))
+ && (DECIMAL_FLOAT_TYPE_P (TREE_TYPE (@0))
+ == DECIMAL_FLOAT_TYPE_P (TREE_TYPE (@00)))
+ && (DECIMAL_FLOAT_TYPE_P (TREE_TYPE (@0))
+ == DECIMAL_FLOAT_TYPE_P (TREE_TYPE (@10))))
+ (with
+ {
+ tree type1 = TREE_TYPE (@10);
+ if (TREE_CODE (@10) == REAL_CST && !DECIMAL_FLOAT_TYPE_P (type1))
+ {
+ REAL_VALUE_TYPE orig = TREE_REAL_CST (@10);
+ if (TYPE_PRECISION (type1) > TYPE_PRECISION (float_type_node)
+ && exact_real_truncate (TYPE_MODE (float_type_node), &orig))
+ type1 = float_type_node;
+ if (TYPE_PRECISION (type1) > TYPE_PRECISION (double_type_node)
+ && exact_real_truncate (TYPE_MODE (double_type_node), &orig))
+ type1 = double_type_node;
+ }
+ tree newtype
+ = (TYPE_PRECISION (TREE_TYPE (@00)) > TYPE_PRECISION (type1)
+ ? TREE_TYPE (@00) : type1);
+ }
+ (if (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (newtype))
+ (cmp (convert:newtype @00) (convert:newtype @10))))))))
+
(for cmp (eq ne)
(simplify
/* SSA names are canonicalized to 2nd place. */
(cmp addr@0 SSA_NAME@1)
(with
- { poly_int64 off; tree base; }
+ {
+ poly_int64 off; tree base;
+ tree addr = (TREE_CODE (@0) == SSA_NAME
+ ? gimple_assign_rhs1 (SSA_NAME_DEF_STMT (@0)) : @0);
+ }
/* A local variable can never be pointed to by
the default SSA name of an incoming parameter. */
(if (SSA_NAME_IS_DEFAULT_DEF (@1)
&& TREE_CODE (SSA_NAME_VAR (@1)) == PARM_DECL
- && (base = get_base_address (TREE_OPERAND (@0, 0)))
+ && (base = get_base_address (TREE_OPERAND (addr, 0)))
&& TREE_CODE (base) == VAR_DECL
&& auto_var_in_fn_p (base, current_function_decl))
(if (cmp == NE_EXPR)
{ constant_boolean_node (true, type); }
{ constant_boolean_node (false, type); })
/* If the address is based on @1 decide using the offset. */
- (if ((base = get_addr_base_and_unit_offset (TREE_OPERAND (@0, 0), &off))
+ (if ((base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0), &off))
&& TREE_CODE (base) == MEM_REF
&& TREE_OPERAND (base, 0) == @1)
(with { off += mem_ref_offset (base).force_shwi (); }
@@ -7921,6 +8026,68 @@ and,
(simplify (reduc (op @0 VECTOR_CST@1))
(op (reduc:type @0) (reduc:type @1))))
+/* Simplify vector floating point operations of alternating sub/add pairs
+ into using an fneg of a wider element type followed by a normal add.
+ under IEEE 754 the fneg of the wider type will negate every even entry
+ and when doing an add we get a sub of the even and add of every odd
+ elements. */
+(simplify
+ (vec_perm (plus:c @0 @1) (minus @0 @1) VECTOR_CST@2)
+ (if (!VECTOR_INTEGER_TYPE_P (type)
+ && !FLOAT_WORDS_BIG_ENDIAN)
+ (with
+ {
+ /* Build a vector of integers from the tree mask. */
+ vec_perm_builder builder;
+ }
+ (if (tree_to_vec_perm_builder (&builder, @2))
+ (with
+ {
+ /* Create a vec_perm_indices for the integer vector. */
+ poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (type);
+ vec_perm_indices sel (builder, 2, nelts);
+ machine_mode vec_mode = TYPE_MODE (type);
+ machine_mode wide_mode;
+ scalar_mode wide_elt_mode;
+ poly_uint64 wide_nunits;
+ scalar_mode inner_mode = GET_MODE_INNER (vec_mode);
+ }
+ (if (sel.series_p (0, 2, 0, 2)
+ && GET_MODE_2XWIDER_MODE (inner_mode).exists (&wide_elt_mode)
+ && multiple_p (GET_MODE_NUNITS (vec_mode), 2, &wide_nunits)
+ && related_vector_mode (vec_mode, wide_elt_mode,
+ wide_nunits).exists (&wide_mode))
+ (with
+ {
+ tree stype
+ = lang_hooks.types.type_for_mode (GET_MODE_INNER (wide_mode),
+ TYPE_UNSIGNED (type));
+ tree ntype = build_vector_type_for_mode (stype, wide_mode);
+
+ /* The format has to be a non-extended ieee format. */
+ const struct real_format *fmt_old = FLOAT_MODE_FORMAT (vec_mode);
+ const struct real_format *fmt_new = FLOAT_MODE_FORMAT (wide_mode);
+ }
+ (if (TYPE_MODE (stype) != BLKmode
+ && VECTOR_TYPE_P (ntype)
+ && fmt_old != NULL
+ && fmt_new != NULL)
+ (with
+ {
+ /* If the target doesn't support v1xx vectors, try using
+ scalar mode xx instead. */
+ if (known_eq (GET_MODE_NUNITS (wide_mode), 1)
+ && !target_supports_op_p (ntype, NEGATE_EXPR, optab_vector))
+ ntype = stype;
+ }
+ (if (fmt_new->signbit_rw
+ == fmt_old->signbit_rw + GET_MODE_UNIT_BITSIZE (vec_mode)
+ && fmt_new->signbit_rw == fmt_new->signbit_ro
+ && targetm.can_change_mode_class (TYPE_MODE (ntype), TYPE_MODE (type), ALL_REGS)
+ && ((optimize_vectors_before_lowering_p () && VECTOR_TYPE_P (ntype))
+ || target_supports_op_p (ntype, NEGATE_EXPR, optab_vector)))
+ (plus (view_convert:type (negate (view_convert:ntype @1))) @0)))))))))))
+
(simplify
(vec_perm @0 @1 VECTOR_CST@2)
(with
@@ -8189,3 +8356,59 @@ and,
(bit_and (negate @0) integer_onep@1)
(if (!TYPE_OVERFLOW_SANITIZED (type))
(bit_and @0 @1)))
+
+/* Optimize
+ c1 = VEC_PERM_EXPR (a, a, mask)
+ c2 = VEC_PERM_EXPR (b, b, mask)
+ c3 = c1 op c2
+ -->
+ c = a op b
+ c3 = VEC_PERM_EXPR (c, c, mask)
+ For all integer non-div operations. */
+(for op (plus minus mult bit_and bit_ior bit_xor
+ lshift rshift)
+ (simplify
+ (op (vec_perm @0 @0 @2) (vec_perm @1 @1 @2))
+ (if (VECTOR_INTEGER_TYPE_P (type))
+ (vec_perm (op@3 @0 @1) @3 @2))))
+
+/* Similar for float arithmetic when permutation constant covers
+ all vector elements. */
+(for op (plus minus mult)
+ (simplify
+ (op (vec_perm @0 @0 VECTOR_CST@2) (vec_perm @1 @1 VECTOR_CST@2))
+ (if (VECTOR_FLOAT_TYPE_P (type)
+ && TYPE_VECTOR_SUBPARTS (type).is_constant ())
+ (with
+ {
+ tree perm_cst = @2;
+ vec_perm_builder builder;
+ bool full_perm_p = false;
+ if (tree_to_vec_perm_builder (&builder, perm_cst))
+ {
+ unsigned HOST_WIDE_INT nelts;
+
+ nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
+ /* Create a vec_perm_indices for the VECTOR_CST. */
+ vec_perm_indices sel (builder, 1, nelts);
+
+ /* Check if perm indices covers all vector elements. */
+ if (sel.encoding ().encoded_full_vector_p ())
+ {
+ auto_sbitmap seen (nelts);
+ bitmap_clear (seen);
+
+ unsigned HOST_WIDE_INT count = 0, i;
+
+ for (i = 0; i < nelts; i++)
+ {
+ if (!bitmap_set_bit (seen, sel[i].to_constant ()))
+ break;
+ count++;
+ }
+ full_perm_p = count == nelts;
+ }
+ }
+ }
+ (if (full_perm_p)
+ (vec_perm (op@3 @0 @1) @3 @2))))))
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index 3e2d268..fd88c22 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -178,7 +178,6 @@ create_dispatcher_calls (struct cgraph_node *node)
node->set_comdat_group (NULL);
node->externally_visible = false;
node->forced_by_abi = false;
- node->set_section (NULL);
DECL_ARTIFICIAL (node->decl) = 1;
node->force_output = true;
@@ -391,19 +390,23 @@ expand_target_clones (struct cgraph_node *node, bool definition)
for (i = 0; i < attrnum; i++)
{
char *attr = attrs[i];
- char *suffix = XNEWVEC (char, strlen (attr) + 1);
- create_new_asm_name (attr, suffix);
/* Create new target clone. */
tree attributes = make_attribute ("target", attr,
DECL_ATTRIBUTES (node->decl));
+ char *suffix = XNEWVEC (char, strlen (attr) + 1);
+ create_new_asm_name (attr, suffix);
cgraph_node *new_node = create_target_clone (node, definition, suffix,
attributes);
+ XDELETEVEC (suffix);
if (new_node == NULL)
- return false;
+ {
+ XDELETEVEC (attrs);
+ XDELETEVEC (attr_str);
+ return false;
+ }
new_node->local = false;
- XDELETEVEC (suffix);
decl2_v = new_node->function_version ();
if (decl2_v != NULL)
@@ -536,7 +539,8 @@ public:
bool
pass_target_clone::gate (function *)
{
- return true;
+ /* If there were any errors avoid pass property verification errors. */
+ return !seen_error ();
}
} // anon namespace
diff --git a/gcc/objcp/ChangeLog b/gcc/objcp/ChangeLog
index c5b292a..da57932 100644
--- a/gcc/objcp/ChangeLog
+++ b/gcc/objcp/ChangeLog
@@ -1,3 +1,13 @@
+2022-11-15 Patrick Palka <ppalka@redhat.com>
+
+ * objcp-lang.cc (objcp_tsubst_copy_and_build): Adjust calls to
+ tsubst_copy_and_build and tsubst_expr.
+
+2022-11-15 Patrick Palka <ppalka@redhat.com>
+
+ * objcp-lang.cc (objcp_tsubst_copy_and_build): Remove
+ function_p parameter.
+
2022-05-31 Jason Merrill <jason@redhat.com>
* Make-lang.in (obj-c++.tags): Look at *.cc.
diff --git a/gcc/objcp/objcp-lang.cc b/gcc/objcp/objcp-lang.cc
index 2e8809b..fa75402 100644
--- a/gcc/objcp/objcp-lang.cc
+++ b/gcc/objcp/objcp-lang.cc
@@ -50,13 +50,11 @@ struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
there should be very few (if any) routines below. */
tree
-objcp_tsubst_copy_and_build (tree t, tree args, tsubst_flags_t complain,
- tree in_decl, bool function_p ATTRIBUTE_UNUSED)
+objcp_tsubst_copy_and_build (tree t, tree args, tsubst_flags_t complain,
+ tree in_decl)
{
#define RECURSE(NODE) \
- tsubst_copy_and_build (NODE, args, complain, in_decl, \
- /*function_p=*/false, \
- /*integral_constant_expression_p=*/false)
+ tsubst_copy_and_build (NODE, args, complain, in_decl)
/* The following two can only occur in Objective-C++. */
diff --git a/gcc/omp-simd-clone.cc b/gcc/omp-simd-clone.cc
index 34cbee5..21d69aa 100644
--- a/gcc/omp-simd-clone.cc
+++ b/gcc/omp-simd-clone.cc
@@ -51,6 +51,210 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h"
#include "attribs.h"
#include "omp-simd-clone.h"
+#include "omp-low.h"
+#include "omp-general.h"
+
+/* Print debug info for ok_for_auto_simd_clone to the dump file, logging
+ failure reason EXCUSE for function DECL. Always returns false. */
+static bool
+auto_simd_fail (tree decl, const char *excuse)
+{
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "\nNot auto-cloning %s because %s\n",
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
+ excuse);
+ return false;
+}
+
+/* Helper function for ok_for_auto_simd_clone; return false if the statement
+ violates restrictions for an "omp declare simd" function. Specifically,
+ the function must not
+ - throw or call setjmp/longjmp
+ - write memory that could alias parallel calls
+ - read volatile memory
+ - include openmp directives or calls
+ - call functions that might do those things */
+
+static bool
+auto_simd_check_stmt (gimple *stmt, tree outer)
+{
+ tree decl;
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_CALL:
+
+ /* Calls to functions that are CONST or PURE are ok, even if they
+ are internal functions without a decl. Reject other internal
+ functions. */
+ if (gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE))
+ break;
+ if (gimple_call_internal_p (stmt))
+ return auto_simd_fail (outer,
+ "body contains internal function call");
+
+ decl = gimple_call_fndecl (stmt);
+
+ /* We can't know whether indirect calls are safe. */
+ if (decl == NULL_TREE)
+ return auto_simd_fail (outer, "body contains indirect call");
+
+ /* Calls to functions that are already marked "omp declare simd" are
+ OK. */
+ if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (decl)))
+ break;
+
+ /* Let recursive calls to the current function through. */
+ if (decl == outer)
+ break;
+
+ /* Other function calls are not permitted. This covers all calls to
+ the libgomp API and setjmp/longjmp, too, as well as things like
+ __cxa_throw_ related to exception handling. */
+ return auto_simd_fail (outer, "body contains unsafe function call");
+
+ /* Reject EH-related constructs. Most of the EH gimple codes are
+ already lowered by the time this pass runs during IPA.
+ GIMPLE_EH_DISPATCH and GIMPLE_RESX remain and are lowered by
+ pass_lower_eh_dispatch and pass_lower_resx, respectively; those
+ passes run later. */
+ case GIMPLE_EH_DISPATCH:
+ case GIMPLE_RESX:
+ return auto_simd_fail (outer, "body contains EH constructs");
+
+ /* Asms are not permitted since we don't know what they do. */
+ case GIMPLE_ASM:
+ return auto_simd_fail (outer, "body contains inline asm");
+
+ default:
+ break;
+ }
+
+ /* Memory writes are not permitted.
+ FIXME: this could be relaxed a little to permit writes to
+ function-local variables that could not alias other instances
+ of the function running in parallel. */
+ if (gimple_store_p (stmt))
+ return auto_simd_fail (outer, "body includes memory write");
+
+ /* Volatile reads are not permitted. */
+ if (gimple_has_volatile_ops (stmt))
+ return auto_simd_fail (outer, "body includes volatile op");
+
+ /* Otherwise OK. */
+ return true;
+}
+
+/* Helper function for ok_for_auto_simd_clone: return true if type T is
+ plausible for a cloneable function argument or return type. */
+static bool
+plausible_type_for_simd_clone (tree t)
+{
+ if (TREE_CODE (t) == VOID_TYPE)
+ return true;
+ else if (RECORD_OR_UNION_TYPE_P (t) || !is_a <scalar_mode> (TYPE_MODE (t)))
+ /* Small record/union types may fit into a scalar mode, but are
+ still not suitable. */
+ return false;
+ else if (TYPE_ATOMIC (t))
+ /* Atomic types trigger warnings in simd_clone_clauses_extract. */
+ return false;
+ else
+ return true;
+}
+
+/* Check if the function NODE appears suitable for auto-annotation
+ with "declare simd". */
+
+static bool
+ok_for_auto_simd_clone (struct cgraph_node *node)
+{
+ tree decl = node->decl;
+ tree t;
+ basic_block bb;
+
+ /* Nothing to do if the function isn't a definition or doesn't
+ have a body. */
+ if (!node->definition || !node->has_gimple_body_p ())
+ return auto_simd_fail (decl, "no definition or body");
+
+ /* No point in trying to generate implicit clones if the function
+ isn't used in the compilation unit. */
+ if (!node->callers)
+ return auto_simd_fail (decl, "function is not used");
+
+ /* Nothing to do if the function already has the "omp declare simd"
+ attribute, is marked noclone, or is not "omp declare target". */
+ if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (decl))
+ || lookup_attribute ("noclone", DECL_ATTRIBUTES (decl))
+ || !lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
+ return auto_simd_fail (decl, "incompatible attributes");
+
+ /* Check whether the function is restricted host/nohost via the
+ "omp declare target device_type" clause, and that doesn't match
+ what we're compiling for. Internally, these translate into
+ "omp declare target [no]host" attributes on the decl; "any"
+ translates into both attributes, but the default (which is supposed
+ to be equivalent to "any") is neither. */
+ tree host = lookup_attribute ("omp declare target host",
+ DECL_ATTRIBUTES (decl));
+ tree nohost = lookup_attribute ("omp declare target nohost",
+ DECL_ATTRIBUTES (decl));
+#ifdef ACCEL_COMPILER
+ if (host && !nohost)
+ return auto_simd_fail (decl, "device doesn't match for accel compiler");
+#else
+ if (nohost && !host)
+ return auto_simd_fail (decl, "device doesn't match for host compiler");
+#endif
+
+ /* Backends will check for vectorizable arguments/return types in a
+ target-specific way, but we can immediately filter out functions
+ that have implausible argument/return types. */
+ t = TREE_TYPE (TREE_TYPE (decl));
+ if (!plausible_type_for_simd_clone (t))
+ return auto_simd_fail (decl, "return type fails sniff test");
+
+ if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
+ {
+ for (tree temp = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ temp; temp = TREE_CHAIN (temp))
+ {
+ t = TREE_VALUE (temp);
+ if (!plausible_type_for_simd_clone (t))
+ return auto_simd_fail (decl, "argument type fails sniff test");
+ }
+ }
+ else if (DECL_ARGUMENTS (decl))
+ {
+ for (tree temp = DECL_ARGUMENTS (decl); temp; temp = DECL_CHAIN (temp))
+ {
+ t = TREE_TYPE (temp);
+ if (!plausible_type_for_simd_clone (t))
+ return auto_simd_fail (decl, "argument type fails sniff test");
+ }
+ }
+ else
+ return auto_simd_fail (decl, "function has no arguments");
+
+ /* Scan the function body to see if it is suitable for SIMD-ization. */
+ node->get_body ();
+
+ FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (decl))
+ {
+ for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
+ gsi_next (&gsi))
+ if (!auto_simd_check_stmt (gsi_stmt (gsi), decl))
+ return false;
+ }
+
+ /* All is good. */
+ if (dump_file)
+ fprintf (dump_file, "\nMarking %s for auto-cloning\n",
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
+ return true;
+}
+
/* Return the number of elements in vector type VECTYPE, which is associated
with a SIMD clone. At present these always have a constant length. */
@@ -430,10 +634,12 @@ simd_clone_mangle (struct cgraph_node *node,
return get_identifier (str);
}
-/* Create a simd clone of OLD_NODE and return it. */
+/* Create a simd clone of OLD_NODE and return it. If FORCE_LOCAL is true,
+ create it as a local symbol, otherwise copy the symbol linkage and
+ visibility attributes from OLD_NODE. */
static struct cgraph_node *
-simd_clone_create (struct cgraph_node *old_node)
+simd_clone_create (struct cgraph_node *old_node, bool force_local)
{
struct cgraph_node *new_node;
if (old_node->definition)
@@ -463,23 +669,38 @@ simd_clone_create (struct cgraph_node *old_node)
return new_node;
set_decl_built_in_function (new_node->decl, NOT_BUILT_IN, 0);
- TREE_PUBLIC (new_node->decl) = TREE_PUBLIC (old_node->decl);
- DECL_COMDAT (new_node->decl) = DECL_COMDAT (old_node->decl);
- DECL_WEAK (new_node->decl) = DECL_WEAK (old_node->decl);
- DECL_EXTERNAL (new_node->decl) = DECL_EXTERNAL (old_node->decl);
- DECL_VISIBILITY_SPECIFIED (new_node->decl)
- = DECL_VISIBILITY_SPECIFIED (old_node->decl);
- DECL_VISIBILITY (new_node->decl) = DECL_VISIBILITY (old_node->decl);
- DECL_DLLIMPORT_P (new_node->decl) = DECL_DLLIMPORT_P (old_node->decl);
- if (DECL_ONE_ONLY (old_node->decl))
- make_decl_one_only (new_node->decl, DECL_ASSEMBLER_NAME (new_node->decl));
-
- /* The method cgraph_version_clone_with_body () will force the new
- symbol local. Undo this, and inherit external visibility from
- the old node. */
- new_node->local = old_node->local;
- new_node->externally_visible = old_node->externally_visible;
- new_node->calls_declare_variant_alt = old_node->calls_declare_variant_alt;
+ if (force_local)
+ {
+ TREE_PUBLIC (new_node->decl) = 0;
+ DECL_COMDAT (new_node->decl) = 0;
+ DECL_WEAK (new_node->decl) = 0;
+ DECL_EXTERNAL (new_node->decl) = 0;
+ DECL_VISIBILITY_SPECIFIED (new_node->decl) = 0;
+ DECL_VISIBILITY (new_node->decl) = VISIBILITY_DEFAULT;
+ DECL_DLLIMPORT_P (new_node->decl) = 0;
+ }
+ else
+ {
+ TREE_PUBLIC (new_node->decl) = TREE_PUBLIC (old_node->decl);
+ DECL_COMDAT (new_node->decl) = DECL_COMDAT (old_node->decl);
+ DECL_WEAK (new_node->decl) = DECL_WEAK (old_node->decl);
+ DECL_EXTERNAL (new_node->decl) = DECL_EXTERNAL (old_node->decl);
+ DECL_VISIBILITY_SPECIFIED (new_node->decl)
+ = DECL_VISIBILITY_SPECIFIED (old_node->decl);
+ DECL_VISIBILITY (new_node->decl) = DECL_VISIBILITY (old_node->decl);
+ DECL_DLLIMPORT_P (new_node->decl) = DECL_DLLIMPORT_P (old_node->decl);
+ if (DECL_ONE_ONLY (old_node->decl))
+ make_decl_one_only (new_node->decl,
+ DECL_ASSEMBLER_NAME (new_node->decl));
+
+ /* The method cgraph_version_clone_with_body () will force the new
+ symbol local. Undo this, and inherit external visibility from
+ the old node. */
+ new_node->local = old_node->local;
+ new_node->externally_visible = old_node->externally_visible;
+ new_node->calls_declare_variant_alt
+ = old_node->calls_declare_variant_alt;
+ }
return new_node;
}
@@ -1683,13 +1904,42 @@ simd_clone_adjust (struct cgraph_node *node)
void
expand_simd_clones (struct cgraph_node *node)
{
- tree attr = lookup_attribute ("omp declare simd",
- DECL_ATTRIBUTES (node->decl));
- if (attr == NULL_TREE
- || node->inlined_to
+ tree attr;
+ bool explicit_p = true;
+
+ if (node->inlined_to
|| lookup_attribute ("noclone", DECL_ATTRIBUTES (node->decl)))
return;
+ attr = lookup_attribute ("omp declare simd",
+ DECL_ATTRIBUTES (node->decl));
+
+ /* See if we can add an "omp declare simd" directive implicitly
+ before giving up. */
+ /* FIXME: OpenACC "#pragma acc routine" translates into
+ "omp declare target", but appears also to have some other effects
+ that conflict with generating SIMD clones, causing ICEs. So don't
+ do this if we've got OpenACC instead of OpenMP. */
+ if (attr == NULL_TREE
+#ifdef ACCEL_COMPILER
+ && (flag_openmp_target_simd_clone == OMP_TARGET_SIMD_CLONE_ANY
+ || flag_openmp_target_simd_clone == OMP_TARGET_SIMD_CLONE_NOHOST)
+#else
+ && (flag_openmp_target_simd_clone == OMP_TARGET_SIMD_CLONE_ANY
+ || flag_openmp_target_simd_clone == OMP_TARGET_SIMD_CLONE_HOST)
+#endif
+ && !oacc_get_fn_attrib (node->decl)
+ && ok_for_auto_simd_clone (node))
+ {
+ attr = tree_cons (get_identifier ("omp declare simd"), NULL,
+ DECL_ATTRIBUTES (node->decl));
+ DECL_ATTRIBUTES (node->decl) = attr;
+ explicit_p = false;
+ }
+
+ if (attr == NULL_TREE)
+ return;
+
/* Ignore
#pragma omp declare simd
extern int foo ();
@@ -1714,13 +1964,15 @@ expand_simd_clones (struct cgraph_node *node)
poly_uint64 orig_simdlen = clone_info->simdlen;
tree base_type = simd_clone_compute_base_data_type (node, clone_info);
+
/* The target can return 0 (no simd clones should be created),
1 (just one ISA of simd clones should be created) or higher
count of ISA variants. In that case, clone_info is initialized
for the first ISA variant. */
int count
= targetm.simd_clone.compute_vecsize_and_simdlen (node, clone_info,
- base_type, 0);
+ base_type, 0,
+ explicit_p);
if (count == 0)
continue;
@@ -1745,7 +1997,8 @@ expand_simd_clones (struct cgraph_node *node)
/* And call the target hook again to get the right ISA. */
targetm.simd_clone.compute_vecsize_and_simdlen (node, clone,
base_type,
- i / 2);
+ i / 2,
+ explicit_p);
if ((i & 1) != 0)
clone->inbranch = 1;
}
@@ -1763,7 +2016,7 @@ expand_simd_clones (struct cgraph_node *node)
/* Only when we are sure we want to create the clone actually
clone the function (or definitions) or create another
extern FUNCTION_DECL (for prototypes without definitions). */
- struct cgraph_node *n = simd_clone_create (node);
+ struct cgraph_node *n = simd_clone_create (node, !explicit_p);
if (n == NULL)
{
if (i == 0)
@@ -1798,6 +2051,10 @@ expand_simd_clones (struct cgraph_node *node)
simd_clone_adjust_return_type (n);
simd_clone_adjust_argument_types (n);
}
+ if (dump_file)
+ fprintf (dump_file, "\nGenerated %s clone %s\n",
+ (TREE_PUBLIC (n->decl) ? "global" : "local"),
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl)));
}
}
while ((attr = lookup_attribute ("omp declare simd", TREE_CHAIN (attr))));
diff --git a/gcc/optabs.cc b/gcc/optabs.cc
index c2a6f97..2ffd455 100644
--- a/gcc/optabs.cc
+++ b/gcc/optabs.cc
@@ -46,6 +46,8 @@ along with GCC; see the file COPYING3. If not see
#include "libfuncs.h"
#include "internal-fn.h"
#include "langhooks.h"
+#include "gimple.h"
+#include "ssa.h"
static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
machine_mode *);
@@ -1104,8 +1106,9 @@ expand_doubleword_mod (machine_mode mode, rtx op0, rtx op1, bool unsignedp)
return NULL_RTX;
}
}
- rtx remainder = expand_divmod (1, TRUNC_MOD_EXPR, word_mode, sum,
- gen_int_mode (INTVAL (op1), word_mode),
+ rtx remainder = expand_divmod (1, TRUNC_MOD_EXPR, word_mode, NULL, NULL,
+ sum, gen_int_mode (INTVAL (op1),
+ word_mode),
NULL_RTX, 1, OPTAB_DIRECT);
if (remainder == NULL_RTX)
return NULL_RTX;
@@ -1208,8 +1211,8 @@ expand_doubleword_divmod (machine_mode mode, rtx op0, rtx op1, rtx *rem,
if (op11 != const1_rtx)
{
- rtx rem2 = expand_divmod (1, TRUNC_MOD_EXPR, mode, quot1, op11,
- NULL_RTX, unsignedp, OPTAB_DIRECT);
+ rtx rem2 = expand_divmod (1, TRUNC_MOD_EXPR, mode, NULL, NULL, quot1,
+ op11, NULL_RTX, unsignedp, OPTAB_DIRECT);
if (rem2 == NULL_RTX)
return NULL_RTX;
@@ -1223,8 +1226,8 @@ expand_doubleword_divmod (machine_mode mode, rtx op0, rtx op1, rtx *rem,
if (rem2 == NULL_RTX)
return NULL_RTX;
- rtx quot2 = expand_divmod (0, TRUNC_DIV_EXPR, mode, quot1, op11,
- NULL_RTX, unsignedp, OPTAB_DIRECT);
+ rtx quot2 = expand_divmod (0, TRUNC_DIV_EXPR, mode, NULL, NULL, quot1,
+ op11, NULL_RTX, unsignedp, OPTAB_DIRECT);
if (quot2 == NULL_RTX)
return NULL_RTX;
@@ -4344,12 +4347,17 @@ can_vec_set_var_idx_p (machine_mode vec_mode)
return false;
machine_mode inner_mode = GET_MODE_INNER (vec_mode);
+
rtx reg1 = alloca_raw_REG (vec_mode, LAST_VIRTUAL_REGISTER + 1);
rtx reg2 = alloca_raw_REG (inner_mode, LAST_VIRTUAL_REGISTER + 2);
- rtx reg3 = alloca_raw_REG (VOIDmode, LAST_VIRTUAL_REGISTER + 3);
enum insn_code icode = optab_handler (vec_set_optab, vec_mode);
+ const struct insn_data_d *data = &insn_data[icode];
+ machine_mode idx_mode = data->operand[2].mode;
+
+ rtx reg3 = alloca_raw_REG (idx_mode, LAST_VIRTUAL_REGISTER + 3);
+
return icode != CODE_FOR_nothing && insn_operand_matches (icode, 0, reg1)
&& insn_operand_matches (icode, 1, reg2)
&& insn_operand_matches (icode, 2, reg3);
@@ -4483,10 +4491,14 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
{
enum insn_code icode = optab_handler (cbranch_optab, CCmode);
test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
- gcc_assert (icode != CODE_FOR_nothing
- && insn_operand_matches (icode, 0, test));
- *ptest = test;
- return;
+ if (icode != CODE_FOR_nothing
+ && insn_operand_matches (icode, 0, test))
+ {
+ *ptest = test;
+ return;
+ }
+ else
+ goto fail;
}
test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
@@ -4617,7 +4629,8 @@ prepare_operand (enum insn_code icode, rtx x, int opnum, machine_mode mode,
static void
emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label,
- profile_probability prob)
+ direct_optab cmp_optab, profile_probability prob,
+ bool test_branch)
{
machine_mode optab_mode;
enum mode_class mclass;
@@ -4626,12 +4639,17 @@ emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label,
mclass = GET_MODE_CLASS (mode);
optab_mode = (mclass == MODE_CC) ? CCmode : mode;
- icode = optab_handler (cbranch_optab, optab_mode);
+ icode = optab_handler (cmp_optab, optab_mode);
gcc_assert (icode != CODE_FOR_nothing);
- gcc_assert (insn_operand_matches (icode, 0, test));
- insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
- XEXP (test, 1), label));
+ gcc_assert (test_branch || insn_operand_matches (icode, 0, test));
+ if (test_branch)
+ insn = emit_jump_insn (GEN_FCN (icode) (XEXP (test, 0),
+ XEXP (test, 1), label));
+ else
+ insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
+ XEXP (test, 1), label));
+
if (prob.initialized_p ()
&& profile_status_for_fn (cfun) != PROFILE_ABSENT
&& insn
@@ -4641,6 +4659,68 @@ emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label,
add_reg_br_prob_note (insn, prob);
}
+/* PTEST points to a comparison that compares its first operand with zero.
+ Check to see if it can be performed as a bit-test-and-branch instead.
+ On success, return the instruction that performs the bit-test-and-branch
+ and replace the second operand of *PTEST with the bit number to test.
+ On failure, return CODE_FOR_nothing and leave *PTEST unchanged.
+
+ Note that the comparison described by *PTEST should not be taken
+ literally after a successful return. *PTEST is just a convenient
+ place to store the two operands of the bit-and-test.
+
+ VAL must contain the original tree expression for the first operand
+ of *PTEST. */
+
+static enum insn_code
+validate_test_and_branch (tree val, rtx *ptest, machine_mode *pmode, optab *res)
+{
+ if (!val || TREE_CODE (val) != SSA_NAME)
+ return CODE_FOR_nothing;
+
+ machine_mode mode = TYPE_MODE (TREE_TYPE (val));
+ rtx test = *ptest;
+ direct_optab optab;
+
+ if (GET_CODE (test) == EQ)
+ optab = tbranch_eq_optab;
+ else if (GET_CODE (test) == NE)
+ optab = tbranch_ne_optab;
+ else
+ return CODE_FOR_nothing;
+
+ *res = optab;
+
+ /* If the target supports the testbit comparison directly, great. */
+ auto icode = direct_optab_handler (optab, mode);
+ if (icode == CODE_FOR_nothing)
+ return icode;
+
+ if (tree_zero_one_valued_p (val))
+ {
+ auto pos = BITS_BIG_ENDIAN ? GET_MODE_BITSIZE (mode) - 1 : 0;
+ XEXP (test, 1) = gen_int_mode (pos, mode);
+ *ptest = test;
+ *pmode = mode;
+ return icode;
+ }
+
+ wide_int wcst = get_nonzero_bits (val);
+ if (wcst == -1)
+ return CODE_FOR_nothing;
+
+ int bitpos;
+
+ if ((bitpos = wi::exact_log2 (wcst)) == -1)
+ return CODE_FOR_nothing;
+
+ auto pos = BITS_BIG_ENDIAN ? GET_MODE_BITSIZE (mode) - 1 - bitpos : bitpos;
+ XEXP (test, 1) = gen_int_mode (pos, mode);
+ *ptest = test;
+ *pmode = mode;
+ return icode;
+}
+
/* Generate code to compare X with Y so that the condition codes are
set and to jump to LABEL if the condition is true. If X is a
constant and Y is not a constant, then the comparison is swapped to
@@ -4658,11 +4738,13 @@ emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label,
It will be potentially converted into an unsigned variant based on
UNSIGNEDP to select a proper jump instruction.
- PROB is the probability of jumping to LABEL. */
+ PROB is the probability of jumping to LABEL. If the comparison is against
+ zero then VAL contains the expression from which the non-zero RTL is
+ derived. */
void
emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
- machine_mode mode, int unsignedp, rtx label,
+ machine_mode mode, int unsignedp, tree val, rtx label,
profile_probability prob)
{
rtx op0 = x, op1 = y;
@@ -4687,10 +4769,34 @@ emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
&test, &mode);
- emit_cmp_and_jump_insn_1 (test, mode, label, prob);
+
+ /* Check if we're comparing a truth type with 0, and if so check if
+ the target supports tbranch. */
+ machine_mode tmode = mode;
+ direct_optab optab;
+ if (op1 == CONST0_RTX (GET_MODE (op1))
+ && validate_test_and_branch (val, &test, &tmode,
+ &optab) != CODE_FOR_nothing)
+ {
+ emit_cmp_and_jump_insn_1 (test, tmode, label, optab, prob, true);
+ return;
+ }
+
+ emit_cmp_and_jump_insn_1 (test, mode, label, cbranch_optab, prob, false);
}
-
+/* Overloaded version of emit_cmp_and_jump_insns in which VAL is unknown. */
+
+void
+emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
+ machine_mode mode, int unsignedp, rtx label,
+ profile_probability prob)
+{
+ emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, NULL,
+ label, prob);
+}
+
+
/* Emit a library call comparison between floating point X and Y.
COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
@@ -7956,6 +8062,8 @@ maybe_gen_insn (enum insn_code icode, unsigned int nops,
switch (nops)
{
+ case 0:
+ return GEN_FCN (icode) ();
case 1:
return GEN_FCN (icode) (ops[0].value);
case 2:
diff --git a/gcc/optabs.def b/gcc/optabs.def
index a6db234..5516a59 100644
--- a/gcc/optabs.def
+++ b/gcc/optabs.def
@@ -220,6 +220,8 @@ OPTAB_D (reload_in_optab, "reload_in$a")
OPTAB_D (reload_out_optab, "reload_out$a")
OPTAB_DC(cbranch_optab, "cbranch$a4", COMPARE)
+OPTAB_D (tbranch_eq_optab, "tbranch_eq$a3")
+OPTAB_D (tbranch_ne_optab, "tbranch_ne$a3")
OPTAB_D (addcc_optab, "add$acc")
OPTAB_D (negcc_optab, "neg$acc")
OPTAB_D (notcc_optab, "not$acc")
diff --git a/gcc/optabs.h b/gcc/optabs.h
index cfd7c74..cd55604 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -268,6 +268,10 @@ extern void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx,
machine_mode, int, rtx,
profile_probability prob
= profile_probability::uninitialized ());
+extern void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx,
+ machine_mode, int, tree, rtx,
+ profile_probability prob
+ = profile_probability::uninitialized ());
/* Generate code to indirectly jump to a location given in the rtx LOC. */
extern void emit_indirect_jump (rtx);
diff --git a/gcc/opts.cc b/gcc/opts.cc
index ae079fc..73fc977 100644
--- a/gcc/opts.cc
+++ b/gcc/opts.cc
@@ -658,6 +658,8 @@ static const struct default_options default_options_table[] =
REORDER_BLOCKS_ALGORITHM_STC },
{ OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_ftree_loop_vectorize, NULL, 1 },
{ OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_ftree_slp_vectorize, NULL, 1 },
+ { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_fopenmp_target_simd_clone_, NULL,
+ OMP_TARGET_SIMD_CLONE_NOHOST },
#ifdef INSN_SCHEDULING
/* Only run the pre-regalloc scheduling pass if optimizing for speed. */
{ OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_fschedule_insns, NULL, 1 },
@@ -3248,6 +3250,10 @@ common_handle_option (struct gcc_options *opts,
dc->report_bug = value;
break;
+ case OPT_fmultiflags:
+ gcc_checking_assert (lang_mask == CL_DRIVER);
+ break;
+
default:
/* If the flag was handled in a standard way, assume the lack of
processing here is intentional. */
diff --git a/gcc/params.opt b/gcc/params.opt
index a34fee1..397ec0b 100644
--- a/gcc/params.opt
+++ b/gcc/params.opt
@@ -726,6 +726,10 @@ The maximum number of instructions to consider to unroll in a loop.
Common Joined UInteger Var(param_max_unswitch_insns) Init(50) Param Optimization
The maximum number of insns of an unswitched loop.
+-param=max-unswitch-depth=
+Common Joined UInteger Var(param_max_unswitch_depth) Init(50) IntegerRange(1, 50) Param Optimization
+The maximum depth of a loop nest to be unswitched.
+
-param=max-variable-expansions-in-unroller=
Common Joined UInteger Var(param_max_variable_expansions) Init(1) Param Optimization
If -fvariable-expansion-in-unroller is used, the maximum number of times that an individual variable will be expanded during loop unrolling.
@@ -746,10 +750,6 @@ Max. size of var tracking hash tables.
Common Joined UInteger Var(param_max_find_base_term_values) Init(200) Param Optimization
Maximum number of VALUEs handled during a single find_base_term call.
--param=max-vrp-switch-assertions=
-Common Joined UInteger Var(param_max_vrp_switch_assertions) Init(10) Param Optimization
-Maximum number of assertions to add along the default edge of a switch statement during VRP.
-
-param=min-crossjump-insns=
Common Joined UInteger Var(param_min_crossjump_insns) Init(5) IntegerRange(1, 65536) Param Optimization
The minimum number of matching instructions to consider for crossjumping.
@@ -1165,21 +1165,4 @@ The maximum factor which the loop vectorizer applies to the cost of statements i
Common Joined UInteger Var(param_vect_induction_float) Init(1) IntegerRage(0, 1) Param Optimization
Enable loop vectorization of floating point inductions.
--param=vrp1-mode=
-Common Joined Var(param_vrp1_mode) Enum(vrp_mode) Init(VRP_MODE_RANGER) Param Optimization
---param=vrp1-mode=[vrp|ranger] Specifies the mode VRP1 should operate in.
-
--param=vrp2-mode=
-Common Joined Var(param_vrp2_mode) Enum(vrp_mode) Init(VRP_MODE_RANGER) Param Optimization
---param=vrp2-mode=[vrp|ranger] Specifies the mode VRP2 should operate in.
-
-Enum
-Name(vrp_mode) Type(enum vrp_mode) UnknownError(unknown vrp mode %qs)
-
-EnumValue
-Enum(vrp_mode) String(vrp) Value(VRP_MODE_VRP)
-
-EnumValue
-Enum(vrp_mode) String(ranger) Value(VRP_MODE_RANGER)
-
; This comment is to ensure we retain the blank line above.
diff --git a/gcc/passes.def b/gcc/passes.def
index 193b579..462e9af 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -346,8 +346,8 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_ccp, true /* nonzero_p */);
NEXT_PASS (pass_warn_restrict);
NEXT_PASS (pass_dse);
- NEXT_PASS (pass_cd_dce, true /* update_address_taken_p */);
- /* After late CD DCE we rewrite no longer addressed locals into SSA
+ NEXT_PASS (pass_dce, true /* update_address_taken_p */);
+ /* After late DCE we rewrite no longer addressed locals into SSA
form if possible. */
NEXT_PASS (pass_forwprop);
NEXT_PASS (pass_sink_code, true /* unsplit edges */);
@@ -355,12 +355,12 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_fold_builtins);
NEXT_PASS (pass_optimize_widening_mul);
NEXT_PASS (pass_store_merging);
- NEXT_PASS (pass_tail_calls);
/* If DCE is not run before checking for uninitialized uses,
we may get false warnings (e.g., testsuite/gcc.dg/uninit-5.c).
However, this also causes us to misdiagnose cases that should be
real warnings (e.g., testsuite/gcc.dg/pr18501.c). */
- NEXT_PASS (pass_dce);
+ NEXT_PASS (pass_cd_dce, false /* update_address_taken_p */);
+ NEXT_PASS (pass_tail_calls);
/* Split critical edges before late uninit warning to reduce the
number of false positives from it. */
NEXT_PASS (pass_split_crit_edges);
diff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc
index 0f01002..ea6ca68 100644
--- a/gcc/pointer-query.cc
+++ b/gcc/pointer-query.cc
@@ -600,8 +600,8 @@ gimple_parm_array_size (tree ptr, wide_int rng[2],
/* Initialize the object. */
access_ref::access_ref ()
- : ref (), eval ([](tree x){ return x; }), deref (), trail1special (true),
- base0 (true), parmarray ()
+ : ref (), eval ([](tree x){ return x; }), deref (), ref_nullptr_p (false),
+ trail1special (true), base0 (true), parmarray ()
{
/* Set to valid. */
offrng[0] = offrng[1] = 0;
@@ -1193,7 +1193,16 @@ access_ref::inform_access (access_mode mode, int ostype /* = 1 */) const
loc = EXPR_LOCATION (ref);
else if (TREE_CODE (ref) != IDENTIFIER_NODE
&& TREE_CODE (ref) != SSA_NAME)
- return;
+ {
+ if (TREE_CODE (ref) == INTEGER_CST && ref_nullptr_p)
+ {
+ if (mode == access_read_write || mode == access_write_only)
+ inform (loc, "destination object is likely at address zero");
+ else
+ inform (loc, "source object is likely at address zero");
+ }
+ return;
+ }
if (mode == access_read_write || mode == access_write_only)
{
@@ -2144,12 +2153,6 @@ handle_ssa_name (tree ptr, bool addr, int ostype,
tree rhs = gimple_assign_rhs1 (stmt);
- if (code == ASSERT_EXPR)
- {
- rhs = TREE_OPERAND (rhs, 0);
- return compute_objsize_r (rhs, stmt, addr, ostype, pref, snlim, qry);
- }
-
if (code == POINTER_PLUS_EXPR
&& TREE_CODE (TREE_TYPE (rhs)) == POINTER_TYPE)
{
@@ -2286,7 +2289,10 @@ compute_objsize_r (tree ptr, gimple *stmt, bool addr, int ostype,
if (targetm.addr_space.zero_address_valid (as))
pref->set_max_size_range ();
else
- pref->sizrng[0] = pref->sizrng[1] = 0;
+ {
+ pref->sizrng[0] = pref->sizrng[1] = 0;
+ pref->ref_nullptr_p = true;
+ }
}
else
pref->sizrng[0] = pref->sizrng[1] = 0;
diff --git a/gcc/pointer-query.h b/gcc/pointer-query.h
index 801a240..19a6f15 100644
--- a/gcc/pointer-query.h
+++ b/gcc/pointer-query.h
@@ -88,7 +88,7 @@ struct access_ref
argument to the minimum. */
offset_int size_remaining (offset_int * = nullptr) const;
-/* Return true if the offset and object size are in range for SIZE. */
+ /* 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. */
@@ -141,6 +141,9 @@ struct access_ref
/* Positive when REF is dereferenced, negative when its address is
taken. */
int deref;
+ /* The following indicates if heuristics interpreted 'ref' is interpreted
+ as (offsetted) nullptr. */
+ bool ref_nullptr_p;
/* Set if trailing one-element arrays should be treated as flexible
array members. */
bool trail1special;
diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 04208c8..929ff9c 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -49,13 +49,68 @@ along with GCC; see the file COPYING3. If not see
// Default definitions for floating point operators.
bool
-range_operator_float::fold_range (frange &r ATTRIBUTE_UNUSED,
- tree type ATTRIBUTE_UNUSED,
- const frange &lh ATTRIBUTE_UNUSED,
- const frange &rh ATTRIBUTE_UNUSED,
- relation_trio) const
+range_operator_float::fold_range (frange &r, tree type,
+ const frange &op1, const frange &op2,
+ relation_trio trio) const
{
- return false;
+ if (empty_range_varying (r, type, op1, op2))
+ return true;
+ if (op1.known_isnan () || op2.known_isnan ())
+ {
+ r.set_nan (op1.type ());
+ return true;
+ }
+
+ REAL_VALUE_TYPE lb, ub;
+ bool maybe_nan;
+ rv_fold (lb, ub, maybe_nan, type,
+ op1.lower_bound (), op1.upper_bound (),
+ op2.lower_bound (), op2.upper_bound (), trio.op1_op2 ());
+
+ // Handle possible NANs by saturating to the appropriate INF if only
+ // one end is a NAN. If both ends are a NAN, just return a NAN.
+ bool lb_nan = real_isnan (&lb);
+ bool ub_nan = real_isnan (&ub);
+ if (lb_nan && ub_nan)
+ {
+ r.set_nan (type);
+ return true;
+ }
+ if (lb_nan)
+ lb = dconstninf;
+ else if (ub_nan)
+ ub = dconstinf;
+
+ r.set (type, lb, ub);
+
+ if (lb_nan || ub_nan || maybe_nan
+ || op1.maybe_isnan ()
+ || op2.maybe_isnan ())
+ // Keep the default NAN (with a varying sign) set by the setter.
+ ;
+ else
+ r.clear_nan ();
+
+ return true;
+}
+
+// For a given operation, fold two sets of ranges into [lb, ub].
+// MAYBE_NAN is set to TRUE if, in addition to any result in LB or
+// UB, the final range has the possiblity of a NAN.
+void
+range_operator_float::rv_fold (REAL_VALUE_TYPE &lb,
+ REAL_VALUE_TYPE &ub,
+ bool &maybe_nan,
+ tree type ATTRIBUTE_UNUSED,
+ const REAL_VALUE_TYPE &lh_lb ATTRIBUTE_UNUSED,
+ const REAL_VALUE_TYPE &lh_ub ATTRIBUTE_UNUSED,
+ const REAL_VALUE_TYPE &rh_lb ATTRIBUTE_UNUSED,
+ const REAL_VALUE_TYPE &rh_ub ATTRIBUTE_UNUSED,
+ relation_kind) const
+{
+ lb = dconstninf;
+ ub = dconstinf;
+ maybe_nan = true;
}
bool
@@ -192,6 +247,130 @@ frelop_early_resolve (irange &r, tree type,
&& relop_early_resolve (r, type, op1, op2, rel, my_rel));
}
+// Set VALUE to its next real value, or INF if the operation overflows.
+
+inline void
+frange_nextafter (enum machine_mode mode,
+ REAL_VALUE_TYPE &value,
+ const REAL_VALUE_TYPE &inf)
+{
+ if (MODE_COMPOSITE_P (mode)
+ && (real_isdenormal (&value, mode) || real_iszero (&value)))
+ {
+ // IBM extended denormals only have DFmode precision.
+ REAL_VALUE_TYPE tmp, tmp2;
+ real_convert (&tmp2, DFmode, &value);
+ real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2, &inf);
+ real_convert (&value, mode, &tmp);
+ }
+ else
+ {
+ REAL_VALUE_TYPE tmp;
+ real_nextafter (&tmp, REAL_MODE_FORMAT (mode), &value, &inf);
+ value = tmp;
+ }
+}
+
+// Like real_arithmetic, but round the result to INF if the operation
+// produced inexact results.
+//
+// ?? There is still one problematic case, i387. With
+// -fexcess-precision=standard we perform most SF/DFmode arithmetic in
+// XFmode (long_double_type_node), so that case is OK. But without
+// -mfpmath=sse, all the SF/DFmode computations are in XFmode
+// precision (64-bit mantissa) and only occassionally rounded to
+// SF/DFmode (when storing into memory from the 387 stack). Maybe
+// this is ok as well though it is just occassionally more precise. ??
+
+static void
+frange_arithmetic (enum tree_code code, tree type,
+ REAL_VALUE_TYPE &result,
+ const REAL_VALUE_TYPE &op1,
+ const REAL_VALUE_TYPE &op2,
+ const REAL_VALUE_TYPE &inf)
+{
+ REAL_VALUE_TYPE value;
+ enum machine_mode mode = TYPE_MODE (type);
+ bool mode_composite = MODE_COMPOSITE_P (mode);
+
+ bool inexact = real_arithmetic (&value, code, &op1, &op2);
+ real_convert (&result, mode, &value);
+
+ // Be extra careful if there may be discrepancies between the
+ // compile and runtime results.
+ bool round = false;
+ if (mode_composite)
+ round = true;
+ else
+ {
+ bool low = real_isneg (&inf);
+ round = (low ? !real_less (&result, &value)
+ : !real_less (&value, &result));
+ if (real_isinf (&result, !low)
+ && !real_isinf (&value)
+ && !flag_rounding_math)
+ {
+ // Use just [+INF, +INF] rather than [MAX, +INF]
+ // even if value is larger than MAX and rounds to
+ // nearest to +INF. Similarly just [-INF, -INF]
+ // rather than [-INF, +MAX] even if value is smaller
+ // than -MAX and rounds to nearest to -INF.
+ // Unless INEXACT is true, in that case we need some
+ // extra buffer.
+ if (!inexact)
+ round = false;
+ else
+ {
+ REAL_VALUE_TYPE tmp = result, tmp2;
+ frange_nextafter (mode, tmp, inf);
+ // TMP is at this point the maximum representable
+ // number.
+ real_arithmetic (&tmp2, MINUS_EXPR, &value, &tmp);
+ if (real_isneg (&tmp2) != low
+ && (REAL_EXP (&tmp2) - REAL_EXP (&tmp)
+ >= 2 - REAL_MODE_FORMAT (mode)->p))
+ round = false;
+ }
+ }
+ }
+ if (round && (inexact || !real_identical (&result, &value)))
+ {
+ if (mode_composite
+ && (real_isdenormal (&result, mode) || real_iszero (&result)))
+ {
+ // IBM extended denormals only have DFmode precision.
+ REAL_VALUE_TYPE tmp, tmp2;
+ real_convert (&tmp2, DFmode, &value);
+ real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2, &inf);
+ real_convert (&result, mode, &tmp);
+ }
+ else
+ frange_nextafter (mode, result, inf);
+ }
+ if (mode_composite)
+ switch (code)
+ {
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ // ibm-ldouble-format documents 1ulp for + and -.
+ frange_nextafter (mode, result, inf);
+ break;
+ case MULT_EXPR:
+ // ibm-ldouble-format documents 2ulps for *.
+ frange_nextafter (mode, result, inf);
+ frange_nextafter (mode, result, inf);
+ break;
+ case RDIV_EXPR:
+ // ibm-ldouble-format documents 3ulps for /.
+ frange_nextafter (mode, result, inf);
+ frange_nextafter (mode, result, inf);
+ frange_nextafter (mode, result, inf);
+ break;
+ default:
+ break;
+ }
+}
+
// Crop R to [-INF, MAX] where MAX is the maximum representable number
// for TYPE.
@@ -214,6 +393,18 @@ frange_drop_ninf (frange &r, tree type)
r.intersect (tmp);
}
+// Crop R to [MIN, MAX] where MAX is the maximum representable number
+// for TYPE and MIN the minimum representable number for TYPE.
+
+static inline void
+frange_drop_infs (frange &r, tree type)
+{
+ REAL_VALUE_TYPE max = real_max_representable (type);
+ REAL_VALUE_TYPE min = real_min_representable (type);
+ frange tmp (type, min, max);
+ r.intersect (tmp);
+}
+
// If zero is in R, make sure both -0.0 and +0.0 are in the range.
static inline void
@@ -267,9 +458,17 @@ build_lt (frange &r, tree type, const frange &val)
r.set_undefined ();
return false;
}
- // We only support closed intervals.
+
REAL_VALUE_TYPE ninf = frange_val_min (type);
- r.set (type, ninf, val.upper_bound ());
+ REAL_VALUE_TYPE prev = val.upper_bound ();
+ machine_mode mode = TYPE_MODE (type);
+ // Default to the conservatively correct closed ranges for
+ // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
+ // !HONOR_INFINITIES, nextafter will yield -INF, but frange::set()
+ // will crop the range appropriately.
+ if (!MODE_COMPOSITE_P (mode))
+ frange_nextafter (mode, prev, ninf);
+ r.set (type, ninf, prev);
return true;
}
@@ -310,9 +509,16 @@ build_gt (frange &r, tree type, const frange &val)
return false;
}
- // We only support closed intervals.
REAL_VALUE_TYPE inf = frange_val_max (type);
- r.set (type, val.lower_bound (), inf);
+ REAL_VALUE_TYPE next = val.lower_bound ();
+ machine_mode mode = TYPE_MODE (type);
+ // Default to the conservatively correct closed ranges for
+ // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
+ // !HONOR_INFINITIES, nextafter will yield +INF, but frange::set()
+ // will crop the range appropriately.
+ if (!MODE_COMPOSITE_P (mode))
+ frange_nextafter (mode, next, inf);
+ r.set (type, next, inf);
return true;
}
@@ -1276,13 +1482,14 @@ foperator_abs::op1_range (frange &r, tree type,
neg_nan.set_nan (type, true);
r.union_ (neg_nan);
}
- if (r.known_isnan ())
+ if (r.known_isnan () || r.undefined_p ())
return true;
// Then add the negative of each pair:
// ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
- r.union_ (frange (type,
- real_value_negate (&positives.upper_bound ()),
- real_value_negate (&positives.lower_bound ())));
+ frange negatives (type, real_value_negate (&positives.upper_bound ()),
+ real_value_negate (&positives.lower_bound ()));
+ negatives.clear_nan ();
+ r.union_ (negatives);
return true;
}
@@ -1332,7 +1539,10 @@ foperator_unordered_lt::op1_range (frange &r, tree type,
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- build_lt (r, type, op2);
+ if (op2.known_isnan ())
+ r.set_varying (type);
+ else
+ build_lt (r, type, op2);
break;
case BRS_FALSE:
@@ -1359,7 +1569,10 @@ foperator_unordered_lt::op2_range (frange &r, tree type,
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- build_gt (r, type, op1);
+ if (op1.known_isnan ())
+ r.set_varying (type);
+ else
+ build_gt (r, type, op1);
break;
case BRS_FALSE:
@@ -1420,7 +1633,10 @@ foperator_unordered_le::op1_range (frange &r, tree type,
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- build_le (r, type, op2);
+ if (op2.known_isnan ())
+ r.set_varying (type);
+ else
+ build_le (r, type, op2);
break;
case BRS_FALSE:
@@ -1448,7 +1664,10 @@ foperator_unordered_le::op2_range (frange &r,
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- build_ge (r, type, op1);
+ if (op1.known_isnan ())
+ r.set_varying (type);
+ else
+ build_ge (r, type, op1);
break;
case BRS_FALSE:
@@ -1511,7 +1730,10 @@ foperator_unordered_gt::op1_range (frange &r,
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- build_gt (r, type, op2);
+ if (op2.known_isnan ())
+ r.set_varying (type);
+ else
+ build_gt (r, type, op2);
break;
case BRS_FALSE:
@@ -1539,7 +1761,10 @@ foperator_unordered_gt::op2_range (frange &r,
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- build_lt (r, type, op1);
+ if (op1.known_isnan ())
+ r.set_varying (type);
+ else
+ build_lt (r, type, op1);
break;
case BRS_FALSE:
@@ -1602,7 +1827,10 @@ foperator_unordered_ge::op1_range (frange &r,
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- build_ge (r, type, op2);
+ if (op2.known_isnan ())
+ r.set_varying (type);
+ else
+ build_ge (r, type, op2);
break;
case BRS_FALSE:
@@ -1629,7 +1857,10 @@ foperator_unordered_ge::op2_range (frange &r, tree type,
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- build_le (r, type, op1);
+ if (op1.known_isnan ())
+ r.set_varying (type);
+ else
+ build_le (r, type, op1);
break;
case BRS_FALSE:
@@ -1722,6 +1953,578 @@ foperator_unordered_equal::op1_range (frange &r, tree type,
return true;
}
+// Final tweaks for float binary op op1_range/op2_range.
+// Return TRUE if the operation is performed and a valid range is available.
+
+static bool
+float_binary_op_range_finish (bool ret, frange &r, tree type,
+ const frange &lhs, bool div_op2 = false)
+{
+ if (!ret)
+ return false;
+
+ // If we get a known NAN from reverse op, it means either that
+ // the other operand was known NAN (in that case we know nothing),
+ // or the reverse operation introduced a known NAN.
+ // Say for lhs = op1 * op2 if lhs is [-0, +0] and op2 is too,
+ // 0 / 0 is known NAN. Just punt in that case.
+ // If NANs aren't honored, we get for 0 / 0 UNDEFINED, so punt as well.
+ // Or if lhs is a known NAN, we also don't know anything.
+ if (r.known_isnan () || lhs.known_isnan () || r.undefined_p ())
+ {
+ r.set_varying (type);
+ return true;
+ }
+
+ // If lhs isn't NAN, then neither operand could be NAN,
+ // even if the reverse operation does introduce a maybe_nan.
+ if (!lhs.maybe_isnan ())
+ {
+ r.clear_nan ();
+ if (div_op2
+ ? !(real_compare (LE_EXPR, &lhs.lower_bound (), &dconst0)
+ && real_compare (GE_EXPR, &lhs.upper_bound (), &dconst0))
+ : !(real_isinf (&lhs.lower_bound ())
+ || real_isinf (&lhs.upper_bound ())))
+ // For reverse + or - or * or op1 of /, if result is finite, then
+ // r must be finite too, as X + INF or X - INF or X * INF or
+ // INF / X is always +-INF or NAN. For op2 of /, if result is
+ // non-zero and not NAN, r must be finite, as X / INF is always
+ // 0 or NAN.
+ frange_drop_infs (r, type);
+ }
+ // If lhs is a maybe or known NAN, the operand could be
+ // NAN.
+ else
+ r.update_nan ();
+ return true;
+}
+
+// True if [lb, ub] is [+-0, +-0].
+static bool
+zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
+{
+ return real_iszero (&lb) && real_iszero (&ub);
+}
+
+// True if +0 or -0 is in [lb, ub] range.
+static bool
+contains_zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
+{
+ return (real_compare (LE_EXPR, &lb, &dconst0)
+ && real_compare (GE_EXPR, &ub, &dconst0));
+}
+
+// True if [lb, ub] is [-INF, -INF] or [+INF, +INF].
+static bool
+singleton_inf_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
+{
+ return real_isinf (&lb) && real_isinf (&ub, real_isneg (&lb));
+}
+
+// Return -1 if binary op result must have sign bit set,
+// 1 if binary op result must have sign bit clear,
+// 0 otherwise.
+// Sign bit of binary op result is exclusive or of the
+// operand's sign bits.
+static int
+signbit_known_p (const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
+ const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub)
+{
+ if (real_isneg (&lh_lb) == real_isneg (&lh_ub)
+ && real_isneg (&rh_lb) == real_isneg (&rh_ub))
+ {
+ if (real_isneg (&lh_lb) == real_isneg (&rh_ub))
+ return 1;
+ else
+ return -1;
+ }
+ return 0;
+}
+
+// Set [lb, ub] to [-0, -0], [-0, +0] or [+0, +0] depending on
+// signbit_known.
+static void
+zero_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
+{
+ ub = lb = dconst0;
+ if (signbit_known <= 0)
+ lb = real_value_negate (&dconst0);
+ if (signbit_known < 0)
+ ub = lb;
+}
+
+// Set [lb, ub] to [-INF, -INF], [-INF, +INF] or [+INF, +INF] depending on
+// signbit_known.
+static void
+inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
+{
+ if (signbit_known > 0)
+ ub = lb = dconstinf;
+ else if (signbit_known < 0)
+ ub = lb = dconstninf;
+ else
+ {
+ lb = dconstninf;
+ ub = dconstinf;
+ }
+}
+
+// Set [lb, ub] to [-INF, -0], [-INF, +INF] or [+0, +INF] depending on
+// signbit_known.
+static void
+zero_to_inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
+{
+ if (signbit_known > 0)
+ {
+ lb = dconst0;
+ ub = dconstinf;
+ }
+ else if (signbit_known < 0)
+ {
+ lb = dconstninf;
+ ub = real_value_negate (&dconst0);
+ }
+ else
+ {
+ lb = dconstninf;
+ ub = dconstinf;
+ }
+}
+
+class foperator_plus : public range_operator_float
+{
+ using range_operator_float::op1_range;
+ using range_operator_float::op2_range;
+public:
+ virtual bool op1_range (frange &r, tree type,
+ const frange &lhs,
+ const frange &op2,
+ relation_trio = TRIO_VARYING) const final override
+ {
+ if (lhs.undefined_p ())
+ return false;
+ range_op_handler minus (MINUS_EXPR, type);
+ if (!minus)
+ return false;
+ return float_binary_op_range_finish (minus.fold_range (r, type, lhs, op2),
+ r, type, lhs);
+ }
+ virtual bool op2_range (frange &r, tree type,
+ const frange &lhs,
+ const frange &op1,
+ relation_trio = TRIO_VARYING) const final override
+ {
+ return op1_range (r, type, lhs, op1);
+ }
+private:
+ void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan,
+ tree type,
+ const REAL_VALUE_TYPE &lh_lb,
+ const REAL_VALUE_TYPE &lh_ub,
+ const REAL_VALUE_TYPE &rh_lb,
+ const REAL_VALUE_TYPE &rh_ub,
+ relation_kind) const final override
+ {
+ frange_arithmetic (PLUS_EXPR, type, lb, lh_lb, rh_lb, dconstninf);
+ frange_arithmetic (PLUS_EXPR, type, ub, lh_ub, rh_ub, dconstinf);
+
+ // [-INF] + [+INF] = NAN
+ if (real_isinf (&lh_lb, true) && real_isinf (&rh_ub, false))
+ maybe_nan = true;
+ // [+INF] + [-INF] = NAN
+ else if (real_isinf (&lh_ub, false) && real_isinf (&rh_lb, true))
+ maybe_nan = true;
+ else
+ maybe_nan = false;
+ }
+} fop_plus;
+
+
+class foperator_minus : public range_operator_float
+{
+ using range_operator_float::op1_range;
+ using range_operator_float::op2_range;
+public:
+ virtual bool op1_range (frange &r, tree type,
+ const frange &lhs,
+ const frange &op2,
+ relation_trio = TRIO_VARYING) const final override
+ {
+ if (lhs.undefined_p ())
+ return false;
+ return float_binary_op_range_finish (fop_plus.fold_range (r, type, lhs,
+ op2),
+ r, type, lhs);
+ }
+ virtual bool op2_range (frange &r, tree type,
+ const frange &lhs,
+ const frange &op1,
+ relation_trio = TRIO_VARYING) const final override
+ {
+ if (lhs.undefined_p ())
+ return false;
+ return float_binary_op_range_finish (fold_range (r, type, op1, lhs),
+ r, type, lhs);
+ }
+private:
+ void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan,
+ tree type,
+ const REAL_VALUE_TYPE &lh_lb,
+ const REAL_VALUE_TYPE &lh_ub,
+ const REAL_VALUE_TYPE &rh_lb,
+ const REAL_VALUE_TYPE &rh_ub,
+ relation_kind) const final override
+ {
+ frange_arithmetic (MINUS_EXPR, type, lb, lh_lb, rh_ub, dconstninf);
+ frange_arithmetic (MINUS_EXPR, type, ub, lh_ub, rh_lb, dconstinf);
+
+ // [+INF] - [+INF] = NAN
+ if (real_isinf (&lh_ub, false) && real_isinf (&rh_ub, false))
+ maybe_nan = true;
+ // [-INF] - [-INF] = NAN
+ else if (real_isinf (&lh_lb, true) && real_isinf (&rh_lb, true))
+ maybe_nan = true;
+ else
+ maybe_nan = false;
+ }
+} fop_minus;
+
+
+class foperator_mult_div_base : public range_operator_float
+{
+protected:
+ // Given CP[0] to CP[3] floating point values rounded to -INF,
+ // set LB to the smallest of them (treating -0 as smaller to +0).
+ // Given CP[4] to CP[7] floating point values rounded to +INF,
+ // set UB to the largest of them (treating -0 as smaller to +0).
+ static void find_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
+ const REAL_VALUE_TYPE (&cp)[8])
+ {
+ lb = cp[0];
+ ub = cp[4];
+ for (int i = 1; i < 4; ++i)
+ {
+ if (real_less (&cp[i], &lb)
+ || (real_iszero (&lb) && real_isnegzero (&cp[i])))
+ lb = cp[i];
+ if (real_less (&ub, &cp[i + 4])
+ || (real_isnegzero (&ub) && real_iszero (&cp[i + 4])))
+ ub = cp[i + 4];
+ }
+ }
+};
+
+
+class foperator_mult : public foperator_mult_div_base
+{
+ using range_operator_float::op1_range;
+ using range_operator_float::op2_range;
+public:
+ virtual bool op1_range (frange &r, tree type,
+ const frange &lhs,
+ const frange &op2,
+ relation_trio = TRIO_VARYING) const final override
+ {
+ if (lhs.undefined_p ())
+ return false;
+ range_op_handler rdiv (RDIV_EXPR, type);
+ if (!rdiv)
+ return false;
+ bool ret = rdiv.fold_range (r, type, lhs, op2);
+ if (ret == false)
+ return false;
+ if (lhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
+ return float_binary_op_range_finish (ret, r, type, lhs);
+ const REAL_VALUE_TYPE &lhs_lb = lhs.lower_bound ();
+ const REAL_VALUE_TYPE &lhs_ub = lhs.upper_bound ();
+ const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
+ const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
+ if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op2_lb, op2_ub))
+ || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
+ && (real_isinf (&op2_lb) || real_isinf (&op2_ub))))
+ {
+ // If both lhs and op2 could be zeros or both could be infinities,
+ // we don't know anything about op1 except maybe for the sign
+ // and perhaps if it can be NAN or not.
+ REAL_VALUE_TYPE lb, ub;
+ int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
+ zero_to_inf_range (lb, ub, signbit_known);
+ r.set (type, lb, ub);
+ }
+ // Otherwise, if op2 is a singleton INF and lhs doesn't include INF,
+ // or if lhs must be zero and op2 doesn't include zero, it would be
+ // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF
+ // range. Those are supersets of UNDEFINED, so let's keep that way.
+ return float_binary_op_range_finish (ret, r, type, lhs);
+ }
+ virtual bool op2_range (frange &r, tree type,
+ const frange &lhs,
+ const frange &op1,
+ relation_trio = TRIO_VARYING) const final override
+ {
+ return op1_range (r, type, lhs, op1);
+ }
+private:
+ void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan,
+ tree type,
+ const REAL_VALUE_TYPE &lh_lb,
+ const REAL_VALUE_TYPE &lh_ub,
+ const REAL_VALUE_TYPE &rh_lb,
+ const REAL_VALUE_TYPE &rh_ub,
+ relation_kind kind) const final override
+ {
+ bool is_square
+ = (kind == VREL_EQ
+ && real_equal (&lh_lb, &rh_lb)
+ && real_equal (&lh_ub, &rh_ub)
+ && real_isneg (&lh_lb) == real_isneg (&rh_lb)
+ && real_isneg (&lh_ub) == real_isneg (&rh_ub));
+
+ maybe_nan = false;
+ // x * x never produces a new NAN and we only multiply the same
+ // values, so the 0 * INF problematic cases never appear there.
+ if (!is_square)
+ {
+ // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN.
+ if ((zero_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub))
+ || (zero_p (rh_lb, rh_ub) && singleton_inf_p (lh_lb, lh_ub)))
+ {
+ real_nan (&lb, "", 0, TYPE_MODE (type));
+ ub = lb;
+ maybe_nan = true;
+ return;
+ }
+
+ // Otherwise, if one range includes zero and the other ends with +-INF,
+ // it is a maybe NAN.
+ if ((contains_zero_p (lh_lb, lh_ub)
+ && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
+ || (contains_zero_p (rh_lb, rh_ub)
+ && (real_isinf (&lh_lb) || real_isinf (&lh_ub))))
+ {
+ maybe_nan = true;
+
+ int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
+
+ // If one of the ranges that includes INF is singleton
+ // and the other range includes zero, the resulting
+ // range is INF and NAN, because the 0 * INF boundary
+ // case will be NAN, but already nextafter (0, 1) * INF
+ // is INF.
+ if (singleton_inf_p (lh_lb, lh_ub)
+ || singleton_inf_p (rh_lb, rh_ub))
+ return inf_range (lb, ub, signbit_known);
+
+ // If one of the multiplicands must be zero, the resulting
+ // range is +-0 and NAN.
+ if (zero_p (lh_lb, lh_ub) || zero_p (rh_lb, rh_ub))
+ return zero_range (lb, ub, signbit_known);
+
+ // Otherwise one of the multiplicands could be
+ // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF]
+ // or similarly with different signs. 0.0 * DBL_MAX
+ // is still 0.0, nextafter (0.0, 1.0) * INF is still INF,
+ // so if the signs are always the same or always different,
+ // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING.
+ return zero_to_inf_range (lb, ub, signbit_known);
+ }
+ }
+
+ REAL_VALUE_TYPE cp[8];
+ // Do a cross-product. At this point none of the multiplications
+ // should produce a NAN.
+ frange_arithmetic (MULT_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
+ frange_arithmetic (MULT_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
+ if (is_square)
+ {
+ // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub)
+ // as maximum and -0.0 as minimum if 0.0 is in the range,
+ // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub).
+ // -0.0 rather than 0.0 because VREL_EQ doesn't prove that
+ // x and y are bitwise equal, just that they compare equal.
+ if (contains_zero_p (lh_lb, lh_ub))
+ {
+ if (real_isneg (&lh_lb) == real_isneg (&lh_ub))
+ cp[1] = dconst0;
+ else
+ cp[1] = real_value_negate (&dconst0);
+ }
+ else
+ cp[1] = cp[0];
+ cp[2] = cp[0];
+ cp[5] = cp[4];
+ cp[6] = cp[4];
+ }
+ else
+ {
+ frange_arithmetic (MULT_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
+ frange_arithmetic (MULT_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
+ frange_arithmetic (MULT_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
+ frange_arithmetic (MULT_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
+ }
+ frange_arithmetic (MULT_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
+ frange_arithmetic (MULT_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);
+
+ find_range (lb, ub, cp);
+ }
+} fop_mult;
+
+
+class foperator_div : public foperator_mult_div_base
+{
+ using range_operator_float::op1_range;
+ using range_operator_float::op2_range;
+public:
+ virtual bool op1_range (frange &r, tree type,
+ const frange &lhs,
+ const frange &op2,
+ relation_trio = TRIO_VARYING) const final override
+ {
+ if (lhs.undefined_p ())
+ return false;
+ bool ret = fop_mult.fold_range (r, type, lhs, op2);
+ if (!ret)
+ return ret;
+ if (lhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
+ return float_binary_op_range_finish (ret, r, type, lhs);
+ const REAL_VALUE_TYPE &lhs_lb = lhs.lower_bound ();
+ const REAL_VALUE_TYPE &lhs_ub = lhs.upper_bound ();
+ const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
+ const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
+ if ((contains_zero_p (lhs_lb, lhs_ub)
+ && (real_isinf (&op2_lb) || real_isinf (&op2_ub)))
+ || ((contains_zero_p (op2_lb, op2_ub))
+ && (real_isinf (&lhs_lb) || real_isinf (&lhs_ub))))
+ {
+ // If both lhs could be zero and op2 infinity or vice versa,
+ // we don't know anything about op1 except maybe for the sign
+ // and perhaps if it can be NAN or not.
+ REAL_VALUE_TYPE lb, ub;
+ int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
+ zero_to_inf_range (lb, ub, signbit_known);
+ r.set (type, lb, ub);
+ }
+ return float_binary_op_range_finish (ret, r, type, lhs);
+ }
+ virtual bool op2_range (frange &r, tree type,
+ const frange &lhs,
+ const frange &op1,
+ relation_trio = TRIO_VARYING) const final override
+ {
+ if (lhs.undefined_p ())
+ return false;
+ bool ret = fold_range (r, type, op1, lhs);
+ if (!ret)
+ return ret;
+ if (lhs.known_isnan () || op1.known_isnan () || op1.undefined_p ())
+ return float_binary_op_range_finish (ret, r, type, lhs, true);
+ const REAL_VALUE_TYPE &lhs_lb = lhs.lower_bound ();
+ const REAL_VALUE_TYPE &lhs_ub = lhs.upper_bound ();
+ const REAL_VALUE_TYPE &op1_lb = op1.lower_bound ();
+ const REAL_VALUE_TYPE &op1_ub = op1.upper_bound ();
+ if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op1_lb, op1_ub))
+ || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
+ && (real_isinf (&op1_lb) || real_isinf (&op1_ub))))
+ {
+ // If both lhs and op1 could be zeros or both could be infinities,
+ // we don't know anything about op2 except maybe for the sign
+ // and perhaps if it can be NAN or not.
+ REAL_VALUE_TYPE lb, ub;
+ int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op1_lb, op1_ub);
+ zero_to_inf_range (lb, ub, signbit_known);
+ r.set (type, lb, ub);
+ }
+ return float_binary_op_range_finish (ret, r, type, lhs, true);
+ }
+private:
+ void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan,
+ tree type,
+ const REAL_VALUE_TYPE &lh_lb,
+ const REAL_VALUE_TYPE &lh_ub,
+ const REAL_VALUE_TYPE &rh_lb,
+ const REAL_VALUE_TYPE &rh_ub,
+ relation_kind) const final override
+ {
+ // +-0.0 / +-0.0 or +-INF / +-INF is a known NAN.
+ if ((zero_p (lh_lb, lh_ub) && zero_p (rh_lb, rh_ub))
+ || (singleton_inf_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub)))
+ {
+ real_nan (&lb, "", 0, TYPE_MODE (type));
+ ub = lb;
+ maybe_nan = true;
+ return;
+ }
+
+ // If +-0.0 is in both ranges, it is a maybe NAN.
+ if (contains_zero_p (lh_lb, lh_ub) && contains_zero_p (rh_lb, rh_ub))
+ maybe_nan = true;
+ // If +-INF is in both ranges, it is a maybe NAN.
+ else if ((real_isinf (&lh_lb) || real_isinf (&lh_ub))
+ && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
+ maybe_nan = true;
+ else
+ maybe_nan = false;
+
+ int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
+
+ // If dividend must be zero, the range is just +-0
+ // (including if the divisor is +-INF).
+ // If divisor must be +-INF, the range is just +-0
+ // (including if the dividend is zero).
+ if (zero_p (lh_lb, lh_ub) || singleton_inf_p (rh_lb, rh_ub))
+ return zero_range (lb, ub, signbit_known);
+
+ // If divisor must be zero, the range is just +-INF
+ // (including if the dividend is +-INF).
+ // If dividend must be +-INF, the range is just +-INF
+ // (including if the dividend is zero).
+ if (zero_p (rh_lb, rh_ub) || singleton_inf_p (lh_lb, lh_ub))
+ return inf_range (lb, ub, signbit_known);
+
+ // Otherwise if both operands may be zero, divisor could be
+ // nextafter(0.0, +-1.0) and dividend +-0.0
+ // in which case result is going to INF or vice versa and
+ // result +0.0. So, all we can say for that case is if the
+ // signs of divisor and dividend are always the same we have
+ // [+0.0, +INF], if they are always different we have
+ // [-INF, -0.0]. If they vary, VARING.
+ // If both may be +-INF, divisor could be INF and dividend FLT_MAX,
+ // in which case result is going to INF or vice versa and
+ // result +0.0. So, all we can say for that case is if the
+ // signs of divisor and dividend are always the same we have
+ // [+0.0, +INF], if they are always different we have
+ // [-INF, -0.0]. If they vary, VARYING.
+ if (maybe_nan)
+ return zero_to_inf_range (lb, ub, signbit_known);
+
+ REAL_VALUE_TYPE cp[8];
+ // Do a cross-division. At this point none of the divisions should
+ // produce a NAN.
+ frange_arithmetic (RDIV_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
+ frange_arithmetic (RDIV_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
+ frange_arithmetic (RDIV_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
+ frange_arithmetic (RDIV_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
+ frange_arithmetic (RDIV_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
+ frange_arithmetic (RDIV_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
+ frange_arithmetic (RDIV_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
+ frange_arithmetic (RDIV_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);
+
+ find_range (lb, ub, cp);
+
+ // If divisor may be zero (but is not known to be only zero),
+ // and dividend can't be zero, the range can go up to -INF or +INF
+ // depending on the signs.
+ if (contains_zero_p (rh_lb, rh_ub))
+ {
+ if (signbit_known <= 0)
+ real_inf (&lb, true);
+ if (signbit_known >= 0)
+ real_inf (&ub, false);
+ }
+ }
+} fop_div;
+
// Instantiate a range_op_table for floating point operations.
static floating_op_table global_floating_table;
@@ -1754,6 +2557,10 @@ floating_op_table::floating_op_table ()
set (ABS_EXPR, fop_abs);
set (NEGATE_EXPR, fop_negate);
+ set (PLUS_EXPR, fop_plus);
+ set (MINUS_EXPR, fop_minus);
+ set (MULT_EXPR, fop_mult);
+ set (RDIV_EXPR, fop_div);
}
// Return a pointer to the range_operator_float instance, if there is
@@ -1809,6 +2616,16 @@ range_op_float_tests ()
r1 = frange_float ("-1", "-0");
r1.update_nan (false);
ASSERT_EQ (r, r1);
+
+ // [-INF,+INF] + [-INF,+INF] could be a NAN.
+ range_op_handler plus (PLUS_EXPR, float_type_node);
+ r0.set_varying (float_type_node);
+ r1.set_varying (float_type_node);
+ r0.clear_nan ();
+ r1.clear_nan ();
+ plus.fold_range (r, float_type_node, r0, r1);
+ if (HONOR_NANS (float_type_node))
+ ASSERT_TRUE (r.maybe_isnan ());
}
} // namespace selftest
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 49ee7be..e53f3a7 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -46,6 +46,51 @@ along with GCC; see the file COPYING3. If not see
#include "wide-int.h"
#include "value-relation.h"
#include "range-op.h"
+#include "tree-ssa-ccp.h"
+
+// Convert irange bitmasks into a VALUE MASK pair suitable for calling CCP.
+
+static void
+irange_to_masked_value (const irange &r, widest_int &value, widest_int &mask)
+{
+ if (r.singleton_p ())
+ {
+ mask = 0;
+ value = widest_int::from (r.lower_bound (), TYPE_SIGN (r.type ()));
+ }
+ else
+ {
+ mask = widest_int::from (r.get_nonzero_bits (), TYPE_SIGN (r.type ()));
+ value = 0;
+ }
+}
+
+// Update the known bitmasks in R when applying the operation CODE to
+// LH and RH.
+
+static void
+update_known_bitmask (irange &r, tree_code code,
+ const irange &lh, const irange &rh)
+{
+ if (r.undefined_p () || lh.undefined_p () || rh.undefined_p ())
+ return;
+
+ widest_int value, mask, lh_mask, rh_mask, lh_value, rh_value;
+ tree type = r.type ();
+ signop sign = TYPE_SIGN (type);
+ int prec = TYPE_PRECISION (type);
+ signop lh_sign = TYPE_SIGN (lh.type ());
+ signop rh_sign = TYPE_SIGN (rh.type ());
+ int lh_prec = TYPE_PRECISION (lh.type ());
+ int rh_prec = TYPE_PRECISION (rh.type ());
+
+ irange_to_masked_value (lh, lh_value, lh_mask);
+ irange_to_masked_value (rh, rh_value, rh_mask);
+ bit_value_binop (code, sign, prec, &value, &mask,
+ lh_sign, lh_prec, lh_value, lh_mask,
+ rh_sign, rh_prec, rh_value, rh_mask);
+ r.set_nonzero_bits (value | mask);
+}
// Return the upper limit for a type.
@@ -197,6 +242,7 @@ range_operator::fold_range (irange &r, tree type,
wi_fold_in_parts (r, type, lh.lower_bound (), lh.upper_bound (),
rh.lower_bound (), rh.upper_bound ());
op1_op2_relation_effect (r, type, lh, rh, rel);
+ update_known_bitmask (r, m_code, lh, rh);
return true;
}
@@ -214,10 +260,12 @@ range_operator::fold_range (irange &r, tree type,
if (r.varying_p ())
{
op1_op2_relation_effect (r, type, lh, rh, rel);
+ update_known_bitmask (r, m_code, lh, rh);
return true;
}
}
op1_op2_relation_effect (r, type, lh, rh, rel);
+ update_known_bitmask (r, m_code, lh, rh);
return true;
}
@@ -1749,17 +1797,18 @@ public:
const wide_int &lh_lb,
const wide_int &lh_ub,
const wide_int &rh_lb,
- const wide_int &rh_ub) const;
+ const wide_int &rh_ub) const final override;
virtual bool wi_op_overflows (wide_int &res, tree type,
- const wide_int &w0, const wide_int &w1) const;
+ const wide_int &w0, const wide_int &w1)
+ const final override;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
- relation_trio) const;
+ relation_trio) const final override;
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
- relation_trio) const;
+ relation_trio) const final override;
} op_mult;
bool
@@ -1880,8 +1929,20 @@ operator_mult::wi_fold (irange &r, tree type,
// diff = max - min
prod2 = prod3 - prod0;
if (wi::geu_p (prod2, sizem1))
- // The range covers all values.
- r.set_varying (type);
+ {
+ // Multiplying by X, where X is a power of 2 is [0,0][X,+INF].
+ if (TYPE_UNSIGNED (type) && rh_lb == rh_ub
+ && wi::exact_log2 (rh_lb) != -1 && prec > 1)
+ {
+ r.set (type, rh_lb, wi::max_value (prec, sign));
+ int_range<2> zero;
+ zero.set_zero (type);
+ r.union_ (zero);
+ }
+ else
+ // The range covers all values.
+ r.set_varying (type);
+ }
else
{
wide_int new_lb = wide_int::from (prod0, prec, sign);
@@ -1894,16 +1955,14 @@ operator_mult::wi_fold (irange &r, tree type,
class operator_div : public cross_product_operator
{
public:
- operator_div (enum tree_code c) { code = c; }
virtual void wi_fold (irange &r, tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
const wide_int &rh_lb,
- const wide_int &rh_ub) const;
+ const wide_int &rh_ub) const final override;
virtual bool wi_op_overflows (wide_int &res, tree type,
- const wide_int &, const wide_int &) const;
-private:
- enum tree_code code;
+ const wide_int &, const wide_int &)
+ const final override;
};
bool
@@ -1916,13 +1975,9 @@ operator_div::wi_op_overflows (wide_int &res, tree type,
wi::overflow_type overflow = wi::OVF_NONE;
signop sign = TYPE_SIGN (type);
- switch (code)
+ switch (m_code)
{
case EXACT_DIV_EXPR:
- // EXACT_DIV_EXPR is implemented as TRUNC_DIV_EXPR in
- // operator_exact_divide. No need to handle it here.
- gcc_unreachable ();
- break;
case TRUNC_DIV_EXPR:
res = wi::div_trunc (w0, w1, sign, &overflow);
break;
@@ -1998,17 +2053,11 @@ operator_div::wi_fold (irange &r, tree type,
gcc_checking_assert (!r.undefined_p ());
}
-operator_div op_trunc_div (TRUNC_DIV_EXPR);
-operator_div op_floor_div (FLOOR_DIV_EXPR);
-operator_div op_round_div (ROUND_DIV_EXPR);
-operator_div op_ceil_div (CEIL_DIV_EXPR);
-
class operator_exact_divide : public operator_div
{
using range_operator::op1_range;
public:
- operator_exact_divide () : operator_div (TRUNC_DIV_EXPR) { }
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
@@ -2430,7 +2479,7 @@ private:
const irange &outer) const;
void fold_pair (irange &r, unsigned index, const irange &inner,
const irange &outer) const;
-} op_convert;
+};
// Add a partial equivalence between the LHS and op1 for casts.
@@ -2754,14 +2803,9 @@ operator_logical_and::op2_range (irange &r, tree type,
class operator_bitwise_and : public range_operator
{
- using range_operator::fold_range;
using range_operator::op1_range;
using range_operator::op2_range;
public:
- virtual bool fold_range (irange &r, tree type,
- const irange &lh,
- const irange &rh,
- relation_trio rel = TRIO_VARYING) const;
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
const irange &op2,
@@ -2785,22 +2829,6 @@ private:
const irange &op2) const;
} op_bitwise_and;
-bool
-operator_bitwise_and::fold_range (irange &r, tree type,
- const irange &lh,
- const irange &rh,
- relation_trio) const
-{
- if (range_operator::fold_range (r, type, lh, rh))
- {
- if (!lh.undefined_p () && !rh.undefined_p ())
- r.set_nonzero_bits (wi::bit_and (lh.get_nonzero_bits (),
- rh.get_nonzero_bits ()));
- return true;
- }
- return false;
-}
-
// Optimize BIT_AND_EXPR, BIT_IOR_EXPR and BIT_XOR_EXPR of signed types
// by considering the number of leading redundant sign bit copies.
@@ -3054,6 +3082,34 @@ set_nonzero_range_from_mask (irange &r, tree type, const irange &lhs)
r.set_varying (type);
}
+/* Find out smallest RES where RES > VAL && (RES & MASK) == RES, if any
+ (otherwise return VAL). VAL and MASK must be zero-extended for
+ precision PREC. If SGNBIT is non-zero, first xor VAL with SGNBIT
+ (to transform signed values into unsigned) and at the end xor
+ SGNBIT back. */
+
+wide_int
+masked_increment (const wide_int &val_in, const wide_int &mask,
+ const wide_int &sgnbit, unsigned int prec)
+{
+ wide_int bit = wi::one (prec), res;
+ unsigned int i;
+
+ wide_int val = val_in ^ sgnbit;
+ for (i = 0; i < prec; i++, bit += bit)
+ {
+ res = mask;
+ if ((res & bit) == 0)
+ continue;
+ res = bit - 1;
+ res = wi::bit_and_not (val + bit, res);
+ res &= mask;
+ if (wi::gtu_p (res, val))
+ return res ^ sgnbit;
+ }
+ return val ^ sgnbit;
+}
+
// This was shamelessly stolen from register_edge_assert_for_2 and
// adjusted to work with iranges.
@@ -3473,6 +3529,9 @@ operator_bitwise_xor::op1_range (irange &r, tree type,
r.set_varying (type);
else if (op2.zero_p ())
r = range_true (type);
+ // See get_bool_state for the rationale
+ else if (op2.contains_p (build_zero_cst (op2.type ())))
+ r = range_true_and_false (type);
else
r = range_false (type);
break;
@@ -3784,7 +3843,7 @@ public:
const irange &op1,
const irange &op2,
relation_kind rel) const;
-} op_identity;
+};
// Determine if there is a relationship between LHS and OP1.
@@ -3829,7 +3888,7 @@ public:
const irange &op1,
const irange &op2,
relation_trio rel = TRIO_VARYING) const;
-} op_unknown;
+};
bool
operator_unknown::fold_range (irange &r, tree type,
@@ -4152,7 +4211,7 @@ public:
virtual void wi_fold (irange & r, tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb, const wide_int &rh_ub) const;
-} op_ptr_min_max;
+};
void
pointer_min_max_operator::wi_fold (irange &r, tree type,
@@ -4279,8 +4338,21 @@ range_op_table::set (enum tree_code code, range_operator &op)
{
gcc_checking_assert (m_range_tree[code] == NULL);
m_range_tree[code] = &op;
+ gcc_checking_assert (op.m_code == ERROR_MARK || op.m_code == code);
+ op.m_code = code;
}
+// Shared operators that require separate instantiations because they
+// do not share a common tree code.
+static operator_cast op_nop, op_convert;
+static operator_identity op_ssa, op_paren, op_obj_type;
+static operator_unknown op_realpart, op_imagpart;
+static pointer_min_max_operator op_ptr_min, op_ptr_max;
+static operator_div op_trunc_div;
+static operator_div op_floor_div;
+static operator_div op_round_div;
+static operator_div op_ceil_div;
+
// Instantiate a range op table for integral operations.
class integral_table : public range_op_table
@@ -4309,7 +4381,7 @@ integral_table::integral_table ()
set (EXACT_DIV_EXPR, op_exact_div);
set (LSHIFT_EXPR, op_lshift);
set (RSHIFT_EXPR, op_rshift);
- set (NOP_EXPR, op_convert);
+ set (NOP_EXPR, op_nop);
set (CONVERT_EXPR, op_convert);
set (TRUTH_AND_EXPR, op_logical_and);
set (BIT_AND_EXPR, op_bitwise_and);
@@ -4320,11 +4392,11 @@ integral_table::integral_table ()
set (TRUTH_NOT_EXPR, op_logical_not);
set (BIT_NOT_EXPR, op_bitwise_not);
set (INTEGER_CST, op_integer_cst);
- set (SSA_NAME, op_identity);
- set (PAREN_EXPR, op_identity);
- set (OBJ_TYPE_REF, op_identity);
- set (IMAGPART_EXPR, op_unknown);
- set (REALPART_EXPR, op_unknown);
+ set (SSA_NAME, op_ssa);
+ set (PAREN_EXPR, op_paren);
+ set (OBJ_TYPE_REF, op_obj_type);
+ set (IMAGPART_EXPR, op_imagpart);
+ set (REALPART_EXPR, op_realpart);
set (POINTER_DIFF_EXPR, op_pointer_diff);
set (ABS_EXPR, op_abs);
set (ABSU_EXPR, op_absu);
@@ -4344,8 +4416,8 @@ pointer_table::pointer_table ()
{
set (BIT_AND_EXPR, op_pointer_and);
set (BIT_IOR_EXPR, op_pointer_or);
- set (MIN_EXPR, op_ptr_min_max);
- set (MAX_EXPR, op_ptr_min_max);
+ set (MIN_EXPR, op_ptr_min);
+ set (MAX_EXPR, op_ptr_max);
set (POINTER_PLUS_EXPR, op_pointer_plus);
set (EQ_EXPR, op_equal);
@@ -4354,10 +4426,10 @@ pointer_table::pointer_table ()
set (LE_EXPR, op_le);
set (GT_EXPR, op_gt);
set (GE_EXPR, op_ge);
- set (SSA_NAME, op_identity);
+ set (SSA_NAME, op_ssa);
set (INTEGER_CST, op_integer_cst);
set (ADDR_EXPR, op_addr);
- set (NOP_EXPR, op_convert);
+ set (NOP_EXPR, op_nop);
set (CONVERT_EXPR, op_convert);
set (BIT_NOT_EXPR, op_bitwise_not);
diff --git a/gcc/range-op.h b/gcc/range-op.h
index c724989..da85b5b 100644
--- a/gcc/range-op.h
+++ b/gcc/range-op.h
@@ -48,7 +48,9 @@ along with GCC; see the file COPYING3. If not see
class range_operator
{
+ friend class range_op_table;
public:
+ range_operator () : m_code (ERROR_MARK) { }
// Perform an operation between 2 ranges and return it.
virtual bool fold_range (irange &r, tree type,
const irange &lh,
@@ -106,6 +108,9 @@ protected:
const wide_int &lh_ub,
const wide_int &rh_lb,
const wide_int &rh_ub) const;
+
+ // Tree code of the range operator or ERROR_MARK if unknown.
+ tree_code m_code;
};
// Like range_operator above, but for floating point operators.
@@ -117,6 +122,14 @@ public:
const frange &lh,
const frange &rh,
relation_trio = TRIO_VARYING) const;
+ virtual void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
+ bool &maybe_nan,
+ tree type,
+ const REAL_VALUE_TYPE &lh_lb,
+ const REAL_VALUE_TYPE &lh_ub,
+ const REAL_VALUE_TYPE &rh_lb,
+ const REAL_VALUE_TYPE &rh_ub,
+ relation_kind) const;
// Unary operations have the range of the LHS as op2.
virtual bool fold_range (irange &r, tree type,
const frange &lh,
diff --git a/gcc/real.cc b/gcc/real.cc
index aae7c33..1c71858 100644
--- a/gcc/real.cc
+++ b/gcc/real.cc
@@ -111,6 +111,16 @@ static const REAL_VALUE_TYPE * real_digit (int);
static void times_pten (REAL_VALUE_TYPE *, int);
static void round_for_format (const struct real_format *, REAL_VALUE_TYPE *);
+
+/* Determine whether a floating-point value X is a denormal. R is
+ expected to be in denormal form, so this function is only
+ meaningful after a call to round_for_format. */
+
+static inline bool
+real_isdenormal (const REAL_VALUE_TYPE *r)
+{
+ return r->cl == rvc_normal && (r->sig[SIGSZ-1] & SIG_MSB) == 0;
+}
/* Initialize R with a positive zero. */
@@ -2962,7 +2972,6 @@ encode_ieee_single (const struct real_format *fmt, long *buf,
{
unsigned long image, sig, exp;
unsigned long sign = r->sign;
- bool denormal = real_isdenormal (r);
image = sign << 31;
sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 24)) & 0x7fffff;
@@ -3002,7 +3011,7 @@ encode_ieee_single (const struct real_format *fmt, long *buf,
/* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
whereas the intermediate representation is 0.F x 2**exp.
Which means we're off by one. */
- if (denormal)
+ if (real_isdenormal (r))
exp = 0;
else
exp = REAL_EXP (r) + 127 - 1;
@@ -3183,7 +3192,6 @@ encode_ieee_double (const struct real_format *fmt, long *buf,
{
unsigned long image_lo, image_hi, sig_lo, sig_hi, exp;
unsigned long sign = r->sign;
- bool denormal = real_isdenormal (r);
image_hi = sign << 31;
image_lo = 0;
@@ -3255,7 +3263,7 @@ encode_ieee_double (const struct real_format *fmt, long *buf,
/* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
whereas the intermediate representation is 0.F x 2**exp.
Which means we're off by one. */
- if (denormal)
+ if (real_isdenormal (r))
exp = 0;
else
exp = REAL_EXP (r) + 1023 - 1;
@@ -3441,7 +3449,6 @@ encode_ieee_extended (const struct real_format *fmt, long *buf,
const REAL_VALUE_TYPE *r)
{
unsigned long image_hi, sig_hi, sig_lo;
- bool denormal = real_isdenormal (r);
image_hi = r->sign << 15;
sig_hi = sig_lo = 0;
@@ -3523,7 +3530,7 @@ encode_ieee_extended (const struct real_format *fmt, long *buf,
this discrepancy has been taken care of by the difference
in fmt->emin in round_for_format. */
- if (denormal)
+ if (real_isdenormal (r))
exp = 0;
else
{
@@ -3972,7 +3979,6 @@ encode_ieee_quad (const struct real_format *fmt, long *buf,
{
unsigned long image3, image2, image1, image0, exp;
unsigned long sign = r->sign;
- bool denormal = real_isdenormal (r);
REAL_VALUE_TYPE u;
image3 = sign << 31;
@@ -4048,7 +4054,7 @@ encode_ieee_quad (const struct real_format *fmt, long *buf,
/* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
whereas the intermediate representation is 0.F x 2**exp.
Which means we're off by one. */
- if (denormal)
+ if (real_isdenormal (r))
exp = 0;
else
exp = REAL_EXP (r) + 16383 - 1;
@@ -4729,7 +4735,6 @@ encode_ieee_half (const struct real_format *fmt, long *buf,
{
unsigned long image, sig, exp;
unsigned long sign = r->sign;
- bool denormal = real_isdenormal (r);
image = sign << 15;
sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 11)) & 0x3ff;
@@ -4769,7 +4774,7 @@ encode_ieee_half (const struct real_format *fmt, long *buf,
/* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
whereas the intermediate representation is 0.F x 2**exp.
Which means we're off by one. */
- if (denormal)
+ if (real_isdenormal (r))
exp = 0;
else
exp = REAL_EXP (r) + 15 - 1;
@@ -4843,7 +4848,6 @@ encode_arm_bfloat_half (const struct real_format *fmt, long *buf,
{
unsigned long image, sig, exp;
unsigned long sign = r->sign;
- bool denormal = real_isdenormal (r);
image = sign << 15;
sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 8)) & 0x7f;
@@ -4880,7 +4884,7 @@ encode_arm_bfloat_half (const struct real_format *fmt, long *buf,
break;
case rvc_normal:
- if (denormal)
+ if (real_isdenormal (r))
exp = 0;
else
exp = REAL_EXP (r) + 127 - 1;
diff --git a/gcc/real.h b/gcc/real.h
index 306e959..b14bcdd 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -286,11 +286,12 @@ extern bool real_isnan (const REAL_VALUE_TYPE *);
/* Determine whether a floating-point value X is a signaling NaN. */
extern bool real_issignaling_nan (const REAL_VALUE_TYPE *);
-/* Determine whether a floating-point value X is a denormal. */
+/* Determine whether floating-point value R is a denormal. This
+ function is only valid for normalized values. */
inline bool
-real_isdenormal (const REAL_VALUE_TYPE *r)
+real_isdenormal (const REAL_VALUE_TYPE *r, machine_mode mode)
{
- return r->cl == rvc_normal && (r->sig[SIGSZ-1] & SIG_MSB) == 0;
+ return r->cl == rvc_normal && REAL_EXP (r) < REAL_MODE_FORMAT (mode)->emin;
}
/* Determine whether a floating-point value X is finite. */
diff --git a/gcc/reg-stack.cc b/gcc/reg-stack.cc
index 95e0e61..4046f17 100644
--- a/gcc/reg-stack.cc
+++ b/gcc/reg-stack.cc
@@ -263,14 +263,14 @@ static void swap_to_top (rtx_insn *, stack_ptr, rtx, rtx);
static bool move_for_stack_reg (rtx_insn *, stack_ptr, rtx);
static bool move_nan_for_stack_reg (rtx_insn *, stack_ptr, rtx);
static int swap_rtx_condition_1 (rtx);
-static int swap_rtx_condition (rtx_insn *);
+static int swap_rtx_condition (rtx_insn *, int &);
static void compare_for_stack_reg (rtx_insn *, stack_ptr, rtx, bool);
static bool subst_stack_regs_pat (rtx_insn *, stack_ptr, rtx);
static void subst_asm_stack_regs (rtx_insn *, stack_ptr);
static bool subst_stack_regs (rtx_insn *, stack_ptr);
static void change_stack (rtx_insn *, stack_ptr, stack_ptr, enum emit_where);
static void print_stack (FILE *, stack_ptr);
-static rtx_insn *next_flags_user (rtx_insn *);
+static rtx_insn *next_flags_user (rtx_insn *, int &);
/* Return nonzero if any stack register is mentioned somewhere within PAT. */
@@ -336,7 +336,7 @@ stack_regs_mentioned (const_rtx insn)
static rtx ix86_flags_rtx;
static rtx_insn *
-next_flags_user (rtx_insn *insn)
+next_flags_user (rtx_insn *insn, int &debug_seen)
{
/* Search forward looking for the first use of this value.
Stop at block boundaries. */
@@ -346,7 +346,14 @@ next_flags_user (rtx_insn *insn)
insn = NEXT_INSN (insn);
if (INSN_P (insn) && reg_mentioned_p (ix86_flags_rtx, PATTERN (insn)))
- return insn;
+ {
+ if (DEBUG_INSN_P (insn) && debug_seen >= 0)
+ {
+ debug_seen = 1;
+ continue;
+ }
+ return insn;
+ }
if (CALL_P (insn))
return NULL;
@@ -1248,8 +1255,22 @@ swap_rtx_condition_1 (rtx pat)
return r;
}
+/* This function swaps condition in cc users and returns true
+ if successful. It is invoked in 2 different modes, one with
+ DEBUG_SEEN set initially to 0. In this mode, next_flags_user
+ will skip DEBUG_INSNs that it would otherwise return and just
+ sets DEBUG_SEEN to 1 in that case. If DEBUG_SEEN is 0 at
+ the end of toplevel swap_rtx_condition which returns true,
+ it means no problematic DEBUG_INSNs were seen and all changes
+ have been applied. If it returns true but DEBUG_SEEN is 1,
+ it means some problematic DEBUG_INSNs were seen and no changes
+ have been applied so far. In that case one needs to call
+ swap_rtx_condition again with DEBUG_SEEN set to -1, in which
+ case it doesn't skip DEBUG_INSNs, but instead adjusts the
+ flags related condition in them or resets them as needed. */
+
static int
-swap_rtx_condition (rtx_insn *insn)
+swap_rtx_condition (rtx_insn *insn, int &debug_seen)
{
rtx pat = PATTERN (insn);
@@ -1259,7 +1280,7 @@ swap_rtx_condition (rtx_insn *insn)
&& REG_P (SET_DEST (pat))
&& REGNO (SET_DEST (pat)) == FLAGS_REG)
{
- insn = next_flags_user (insn);
+ insn = next_flags_user (insn, debug_seen);
if (insn == NULL_RTX)
return 0;
pat = PATTERN (insn);
@@ -1281,7 +1302,18 @@ swap_rtx_condition (rtx_insn *insn)
{
insn = NEXT_INSN (insn);
if (INSN_P (insn) && reg_mentioned_p (dest, insn))
- break;
+ {
+ if (DEBUG_INSN_P (insn))
+ {
+ if (debug_seen >= 0)
+ debug_seen = 1;
+ else
+ /* Reset the DEBUG insn otherwise. */
+ INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
+ continue;
+ }
+ break;
+ }
if (CALL_P (insn))
return 0;
}
@@ -1301,7 +1333,7 @@ swap_rtx_condition (rtx_insn *insn)
return 0;
/* Now we are prepared to handle this. */
- insn = next_flags_user (insn);
+ insn = next_flags_user (insn, debug_seen);
if (insn == NULL_RTX)
return 0;
pat = PATTERN (insn);
@@ -1310,23 +1342,25 @@ swap_rtx_condition (rtx_insn *insn)
if (swap_rtx_condition_1 (pat))
{
int fail = 0;
- INSN_CODE (insn) = -1;
- if (recog_memoized (insn) == -1)
- fail = 1;
- /* In case the flags don't die here, recurse to try fix
- following user too. */
- else if (! dead_or_set_p (insn, ix86_flags_rtx))
+ if (DEBUG_INSN_P (insn))
+ gcc_assert (debug_seen < 0);
+ else
{
- insn = next_flags_user (insn);
- if (!insn || !swap_rtx_condition (insn))
+ INSN_CODE (insn) = -1;
+ if (recog_memoized (insn) == -1)
fail = 1;
}
- if (fail)
+ /* In case the flags don't die here, recurse to try fix
+ following user too. */
+ if (!fail && !dead_or_set_p (insn, ix86_flags_rtx))
{
- swap_rtx_condition_1 (pat);
- return 0;
+ insn = next_flags_user (insn, debug_seen);
+ if (!insn || !swap_rtx_condition (insn, debug_seen))
+ fail = 1;
}
- return 1;
+ if (fail || debug_seen == 1)
+ swap_rtx_condition_1 (pat);
+ return !fail;
}
return 0;
}
@@ -1345,6 +1379,7 @@ compare_for_stack_reg (rtx_insn *insn, stack_ptr regstack,
{
rtx *src1, *src2;
rtx src1_note, src2_note;
+ int debug_seen = 0;
src1 = get_true_reg (&XEXP (pat_src, 0));
src2 = get_true_reg (&XEXP (pat_src, 1));
@@ -1354,8 +1389,17 @@ compare_for_stack_reg (rtx_insn *insn, stack_ptr regstack,
if ((! STACK_REG_P (*src1)
|| (STACK_REG_P (*src2)
&& get_hard_regnum (regstack, *src2) == FIRST_STACK_REG))
- && swap_rtx_condition (insn))
+ && swap_rtx_condition (insn, debug_seen))
{
+ /* If swap_rtx_condition succeeded but some debug insns
+ were seen along the way, it has actually reverted all the
+ changes. Rerun swap_rtx_condition in a mode where DEBUG_ISNSs
+ will be adjusted as well. */
+ if (debug_seen)
+ {
+ debug_seen = -1;
+ swap_rtx_condition (insn, debug_seen);
+ }
std::swap (XEXP (pat_src, 0), XEXP (pat_src, 1));
src1 = get_true_reg (&XEXP (pat_src, 0));
diff --git a/gcc/rust/ChangeLog b/gcc/rust/ChangeLog
new file mode 100644
index 0000000..3a4f03c
--- /dev/null
+++ b/gcc/rust/ChangeLog
@@ -0,0 +1,6 @@
+
+Copyright (C) 2022 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index fb6ff0f..4272ed7 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -3625,7 +3625,7 @@ fold_offsetof (tree expr, tree type, enum tree_code ctx)
definition thereof. */
if (TREE_CODE (v) == ARRAY_REF
|| TREE_CODE (v) == COMPONENT_REF)
- warning (OPT_Warray_bounds,
+ warning (OPT_Warray_bounds_,
"index %E denotes an offset "
"greater than size of %qT",
t, TREE_TYPE (TREE_OPERAND (expr, 0)));
diff --git a/gcc/sanopt.cc b/gcc/sanopt.cc
index e9d188d..6ee51e9 100644
--- a/gcc/sanopt.cc
+++ b/gcc/sanopt.cc
@@ -80,16 +80,16 @@ struct sanopt_info
/* If T has a single definition of form T = T2, return T2. */
-static tree
+static gimple *
maybe_get_single_definition (tree t)
{
if (TREE_CODE (t) == SSA_NAME)
{
gimple *g = SSA_NAME_DEF_STMT (t);
if (gimple_assign_single_p (g))
- return gimple_assign_rhs1 (g);
+ return g;
}
- return NULL_TREE;
+ return NULL;
}
/* Tree triplet for vptr_check_map. */
@@ -618,11 +618,31 @@ maybe_optimize_ubsan_vptr_ifn (class sanopt_ctx *ctx, gimple *stmt)
return true;
}
+/* Checks whether value of T in CHECK and USE is the same. */
+
+static bool
+same_value_p (gimple *check, gimple *use, tree t)
+{
+ tree check_vuse = gimple_vuse (check);
+ tree use_vuse = gimple_vuse (use);
+
+ if (TREE_CODE (t) == SSA_NAME
+ || is_gimple_min_invariant (t)
+ || ! use_vuse)
+ return true;
+
+ if (check_vuse == use_vuse)
+ return true;
+
+ return false;
+}
+
/* Returns TRUE if ASan check of length LEN in block BB can be removed
if preceded by checks in V. */
static bool
-can_remove_asan_check (auto_vec<gimple *> &v, tree len, basic_block bb)
+can_remove_asan_check (auto_vec<gimple *> &v, tree len, basic_block bb,
+ gimple *base_stmt, tree base_addr)
{
unsigned int i;
gimple *g;
@@ -674,8 +694,10 @@ can_remove_asan_check (auto_vec<gimple *> &v, tree len, basic_block bb)
last_bb = imm;
}
- if (last_bb == gbb)
- remove = true;
+ if (last_bb != gbb)
+ break;
+ // In case of base_addr residing in memory we also need to check aliasing
+ remove = ! base_addr || same_value_p (g, base_stmt, base_addr);
break;
}
@@ -718,7 +740,8 @@ maybe_optimize_asan_check_ifn (class sanopt_ctx *ctx, gimple *stmt)
auto_vec<gimple *> *ptr_checks = &ctx->asan_check_map.get_or_insert (ptr);
- tree base_addr = maybe_get_single_definition (ptr);
+ gimple *base_stmt = maybe_get_single_definition (ptr);
+ tree base_addr = base_stmt ? gimple_assign_rhs1 (base_stmt) : NULL_TREE;
auto_vec<gimple *> *base_checks = NULL;
if (base_addr)
{
@@ -747,11 +770,12 @@ maybe_optimize_asan_check_ifn (class sanopt_ctx *ctx, gimple *stmt)
bool remove = false;
if (ptr_checks)
- remove = can_remove_asan_check (*ptr_checks, len, bb);
+ remove = can_remove_asan_check (*ptr_checks, len, bb, NULL, NULL);
if (!remove && base_checks)
/* Try with base address as well. */
- remove = can_remove_asan_check (*base_checks, len, bb);
+ remove = can_remove_asan_check (*base_checks, len, bb, base_stmt,
+ base_addr);
if (!remove)
{
diff --git a/gcc/system.h b/gcc/system.h
index c192b6c..4f9256e 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -747,6 +747,10 @@ extern int vsnprintf (char *, size_t, const char *, va_list);
# include <memory>
#endif
+#ifdef INCLUDE_MUTEX
+# include <mutex>
+#endif
+
#ifdef INCLUDE_MALLOC_H
#if defined(HAVE_MALLINFO) || defined(HAVE_MALLINFO2)
#include <malloc.h>
@@ -1075,7 +1079,7 @@ extern void fancy_abort (const char *, int, const char *)
EH_FRAME_IN_DATA_SECTION TARGET_FLT_EVAL_METHOD_NON_DEFAULT \
JCR_SECTION_NAME TARGET_USE_JCR_SECTION SDB_DEBUGGING_INFO \
SDB_DEBUG NO_IMPLICIT_EXTERN_C NOTICE_UPDATE_CC \
- CC_STATUS_MDEP_INIT CC_STATUS_MDEP CC_STATUS
+ CC_STATUS_MDEP_INIT CC_STATUS_MDEP CC_STATUS SLOW_SHORT_ACCESS
/* Hooks that are no longer used. */
#pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \
diff --git a/gcc/target-def.h b/gcc/target-def.h
index f81f8fe..5e5cc3b 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -62,6 +62,8 @@
# else
# ifdef TARGET_ASM_NAMED_SECTION
# define TARGET_ASM_CONSTRUCTOR default_named_section_asm_out_constructor
+# else
+# define TARGET_ASM_CONSTRUCTOR default_asm_out_constructor
# endif
# endif
#endif
@@ -72,6 +74,8 @@
# else
# ifdef TARGET_ASM_NAMED_SECTION
# define TARGET_ASM_DESTRUCTOR default_named_section_asm_out_destructor
+# else
+# define TARGET_ASM_DESTRUCTOR default_asm_out_destructor
# endif
# endif
#endif
diff --git a/gcc/target.def b/gcc/target.def
index 25f94c1..082a7c6 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1634,7 +1634,7 @@ fields in @var{simd_clone} structure pointed by @var{clone_info} argument and al
not determined by the bitsize (in which case @var{simdlen} is always used).\n\
The hook should return 0 if SIMD clones shouldn't be emitted,\n\
or number of @var{vecsize_mangle} variants that should be emitted.",
-int, (struct cgraph_node *, struct cgraph_simd_clone *, tree, int), NULL)
+int, (struct cgraph_node *, struct cgraph_simd_clone *, tree, int, bool), NULL)
DEFHOOK
(adjust,
@@ -1905,6 +1905,25 @@ implementation approaches itself.",
const vec_perm_indices &sel),
NULL)
+DEFHOOK
+(can_special_div_by_const,
+ "This hook is used to test whether the target has a special method of\n\
+division of vectors of type @var{vectype} using the value @var{constant},\n\
+and producing a vector of type @var{vectype}. The division\n\
+will then not be decomposed by the vectorizer and kept as a div.\n\
+\n\
+When the hook is being used to test whether the target supports a special\n\
+divide, @var{in0}, @var{in1}, and @var{output} are all null. When the hook\n\
+is being used to emit a division, @var{in0} and @var{in1} are the source\n\
+vectors of type @var{vecttype} and @var{output} is the destination vector of\n\
+type @var{vectype}.\n\
+\n\
+Return true if the operation is possible, emitting instructions for it\n\
+if rtxes are provided and updating @var{output}.",
+ bool, (enum tree_code, tree vectype, wide_int constant, rtx *output,
+ rtx in0, rtx in1),
+ default_can_special_div_by_const)
+
/* Return true if the target supports misaligned store/load of a
specific factor denoted in the third parameter. The last parameter
is true if the access is defined in a packed struct. */
diff --git a/gcc/target.h b/gcc/target.h
index d6fa693..c836036 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -51,6 +51,7 @@
#include "insn-codes.h"
#include "tm.h"
#include "hard-reg-set.h"
+#include "tree-core.h"
#if CHECKING_P
diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
index d17d393..d9e61552 100644
--- a/gcc/targhooks.cc
+++ b/gcc/targhooks.cc
@@ -1405,6 +1405,26 @@ default_generate_pic_addr_diff_vec (void)
return flag_pic;
}
+/* Record an element in the table of global constructors. SYMBOL is
+ a SYMBOL_REF of the function to be called; PRIORITY is a number
+ between 0 and MAX_INIT_PRIORITY. */
+
+void
+default_asm_out_constructor (rtx symbol ATTRIBUTE_UNUSED,
+ int priority ATTRIBUTE_UNUSED)
+{
+ sorry ("global constructors not supported on this target");
+}
+
+/* Likewise for global destructors. */
+
+void
+default_asm_out_destructor (rtx symbol ATTRIBUTE_UNUSED,
+ int priority ATTRIBUTE_UNUSED)
+{
+ sorry ("global destructors not supported on this target");
+}
+
/* By default, do no modification. */
tree default_mangle_decl_assembler_name (tree decl ATTRIBUTE_UNUSED,
tree id)
@@ -1820,6 +1840,14 @@ default_have_conditional_execution (void)
return HAVE_conditional_execution;
}
+/* Default that no division by constant operations are special. */
+bool
+default_can_special_div_by_const (enum tree_code, tree, wide_int, rtx *, rtx,
+ rtx)
+{
+ return false;
+}
+
/* By default we assume that c99 functions are present at the runtime,
but sincos is not. */
bool
@@ -1992,15 +2020,17 @@ default_compare_by_pieces_branch_ratio (machine_mode)
return 1;
}
-/* Helper for default_print_patchable_function_entry and other
- print_patchable_function_entry hook implementations. */
+/* Write PATCH_AREA_SIZE NOPs into the asm outfile FILE around a function
+ entry. If RECORD_P is true and the target supports named sections,
+ the location of the NOPs will be recorded in a special object section
+ called "__patchable_function_entries". This routine may be called
+ twice per function to put NOPs before and after the function
+ entry. */
void
-default_print_patchable_function_entry_1 (FILE *file,
- unsigned HOST_WIDE_INT
- patch_area_size,
- bool record_p,
- unsigned int flags)
+default_print_patchable_function_entry (FILE *file,
+ unsigned HOST_WIDE_INT patch_area_size,
+ bool record_p)
{
const char *nop_templ = 0;
int code_num;
@@ -2014,13 +2044,17 @@ default_print_patchable_function_entry_1 (FILE *file,
if (record_p && targetm_common.have_named_sections)
{
char buf[256];
- static int patch_area_number;
section *previous_section = in_section;
const char *asm_op = integer_asm_op (POINTER_SIZE_UNITS, false);
gcc_assert (asm_op != NULL);
- patch_area_number++;
- ASM_GENERATE_INTERNAL_LABEL (buf, "LPFE", patch_area_number);
+ /* If SECTION_LINK_ORDER is supported, this internal label will
+ be filled as the symbol for linked_to section. */
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LPFE", current_function_funcdef_no);
+
+ unsigned int flags = SECTION_WRITE | SECTION_RELRO;
+ if (HAVE_GAS_SECTION_LINK_ORDER)
+ flags |= SECTION_LINK_ORDER;
section *sect = get_section ("__patchable_function_entries",
flags, current_function_decl);
@@ -2042,25 +2076,6 @@ default_print_patchable_function_entry_1 (FILE *file,
output_asm_insn (nop_templ, NULL);
}
-/* Write PATCH_AREA_SIZE NOPs into the asm outfile FILE around a function
- entry. If RECORD_P is true and the target supports named sections,
- the location of the NOPs will be recorded in a special object section
- called "__patchable_function_entries". This routine may be called
- twice per function to put NOPs before and after the function
- entry. */
-
-void
-default_print_patchable_function_entry (FILE *file,
- unsigned HOST_WIDE_INT patch_area_size,
- bool record_p)
-{
- unsigned int flags = SECTION_WRITE | SECTION_RELRO;
- if (HAVE_GAS_SECTION_LINK_ORDER)
- flags |= SECTION_LINK_ORDER;
- default_print_patchable_function_entry_1 (file, patch_area_size, record_p,
- flags);
-}
-
bool
default_profile_before_prologue (void)
{
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index ecce55e..3ca25ab 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -178,6 +178,8 @@ extern void default_target_option_override (void);
extern void hook_void_bitmap (bitmap);
extern int default_reloc_rw_mask (void);
extern bool default_generate_pic_addr_diff_vec (void);
+extern void default_asm_out_constructor (rtx, int);
+extern void default_asm_out_destructor (rtx, int);
extern tree default_mangle_decl_assembler_name (tree, tree);
extern tree default_emutls_var_fields (tree, tree *);
extern tree default_emutls_var_init (tree, tree, tree);
@@ -207,6 +209,8 @@ extern void default_addr_space_diagnose_usage (addr_space_t, location_t);
extern rtx default_addr_space_convert (rtx, tree, tree);
extern unsigned int default_case_values_threshold (void);
extern bool default_have_conditional_execution (void);
+extern bool default_can_special_div_by_const (enum tree_code, tree, wide_int,
+ rtx *, rtx, rtx);
extern bool default_libc_has_function (enum function_class, tree);
extern bool default_libc_has_fast_function (int fcode);
@@ -229,9 +233,6 @@ extern bool default_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
bool);
extern int default_compare_by_pieces_branch_ratio (machine_mode);
-extern void default_print_patchable_function_entry_1 (FILE *,
- unsigned HOST_WIDE_INT,
- bool, unsigned int);
extern void default_print_patchable_function_entry (FILE *,
unsigned HOST_WIDE_INT,
bool);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9dee429..643d903 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,4158 @@
+2022-12-12 Jason Merrill <jason@redhat.com>
+
+ Revert:
+ 2022-12-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/105838
+ * g++.dg/tree-ssa/initlist-opt2.C: New test.
+
+2022-12-12 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/102180
+ * gfortran.dg/pr102180.f90: New test.
+
+2022-12-12 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/108055
+ * gdc.dg/torture/imports/pr108055conv.d: New.
+ * gdc.dg/torture/imports/pr108055spec.d: New.
+ * gdc.dg/torture/imports/pr108055write.d: New.
+ * gdc.dg/torture/pr108055.d: New test.
+
+2022-12-12 Wilco Dijkstra <wilco.dijkstra@arm.com>
+
+ * gcc.target/aarch64/movk_3.c: New test.
+
+2022-12-12 Tamar Christina <tamar.christina@arm.com>
+
+ * gcc.target/aarch64/if-compare_1.c: New test.
+ * gcc.target/aarch64/if-compare_2.c: New test.
+
+2022-12-12 Tamar Christina <tamar.christina@arm.com>
+
+ * gcc.target/aarch64/tbz_1.c: New test.
+
+2022-12-12 Tamar Christina <tamar.christina@arm.com>
+
+ * gcc.target/aarch64/sve/slp_1.c: Update testcase.
+
+2022-12-12 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/aarch64/acle/bti_def.c: New test.
+ * gcc.target/aarch64/acle/pauth_def.c: New test.
+
+2022-12-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/89317
+ * gcc.dg/tree-ssa/pr89317.c: Amend.
+
+2022-12-11 Steve Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/107995
+ * gfortran.dg/pr107995.f90: New test.
+
+2022-12-11 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/108050
+ * gdc.dg/imports/pr108050/mod1.d: New.
+ * gdc.dg/imports/pr108050/mod2.d: New.
+ * gdc.dg/imports/pr108050/package.d: New.
+ * gdc.dg/pr108050.d: New test.
+
+2022-12-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/89317
+ * gcc.dg/tree-ssa/pr89317.c: New testcase.
+
+2022-12-11 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/forwprop-3.c: Adjust.
+ * g++.dg/tree-ssa/pr31146-2.C: Likewise.
+
+2022-12-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/106904
+ * gcc.dg/Wstringop-overflow-pr106904.c: New testcase.
+
+2022-12-10 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/106911
+ * gfortran.dg/pr106911.f90: New test.
+
+2022-12-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107997
+ * gcc.c-torture/compile/pr107997.c: New test.
+
+2022-12-09 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/107872
+ * gfortran.dg/pr107872.f90: New test.
+
+2022-12-09 Martin Liska <mliska@suse.cz>
+
+ * gcc.target/i386/builtin_target.c: Add more checks.
+
+2022-12-09 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/108003
+ * g++.dg/analyzer/pr108003.C: New test.
+
+2022-12-09 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/analyzer/memcpy-1.c (test_8a, test_8b): New tests.
+ * gcc.dg/analyzer/memmove-1.c: New test, based on memcpy-1.c
+ * gcc.dg/analyzer/out-of-bounds-1.c (test7): Update expected
+ result for uninit srcBuf.
+ * gcc.dg/analyzer/out-of-bounds-5.c (test8, test9): Add
+ dg-warnings for memcpy from uninit src vla.
+ * gcc.dg/analyzer/pr104308.c (test_memmove_within_uninit):
+ Expect creation point note to be missing on riscv*-*-*.
+
+2022-12-08 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/108025
+ * gfortran.dg/contiguous_12.f90: New test.
+
+2022-12-08 Eugene Rozenfeld <erozen@microsoft.com>
+
+ * gcc.dg/tree-prof/pr108000.c: Regression test
+
+2022-12-08 David Faust <david.faust@oracle.com>
+
+ * gcc.target/bpf/bswap-1.c: New test.
+
+2022-12-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/105838
+ * g++.dg/tree-ssa/initlist-opt2.C: New test.
+
+2022-12-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/105838
+ * g++.dg/tree-ssa/initlist-opt1.C: New test.
+
+2022-12-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/105838
+ * g++.dg/tree-ssa/allocator-opt1.C: New test.
+
+2022-12-08 Sebastian Pop <spop@amazon.com>
+
+ PR target/98776
+ * gcc.target/aarch64/pr98776.c: New.
+ * gcc.target/aarch64/pr92424-2.c: Adjust pattern.
+ * gcc.target/aarch64/pr92424-3.c: Adjust pattern.
+
+2022-12-08 Siddhesh Poyarekar <siddhesh@gotplt.org>
+
+ * gcc.dg/builtin-dynamic-object-size-0.c (test_strdup,
+ test_strndup, test_strdup_min, test_strndup_min): Free RES
+ before returning from function.
+
+2022-12-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/106719
+ * gcc.dg/pr106719.c: New test.
+
+2022-12-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/107627
+ * gcc.target/i386/pr107627-3.c: New test.
+ * gcc.target/i386/pr107627-4.c: New test.
+
+2022-12-08 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/107985
+ * g++.dg/pr107985.C: New.
+
+2022-12-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107699
+ * gcc.dg/tree-ssa/pr107699.c: New testcase.
+
+2022-12-08 Alexandre Oliva <oliva@adacore.com>
+
+ PR tree-optimization/102706
+ * gcc.dg/Warray-bounds-48.c: Disable -Wstringop-overflow.
+ * gcc.dg/Wzero-length-array-bounds-2.c: Likewise.
+
+2022-12-08 Alexandre Oliva <oliva@adacore.com>
+
+ * gcc.dg/torture/fp-uint64-convert-double-1.c: Expect fail on
+ arm-*-eabi*.
+ * gcc.dg/torture/fp-uint64-convert-double-2.c: Likewise.
+
+2022-12-08 Alexandre Oliva <oliva@adacore.com>
+
+ * c-c++-common/auto-init-1.c: Add -fno-short-enums.
+ * c-c++-common/auto-init-2.c: Likewise.
+ * gcc.dg/debug/btf/btf-enum-1.c: Likewise.
+
+2022-12-08 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vabavq_p_s16.c: Extern functions
+ as "C".
+ * gcc.target/arm/mve/intrinsics/vabavq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_p_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_p_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_x_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_x_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddlvaq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddlvaq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddlvaq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddlvaq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddlvq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddlvq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddlvq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddlvq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_p_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_p_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_p_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_p_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_p_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_p_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_s64.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_u64.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_m_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_m_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_m_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_x_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_x_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_x_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_x_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vfmasq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vfmasq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_m_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_m_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_m_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_x_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_x_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_x_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_x_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_x_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxaq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxaq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxaq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxaq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxaq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxaq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxavq_p_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxavq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxavq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxavq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxavq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxavq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmaq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmaq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmavq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmavq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmq_x_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmq_x_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmvq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmvq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_x_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_p_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_p_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_p_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminaq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminaq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminaq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminaq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminaq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminaq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminavq_p_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminavq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminavq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminavq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminavq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminavq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmaq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmaq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmaq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmaq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmavq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmavq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmavq_p_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmavq_p_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmq_x_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmq_x_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmvq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmvq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmvq_p_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmvq_p_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_x_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_p_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_p_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_p_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_p_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_p_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_p_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlaldavaxq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlaldavaxq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqsubq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrmlaldavhaq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrmlaldavhaq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_x_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_u8.c: Likewise.
+
+2022-12-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107967
+ * gcc.dg/pr107967-1.c: New test.
+ * gcc.dg/pr107967-2.c: New test.
+ * gcc.dg/pr107967-3.c: New test.
+
+2022-12-07 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/108010
+ * gfortran.dg/pr108010.f90: New test.
+
+2022-12-07 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/c2x-constexpr-1.c: Do not use auto, constexpr and a type
+ together.
+ * gcc.dg/c2x-constexpr-3.c: Add tests of auto, constexpr and type
+ used together.
+
+2022-12-07 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/c90-auto-1.c: New test.
+
+2022-12-07 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/cpp/c11-vararg-1.c, gcc.dg/cpp/c2x-va-opt-1.c: New tests.
+
+2022-12-07 Richard Biener <rguenther@suse.de>
+
+ PR ipa/105676
+ * gcc.dg/pr105676.c: New testcase.
+
+2022-12-07 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ PR target/107920
+ * gcc.target/aarch64/sve/acle/general/pr107920.c: New test.
+ * g++.target/aarch64/sve/pr107920.C: Likewise.
+
+2022-12-07 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr107970.c: New test.
+
+2022-12-07 Antoni Boucher <bouanto@zoho.com>
+ Guillaume Gomez <guillaume1.gomez@gmail.com>
+
+ PR jit/107770
+ * jit.dg/harness.h: Add new macro to to perform vector
+ comparisons
+ * jit.dg/test-expressions.c: Extend comparison tests to add float
+ types and vectors
+
+2022-12-06 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107882
+ * gcc.dg/analyzer/memcpy-pr107882.c: New test.
+
+2022-12-06 Qing Zhao <qing.zhao@oracle.com>
+
+ * gcc.dg/Warray-bounds-11.c: Update warnings for -Warray-bounds=2.
+ * gcc.dg/Warray-bounds-flex-arrays-1.c: New test.
+ * gcc.dg/Warray-bounds-flex-arrays-2.c: New test.
+ * gcc.dg/Warray-bounds-flex-arrays-3.c: New test.
+ * gcc.dg/Warray-bounds-flex-arrays-4.c: New test.
+ * gcc.dg/Warray-bounds-flex-arrays-5.c: New test.
+ * gcc.dg/Warray-bounds-flex-arrays-6.c: New test.
+
+2022-12-06 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106325
+ * gcc.dg/analyzer/attr-nonnull-pr106325.c: New test.
+ * gcc.dg/analyzer/attribute-nonnull.c (test_6): New.
+ (test_7): New.
+
+2022-12-06 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/plugin/analyzer_kernel_plugin.c: Include
+ "analyzer/call-details.h".
+ * gcc.dg/plugin/analyzer_known_fns_plugin.c: Likewise.
+
+2022-12-06 Marcel Vollweiler <marcel@codesourcery.com>
+
+ * c-c++-common/gomp/target-teams-1.c: Adapt expected values for
+ num_teams from "1" to "-2" in cases without num_teams clause.
+ * g++.dg/gomp/target-teams-1.C: Likewise.
+ * gfortran.dg/gomp/defaultmap-4.f90: Likewise.
+ * gfortran.dg/gomp/defaultmap-5.f90: Likewise.
+ * gfortran.dg/gomp/defaultmap-6.f90: Likewise.
+
+2022-12-06 Andre Vieira <andre.simoesdiasvieira@arm.com>
+
+ * gcc.target/arm/mve/pr107987.c: New test.
+
+2022-12-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/107969
+ * gcc.target/i386/pr107969.c: New test.
+
+2022-12-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR testsuite/107046
+ * gcc.c-torture/execute/ieee/ieee.exp: For rx-*-* append
+ -mnofpu.
+
+2022-12-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107975
+ * gcc.dg/pr107975.c: New test.
+
+2022-12-06 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/104165
+ * g++.dg/warn/Warray-bounds-pr104165-1.C: New testcase.
+
+2022-12-06 Iain Sandoe <iain@sandoe.co.uk>
+
+ * gcc.target/x86_64/abi/bf16/abi-bf16.exp: Use separate asm for Darwin.
+ * gcc.target/x86_64/abi/bf16/m256bf16/abi-bf16-ymm.exp: Likewise.
+ * gcc.target/x86_64/abi/bf16/m512bf16/abi-bf16-zmm.exp: Likewise.
+ * gcc.target/x86_64/abi/bf16/args.h: Make xmm_regs, x87_regs extern.
+ * gcc.target/x86_64/abi/bf16/m256bf16/args.h: Likewise.
+ * gcc.target/x86_64/abi/bf16/m512bf16/args.h: Likewise.
+ * gcc.target/x86_64/abi/bf16/asm-support-darwin.S: New file.
+ * gcc.target/x86_64/abi/bf16/m256bf16/asm-support-darwin.S: New file.
+ * gcc.target/x86_64/abi/bf16/m512bf16/asm-support-darwin.S: New file.
+
+2022-12-06 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ * gcc.target/aarch64/interleave-init-1.c: New test.
+
+2022-12-05 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/40635
+ * gcc.dg/uninit-pr40635.c: New testcase.
+
+2022-12-05 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/106868
+ * gcc.dg/Wdangling-pointer-pr106868.c: New testcase.
+
+2022-12-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/106805
+ * c-c++-common/pr57371-4.c: Revert 2021-09-19 changes.
+ * c-c++-common/pr57371-5.c: New test.
+ * gcc.c-torture/execute/ieee/fp-cmp-6.x: Add -fno-trapping-math.
+ * gcc.c-torture/execute/ieee/fp-cmp-9.c: New test.
+ * gcc.c-torture/execute/ieee/fp-cmp-9.x: New file.
+
+2022-12-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107879
+ * gcc.c-torture/execute/pr107879.c: New file.
+
+2022-12-05 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107833
+ PR tree-optimization/107839
+ * gcc.dg/torture/pr107833.c: New testcase.
+ * gcc.dg/uninit-pr107839.c: Likewise.
+
+2022-12-04 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107922
+ * gfortran.dg/unpack_field_1.f90: New test.
+
+2022-12-04 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107899
+ * gfortran.dg/pr107899.f90: New test.
+
+2022-12-04 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/107417
+ * g++.dg/cpp2a/concepts-requires33.C: New test.
+
+2022-12-04 Iain Sandoe <iain@sandoe.co.uk>
+ Adrian Perl <adrian.perl@web.de>
+
+ PR c++/100611
+ PR c++/101367
+ PR c++/101976
+ PR c++/99576
+ * g++.dg/coroutines/pr100611.C: New test.
+ * g++.dg/coroutines/pr101367.C: New test.
+ * g++.dg/coroutines/pr101976.C: New test.
+ * g++.dg/coroutines/pr99576_1.C: New test.
+ * g++.dg/coroutines/pr99576_2.C: New test.
+
+2022-12-03 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/103081
+ * g++.dg/cpp2a/using-enum-10.C: New test.
+ * g++.dg/cpp2a/using-enum-10a.C: New test.
+
+2022-12-03 Alexandre Oliva <oliva@adacore.com>
+
+ * gcc.dg/tree-ssa/ssa-sink-18.c: xfail sink2 on riscv64.
+
+2022-12-03 Alexandre Oliva <oliva@adacore.com>
+
+ * gcc.dg/uninit-pred-9_b.c: Add riscv*-*-* to the xfail list
+ for the bogus warning.
+
+2022-12-02 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107874
+ * gfortran.dg/merge_1.f90: Avoid recursive I/O.
+
+2022-12-02 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107851
+ * gcc.dg/analyzer/allocation-size-4.c: Update expected wording.
+ * gcc.dg/analyzer/allocation-size-multiline-1.c: New test.
+ * gcc.dg/analyzer/allocation-size-multiline-2.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-multiline-1.c: Update expected
+ wording.
+ * gcc.dg/analyzer/out-of-bounds-multiline-2.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-read-char-arr.c: Update expected
+ wording.
+ * gcc.dg/analyzer/out-of-bounds-read-int-arr.c: Likewise.
+ * gcc.dg/analyzer/out-of-bounds-write-char-arr.c: Likewise.
+ * gcc.dg/analyzer/out-of-bounds-write-int-arr.c: Likewise.
+
+2022-12-02 Marek Polacek <polacek@redhat.com>
+
+ * g++.dg/cpp0x/constexpr-ex1.C: Adjust dg-error.
+ * g++.dg/cpp23/constexpr-nonlit10.C: Adjust dg-warning.
+ * g++.dg/cpp23/constexpr-nonlit11.C: Likewise.
+ * g++.dg/cpp2a/spaceship-eq3.C: Add dg-error.
+
+2022-12-02 Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
+ Jason Merrill <jason@redhat.com>
+
+ * g++.dg/diagnostic/return-type-loc1.C: New test.
+
+2022-12-02 Vladimir N. Makarov <vmakarov@redhat.com>
+
+ * gcc.target/mips/pr106462.c: New test.
+
+2022-12-02 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/cbranchbf4.c: New test.
+
+2022-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/106577
+ * gcc.target/i386/pr106577.c: New test.
+
+2022-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/84469
+ * g++.dg/gomp/for-21.C (f3, f6, f9): Adjust expected diagnostics.
+ * g++.dg/gomp/for-22.C: New test.
+
+2022-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/84469
+ * g++.dg/cpp1z/decomp56.C: New test.
+ * g++.dg/gomp/pr84469.C: New test.
+
+2022-12-02 Michael Collison <collison@rivosinc.com>
+
+ * gcc.dg/tree-ssa/branchless-cond.c: New test.
+
+2022-12-02 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107948
+ * gcc.dg/analyzer/feasibility-pr107948.c: New test.
+
+2022-12-02 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/analyzer/string-ops-concat-pair.c: New test.
+ * gcc.dg/analyzer/string-ops-dup.c: New test.
+
+2022-12-02 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr107934.c: New test.
+
+2022-12-02 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/107539
+ * g++.dg/template/canon-type-19.C: New test.
+
+2022-12-01 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+
+ * gcc.target/riscv/rvv/base/dup-1.c: New test.
+ * gcc.target/riscv/rvv/base/dup-2.c: New test.
+
+2022-12-01 Christophe Lyon <christophe.lyon@arm.com>
+
+ * gcc.target/arm/simd/mve-compare-1.c: Update.
+ * gcc.target/arm/simd/mve-compare-scalar-1.c: Update.
+ * gcc.target/arm/simd/mve-vabs.c: Update.
+ * gcc.target/arm/simd/mve-vadd-1.c: Update.
+ * gcc.target/arm/simd/mve-vadd-scalar-1.c: Update.
+ * gcc.target/arm/simd/mve-vcmp.c: Update.
+ * gcc.target/arm/simd/pr101325.c: Update.
+
+2022-12-01 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107937
+ * gcc.dg/pr107937.c: New testcase.
+
+2022-12-01 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107935
+ * gcc.dg/torture/pr107935.c: New testcase.
+
+2022-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/107627
+ * gcc.target/i386/pr107627-1.c: New test.
+ * gcc.target/i386/pr107627-2.c: New test.
+
+2022-12-01 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr107863.c: New test.
+
+2022-12-01 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106626
+ * gcc.dg/analyzer/out-of-bounds-multiline-1.c: New test.
+
+2022-12-01 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106626
+ * gcc.dg/analyzer/call-summaries-2.c: Update expected results.
+ * gcc.dg/analyzer/out-of-bounds-1.c: Likewise.
+ * gcc.dg/analyzer/out-of-bounds-2.c: Likewise.
+ * gcc.dg/analyzer/out-of-bounds-3.c: Likewise.
+ * gcc.dg/analyzer/out-of-bounds-4.c: Likewise.
+ * gcc.dg/analyzer/out-of-bounds-5.c: Likewise.
+ * gcc.dg/analyzer/out-of-bounds-container_of.c: Likewise.
+ * gcc.dg/analyzer/out-of-bounds-read-char-arr.c: Likewise. Rename
+ functions from "int_arr_" to "char_arr_".
+ * gcc.dg/analyzer/out-of-bounds-read-int-arr.c: Update expected
+ results.
+ * gcc.dg/analyzer/out-of-bounds-read-struct-arr.c: New test.
+ * gcc.dg/analyzer/out-of-bounds-write-char-arr.c: Update expected
+ results. Rename functions from "int_arr_" to "char_arr_".
+ * gcc.dg/analyzer/out-of-bounds-write-int-arr.c: Update expected
+ results.
+ * gcc.dg/analyzer/out-of-bounds-write-struct-arr.c: New test.
+ * gcc.dg/analyzer/pr101962.c: Update expected results.
+ * gcc.dg/analyzer/realloc-5.c: Update expected results.
+ * gcc.dg/analyzer/zlib-3.c: Update expected results.
+
+2022-12-01 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106626
+ * gcc.dg/analyzer/call-summaries-2.c: Add dg-message for expected
+ note about valid indexes.
+ * gcc.dg/analyzer/out-of-bounds-1.c: Likewise, fixing up existing
+ dg-message directives.
+ * gcc.dg/analyzer/out-of-bounds-write-char-arr.c: Likewise.
+ * gcc.dg/analyzer/out-of-bounds-write-int-arr.c: Likewise.
+
+2022-12-01 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106626
+ * gcc.dg/analyzer/out-of-bounds-read-char-arr.c: Update for
+ changes to expected wording.
+ * gcc.dg/analyzer/out-of-bounds-read-int-arr.c: Likewise.
+ * gcc.dg/analyzer/out-of-bounds-write-char-arr.c: Likewise.
+ * gcc.dg/analyzer/out-of-bounds-write-int-arr.c: Likewise.
+
+2022-12-01 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107928
+ * gcc.dg/analyzer/fd-bind-pr107928.c: New test.
+ * gcc.dg/analyzer/fd-connect-pr107928.c: New test.
+ * gcc.dg/analyzer/fd-stream-socket-active-open.c
+ (test_active_open_from_connect_constant): New, adapted from
+ test_active_open_from_connect.
+ * gcc.dg/analyzer/fd-stream-socket-passive-open.c
+ (test_passive_open_from_bind_constant): New, adapted from
+ test_passive_open_from_bind.
+ (test_passive_open_from_listen_constant): New, adapted from
+ test_passive_open_from_listen.
+
+2022-12-01 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ PR target/100866
+ * gcc.target/powerpc/pr100866-1.c: New.
+
+2022-11-30 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/aarch64/mops_5.c: New test.
+ * gcc.target/aarch64/mops_6.c: Likewise.
+ * gcc.target/aarch64/mops_7.c: Likewise.
+
+2022-11-30 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/107592
+ * gdc.dg/pr107592.d: New test.
+
+2022-11-30 Iskander Shakirzyanov <iskander@ispras.ru>
+ Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ PR driver/107787
+ * gcc.dg/Warray-bounds-34.c: Correct the regular expression
+ for -Warray-bounds=.
+ * gcc.dg/Warray-bounds-43.c: Likewise.
+ * gcc.dg/pr107787.c: New test.
+
+2022-11-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107919
+ * g++.dg/warn/Wuninitialized-pr107919-1.C: New testcase.
+
+2022-11-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107835
+ * gcc.c-torture/compile/pr107835.c: New test.
+
+2022-11-30 Alexandre Oliva <oliva@adacore.com>
+
+ PR target/107304
+ * gcc.target/i386/pr107304.c: dg-require ifunc support.
+
+2022-11-30 Lulu Cheng <chenglulu@loongson.cn>
+
+ * lib/target-supports.exp:
+ * gcc.target/loongarch/stack-check-alloca-1.c: New test.
+ * gcc.target/loongarch/stack-check-alloca-2.c: New test.
+ * gcc.target/loongarch/stack-check-alloca-3.c: New test.
+ * gcc.target/loongarch/stack-check-alloca-4.c: New test.
+ * gcc.target/loongarch/stack-check-alloca-5.c: New test.
+ * gcc.target/loongarch/stack-check-alloca-6.c: New test.
+ * gcc.target/loongarch/stack-check-alloca.h: New test.
+ * gcc.target/loongarch/stack-check-cfa-1.c: New test.
+ * gcc.target/loongarch/stack-check-cfa-2.c: New test.
+ * gcc.target/loongarch/stack-check-prologue-1.c: New test.
+ * gcc.target/loongarch/stack-check-prologue-2.c: New test.
+ * gcc.target/loongarch/stack-check-prologue-3.c: New test.
+ * gcc.target/loongarch/stack-check-prologue-4.c: New test.
+ * gcc.target/loongarch/stack-check-prologue-5.c: New test.
+ * gcc.target/loongarch/stack-check-prologue-6.c: New test.
+ * gcc.target/loongarch/stack-check-prologue-7.c: New test.
+ * gcc.target/loongarch/stack-check-prologue.h: New test.
+
+2022-11-30 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/103546
+ * gcc.dg/analyzer/ferror-1.c: New test.
+ * gcc.dg/analyzer/fileno-1.c: New test.
+ * gcc.dg/analyzer/flex-with-call-summaries.c: New test.
+ * gcc.dg/analyzer/flex-without-call-summaries.c: New test.
+ * gcc.dg/analyzer/getc-1.c: New test.
+ * gcc.dg/analyzer/isatty-1.c: New test.
+
+2022-11-30 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/105784
+ * gcc.dg/analyzer/torture/fold-ptr-arith-pr105784.c: New test.
+
+2022-11-30 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/107542
+ * g++.dg/cpp2a/spaceship-sfinae2.C: New test.
+
+2022-11-29 Harald Anlauf <anlauf@gmx.de>
+ Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/107874
+ * gfortran.dg/merge_init_expr_2.f90: Adjust code to the corrected
+ simplification.
+ * gfortran.dg/merge_1.f90: New test.
+
+2022-11-29 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/107864
+ * g++.dg/concepts/explicit-spec1a.C: New test.
+
+2022-11-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107852
+ * gcc.dg/tree-ssa/ssa-fre-101.c: New testcase.
+
+2022-11-29 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/ipa/iinline-attr.c: XFAIL on SPARC.
+ * gcc.dg/signbit-2.c: Replace vect_int selector by vect_shift.
+
+2022-11-29 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/107810
+ * gnat.dg/unchecked_convert9.adb: Adjust pattern.
+
+2022-11-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/101733
+ * g++.dg/cpp2a/concepts-requires32.C: New test.
+
+2022-11-28 Sinan <sinan.lin@linux.alibaba.com>
+
+ * gcc.target/riscv/rv32-load-64bit-constant.c: New test.
+
+2022-11-28 Maciej W. Rozycki <macro@embecosm.com>
+
+ * gcc.target/riscv/sge.c: New test.
+ * gcc.target/riscv/sgeu.c: New test.
+ * gcc.target/riscv/sle.c: New test.
+ * gcc.target/riscv/sleu.c: New test.
+
+2022-11-28 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107819
+ * gfortran.dg/elemental_dependency_7.f90: New test.
+
+2022-11-28 Frolov Daniil <frolov.da@phystech.edu>
+
+ * gcc.dg/Wformat-overflow1.c: New test.
+
+2022-11-28 Fei Gao <gaofei@eswincomputing.com>
+
+ * gcc.target/riscv/pr93304.c: Adapt testcase for the change, constrain
+ match to assembly instructions only.
+ * gcc.target/riscv/rvv/base/spill-11.c: Adapt testcase for the change.
+ * gcc.target/riscv/stack_frame.c: New test.
+
+2022-11-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107493
+ * gcc.dg/torture/pr107493.c: New testcase.
+
+2022-11-28 Tobias Burnus <tobias@codesourcery.com>
+
+ * gfortran.dg/gomp/copyprivate-1.f90: New test.
+ * gfortran.dg/gomp/copyprivate-2.f90: New test.
+ * gfortran.dg/gomp/nowait-2.f90: Move dg-error tests ...
+ * gfortran.dg/gomp/nowait-4.f90: ... to this new file.
+ * gfortran.dg/gomp/nowait-5.f90: New test.
+ * gfortran.dg/gomp/nowait-6.f90: New test.
+ * gfortran.dg/gomp/nowait-7.f90: New test.
+ * gfortran.dg/gomp/nowait-8.f90: New test.
+
+2022-11-28 Yuri Gribov <y.gribov@samsung.com>
+
+ PR sanitizer/106558
+ * c-c++-common/asan/pr106558.c: New test.
+
+2022-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/106875
+ * g++.target/i386/pr106875.C: New test.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vsetq_lane_f16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vsetq_lane_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsetq_lane_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsetq_lane_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsetq_lane_s64.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsetq_lane_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsetq_lane_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsetq_lane_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsetq_lane_u64.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsetq_lane_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_n_s16.c: Improve tests.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vrshlq_x_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_s32.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_u32.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_n_s16.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_n_s32.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_n_s8.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_n_u16.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_n_u32.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_n_u8.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_s16.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_s32.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_s8.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_u16.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_u32.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_m_u8.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_n_s16.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_n_s32.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_n_s8.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_n_u16.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_n_u32.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_n_u8.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_s16.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_s32.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_s8.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_u16.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_u32.c:
+ * gcc.target/arm/mve/intrinsics/vqsubq_u8.c:
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s16.c:
+ * gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s32.c:
+ * gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s8.c:
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s16.c: Improve tests.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulhq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmullbq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmulltq_s32.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmlahq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmlahq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmlahq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmlashq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmlashq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqdmlashq_n_s8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_n_s16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vqaddq_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vmlasq_m_n_s16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vmlasq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlasq_n_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s16.c: Improve tests.
+ * gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlaldavaxq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmlaldavaxq_s32.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vmladavaq_p_s16.c: Improve tests.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_p_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaq_p_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaxq_p_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaxq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaxq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaxq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaxq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmladavaxq_s8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/viwdupq_m_n_u16.c: Improve tests.
+ * gcc.target/arm/mve/intrinsics/viwdupq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_x_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_n_s16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_x_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_x_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_x_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_x_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhsubq_x_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_n_s16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_x_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_x_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_x_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_x_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vhaddq_x_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vfmasq_m_n_f16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vfmasq_m_n_f32.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vsubq_f16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vsubq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vsubq_x_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vmulq_f16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vmulq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmulq_x_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vaddlvaq_p_s32.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vaddlvaq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddlvaq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddlvaq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddlvq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddlvq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddlvq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddlvq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddq_x_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_p_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_p_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_p_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvaq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_p_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_p_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_p_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vaddvq_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vabsq_f16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vabsq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_x_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_x_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabsq_x_s8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vabdq_f16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vabdq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabdq_x_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vabavq_p_s16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vabavq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_p_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_p_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vabavq_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vmaxaq_m_s16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vmaxaq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxaq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxaq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxaq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxaq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxavq_p_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxavq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxavq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxavq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxavq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxavq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmaq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmaq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmavq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmavq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmq_x_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmq_x_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmvq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmvq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxq_x_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_p_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_p_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_p_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vmaxvq_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vminaq_m_s16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vminaq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminaq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminaq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminaq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminaq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminavq_p_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminavq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminavq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminavq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminavq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminavq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmaq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmaq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmaq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmaq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmavq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmavq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmavq_p_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmavq_p_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmq_x_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmq_x_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmvq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmvq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmvq_p_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminnmvq_p_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_x_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_x_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_x_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_x_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_x_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminq_x_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_p_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_p_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_p_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_p_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_p_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_p_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vminvq_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpcsq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpeqq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgeq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpgtq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmphiq_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpleq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpltq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_m_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcmpneq_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_f16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_f16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdupq_x_n_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vidupq_m_n_u16.c: Improve tests.
+ * gcc.target/arm/mve/intrinsics/vidupq_m_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_m_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_m_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_m_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_m_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_x_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_x_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_x_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_x_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vidupq_x_wb_u8.c: Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u16.c : Improve test.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u32.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u8.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u16.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u32.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u8.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_n_u16.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_n_u32.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_n_u8.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_wb_u16.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_wb_u32.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_wb_u8.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u32.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u8.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u16.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u32.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u8.c : Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vddupq_m_n_u16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vddupq_m_n_u32.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_m_n_u8.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_m_wb_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_m_wb_u32.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_m_wb_u8.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_n_u16.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_n_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_n_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_wb_u16.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_wb_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_wb_u8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_x_n_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_x_n_u32.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_x_n_u8.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_x_wb_u16.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_x_wb_u32.c : Likewise.
+ * gcc.target/arm/mve/intrinsics/vddupq_x_wb_u8.c : Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_f32.c:
+ Update test.
+ * gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_s32.c:
+ Likewise.
+ * gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_u32.c:
+ Likewise.
+
+2022-11-28 Andrea Corallo <andrea.corallo@arm.com>
+
+ * gcc.target/arm/mve/intrinsics/vcreateq_f16.c: Improve test.
+ * gcc.target/arm/mve/intrinsics/vcreateq_f32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_s16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_s32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_s64.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_s8.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_u16.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_u32.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_u64.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/vcreateq_u8.c: Likewise.
+
+2022-11-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107876
+ * g++.dg/tree-ssa/pr107876.C: New testcase.
+
+2022-11-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107867
+ * g++.dg/pr107867.C: New testcase.
+
+2022-11-28 Lulu Cheng <chenglulu@loongson.cn>
+
+ * gcc.target/loongarch/imm-load.c: New test.
+ * gcc.target/loongarch/imm-load1.c: New test.
+
+2022-11-28 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/avx512bf16-cvtsbh2ss-1.c: Scan pslld.
+ * gcc.target/i386/extendbfsf.c: New test.
+
+2022-11-26 Andrew Pinski <apinski@marvell.com>
+
+ PR tree-optimization/103356
+ * gcc.dg/pr103356-1.c: New test.
+
+2022-11-25 Sandra Loosemore <sandra@codesourcery.com>
+
+ * g++.dg/gomp/target-simd-clone-1.C: New.
+ * g++.dg/gomp/target-simd-clone-2.C: New.
+ * gcc.dg/gomp/target-simd-clone-1.c: New.
+ * gcc.dg/gomp/target-simd-clone-2.c: New.
+ * gcc.dg/gomp/target-simd-clone-3.c: New.
+ * gcc.dg/gomp/target-simd-clone-4.c: New.
+ * gcc.dg/gomp/target-simd-clone-5.c: New.
+ * gcc.dg/gomp/target-simd-clone-6.c: New.
+ * gcc.dg/gomp/target-simd-clone-7.c: New.
+ * gcc.dg/gomp/target-simd-clone-8.c: New.
+ * lib/scanoffloadipa.exp: New.
+
+2022-11-25 Tamar Christina <tamar.christina@arm.com>
+
+ PR target/107830
+ * gcc.target/aarch64/sve2/pr107830-1.c: New test.
+ * gcc.target/aarch64/sve2/pr107830-2.c: New test.
+
+2022-11-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/opt100.adb: New test.
+ * gnat.dg/opt100_pkg.adb, gnat.dg/opt100_pkg.ads: New helper.
+
+2022-11-25 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107865
+ * gfortran.dg/graphite/pr107865.f90: New testcase.
+
+2022-11-25 Kewen.Lin <linkw@gcc.gnu.org>
+
+ PR target/99889
+ * g++.dg/pr93195a.C: Remove the skip on powerpc*-*-* 64-bit.
+ * gcc.target/aarch64/pr92424-2.c: Adjust LPFE1 with LPFE0.
+ * gcc.target/aarch64/pr92424-3.c: Likewise.
+ * gcc.target/i386/pr93492-2.c: Likewise.
+ * gcc.target/i386/pr93492-3.c: Likewise.
+ * gcc.target/i386/pr93492-4.c: Likewise.
+ * gcc.target/i386/pr93492-5.c: Likewise.
+
+2022-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/107317
+ * gcc.dg/asan/pr107317.c: New test.
+
+2022-11-24 Florian Weimer <fweimer@redhat.com>
+
+ PR c/107805
+ * gcc.dg/pr107805-1.c: New test.
+ * gcc.dg/pr107805-2.c: Likewise.
+
+2022-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/107127
+ * gcc.dg/pr107127.c (foo): Add missing closing }.
+
+2022-11-24 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106473
+ * gcc.dg/analyzer/aliasing-pr106473.c: New test.
+ * gcc.dg/analyzer/allocation-size-2.c: Add
+ -fanalyzer-fine-grained".
+ * gcc.dg/analyzer/allocation-size-3.c: Likewise.
+ * gcc.dg/analyzer/explode-1.c: Mark leak with XFAIL.
+ * gcc.dg/analyzer/explode-3.c: New test.
+ * gcc.dg/analyzer/malloc-reuse.c: New test.
+
+2022-11-24 Hongyu Wang <hongyu.wang@intel.com>
+
+ PR target/107692
+ * gcc.dg/guality/loop-1.c: Remove additional option for ia32.
+ * gcc.target/i386/pr86270.c: Add -fno-unroll-loops.
+ * gcc.target/i386/pr93002.c: Likewise.
+
+2022-11-23 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.dg/analyzer/call-summaries-2.c (uses_alloca): Use
+ __builtin_alloca instead of alloca.
+
+2022-11-23 Steve Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/107577
+ * gfortran.dg/pr107577.f90: New test.
+
+2022-11-23 Andrew Pinski <apinski@marvell.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR c/107127
+ * gcc.dg/pr107127.c: New test.
+
+2022-11-22 Siddhesh Poyarekar <siddhesh@gotplt.org>
+
+ * gcc.dg/builtin-dynamic-object-size-0.c (test_strdup,
+ test_strndup, test_strdup_min, test_strndup_min): New tests.
+ (main): Call them.
+ * gcc.dg/builtin-dynamic-object-size-1.c: Silence overread
+ warnings.
+ * gcc.dg/builtin-dynamic-object-size-2.c: Likewise.
+ * gcc.dg/builtin-dynamic-object-size-3.c: Likewise.
+ * gcc.dg/builtin-dynamic-object-size-4.c: Likewise.
+ * gcc.dg/builtin-object-size-1.c: Silence overread warnings.
+ Declare free, strdup and strndup.
+ (test11): New test.
+ (main): Call it.
+ * gcc.dg/builtin-object-size-2.c: Silence overread warnings.
+ Declare free, strdup and strndup.
+ (test9): New test.
+ (main): Call it.
+ * gcc.dg/builtin-object-size-3.c: Silence overread warnings.
+ Declare free, strdup and strndup.
+ (test11): New test.
+ (main): Call it.
+ * gcc.dg/builtin-object-size-4.c: Silence overread warnings.
+ Declare free, strdup and strndup.
+ (test9): New test.
+ (main): Call it.
+
+2022-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107788
+ * g++.dg/analyzer/named-functions.C: New test.
+
+2022-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107783
+ * gcc.dg/analyzer/fd-accept.c (test_accept_on_constant): New.
+ * gcc.dg/analyzer/fd-bind.c (test_bind_on_constant): New.
+ * gcc.dg/analyzer/fd-connect.c (test_connect_on_constant): New.
+ * gcc.dg/analyzer/fd-listen.c (test_listen_on_connected_socket):
+ Fix typo.
+ (test_listen_on_constant): New.
+
+2022-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107807
+ * gcc.dg/analyzer/errno-___errno.c: New test.
+ * gcc.dg/analyzer/errno-__error.c: New test.
+ * gcc.dg/analyzer/errno-global-var.c: New test.
+
+2022-11-22 Maciej W. Rozycki <macro@embecosm.com>
+
+ * lib/target-supports.exp
+ (check_effective_target_mpaired_single): Add `args' argument and
+ pass it to `check_no_compiler_messages' replacing
+ `-mpaired-single'.
+ (add_options_for_mips_loongson_mmi): Add `args' argument and
+ pass it to `check_no_compiler_messages'.
+ (check_effective_target_mips_msa): Add `args' argument and pass
+ it to `check_no_compiler_messages' replacing `-mmsa'.
+ (check_effective_target_mpaired_single_runtime)
+ (add_options_for_mpaired_single): Pass `-mpaired-single' to
+ `check_effective_target_mpaired_single'.
+ (check_effective_target_mips_loongson_mmi_runtime)
+ (add_options_for_mips_loongson_mmi): Pass `-mloongson-mmi' to
+ `check_effective_target_mips_loongson_mmi'.
+ (check_effective_target_mips_msa_runtime)
+ (add_options_for_mips_msa): Pass `-mmsa' to
+ `check_effective_target_mips_msa'.
+ (et-is-effective-target): Verify that EFFECTIVE_TARGETS exists
+ and if not, just check if the current compilation environment
+ supports the target feature requested.
+ (check_vect_support_and_set_flags): Pass `-mpaired-single',
+ `-mloongson-mmi', and `-mmsa' to the respective target feature
+ checks.
+
+2022-11-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/sso18.adb: New test.
+
+2022-11-22 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/107661
+ * g++.dg/ipa/pr107661.C: New test.
+
+2022-11-22 Christophe Lyon <christophe.lyon@arm.com>
+
+ PR target/107604
+ * gcc.target/aarch64/aapcs64/test_dfp_17.c: Fix for big-endian.
+
+2022-11-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107803
+ * g++.dg/pr107803.C: New testcase.
+
+2022-11-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107766
+ * g++.dg/vect/pr107766.cc: New testcase.
+
+2022-11-22 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pieces-memset-3.c: Remove xfail.
+ * gcc.target/i386/pieces-memset-37.c: Remove xfail.
+ * gcc.target/i386/pieces-memset-39.c: Remove xfail.
+
+2022-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107788
+ * g++.dg/analyzer/fd-bind-pr107783.C: New test.
+
+2022-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107783
+ * gcc.dg/analyzer/fd-bind-pr107783.c: New test.
+
+2022-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107777
+ * gcc.dg/analyzer/call-summaries-errno.c: New test.
+ * gcc.dg/analyzer/errno-pr107777.c: New test.
+
+2022-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/analyzer/CWE-131-examples.c: New test.
+ * gcc.dg/analyzer/file-CWE-1341-example.c: New test.
+ * gcc.dg/analyzer/malloc-CWE-401-example.c: New test.
+ * gcc.dg/analyzer/malloc-CWE-415-examples.c: New test.
+ * gcc.dg/analyzer/malloc-CWE-416-examples.c: New test.
+ * gcc.dg/analyzer/malloc-CWE-590-examples.c: New test.
+
+2022-11-21 Lewis Hyatt <lhyatt@gmail.com>
+
+ * c-c++-common/gomp/pragma-omp-unknown.c: New test.
+
+2022-11-21 Dimitar Dimitrov <dimitar@dinux.eu>
+
+ * gcc.dg/analyzer/fd-accept.c: Require sockets.
+ * gcc.dg/analyzer/fd-bind.c: Ditto.
+ * gcc.dg/analyzer/fd-connect.c: Ditto.
+ * gcc.dg/analyzer/fd-datagram-socket.c: Ditto.
+ * gcc.dg/analyzer/fd-glibc-byte-stream-connection-server.c:
+ Ditto.
+ * gcc.dg/analyzer/fd-glibc-byte-stream-socket.c: Ditto.
+ * gcc.dg/analyzer/fd-glibc-datagram-client.c: Ditto.
+ * gcc.dg/analyzer/fd-glibc-datagram-socket.c: Ditto.
+ * gcc.dg/analyzer/fd-listen.c: Ditto.
+ * gcc.dg/analyzer/fd-manpage-getaddrinfo-client.c: Ditto.
+ * gcc.dg/analyzer/fd-mappage-getaddrinfo-server.c: Ditto.
+ * gcc.dg/analyzer/fd-socket-meaning.c: Ditto.
+ * gcc.dg/analyzer/fd-socket-misuse.c: Ditto.
+ * gcc.dg/analyzer/fd-stream-socket-active-open.c: Ditto.
+ * gcc.dg/analyzer/fd-stream-socket-passive-open.c: Ditto.
+ * gcc.dg/analyzer/fd-stream-socket.c: Ditto.
+ * gcc.dg/analyzer/fd-symbolic-socket.c: Ditto.
+ * lib/target-supports.exp (check_effective_target_sockets): New
+ check.
+
+2022-11-21 Andrew Carlotti <andrew.carlotti@arm.com>
+
+ * gcc.dg/pr77975.c: Make tests more robust.
+
+2022-11-21 Andrew Carlotti <andrew.carlotti@arm.com>
+
+ * gcc.dg/tree-ssa/popcount-max.c: New test.
+
+2022-11-21 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
+ Yvan ROUX <yvan.roux@foss.st.com>
+
+ * g++.dg/modules/pr99023_b.X: Match Windows paths too.
+
+2022-11-21 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * gcc.target/riscv/pr107786-2.c: New test.
+ * gcc.target/riscv/pr107786.c: New test.
+
+2022-11-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/machine_attr2.ads, gnat.dg/machine_attr2.adb: New test.
+
+2022-11-21 Andrew Pinski <apinski@marvell.com>
+
+ * gcc.dg/redecl-23.c: New test.
+ * gcc.dg/redecl-24.c: New test.
+ * gcc.dg/redecl-25.c: New test.
+
+2022-11-21 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/avxneconvert-1.c: New test.
+
+2022-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/107183
+ * gcc.dg/ubsan/pr107183.c: New test.
+
+2022-11-20 Jeff Law <jeffreyalaw@gmail.com>
+
+ * gcc.dg/pr96542.c: Avoid falsely matching DECL_UIDs with
+ the number 254 in them.
+
+2022-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/107628
+ * gcc.target/i386/pr107628.c: New test.
+
+2022-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/cpp23/constexpr-nonlit17.C: New test.
+ * g++.dg/cpp23/constexpr-nonlit18.C: New test.
+ * g++.dg/cpp23/feat-cxx2b.C: Adjust expected __cpp_constexpr
+ value.
+ * g++.dg/ext/stmtexpr19.C: Don't expect an error.
+ * g++.dg/ext/stmtexpr25.C: New test.
+
+2022-11-19 Jeff Chapman II <jchapman@lock3software.com>
+ Andrew Sutton <asutton@lock3software.com>
+ Andrew Marmaduke <amarmaduke@lock3software.com>
+ Michael Lopez <mlopez@lock3software.com>
+ Jason Merrill <jason@redhat.com>
+
+ * g++.dg/modules/modules.exp: Pass dg-options to link command.
+ * lib/g++.exp: Add -L for libstdc++exp.a.
+ * g++.dg/contracts/backtrace_handler/assert_fail.cpp: New test.
+ * g++.dg/contracts/backtrace_handler/handle_contract_violation.cpp: New test.
+ * g++.dg/contracts/contracts-access1.C: New test.
+ * g++.dg/contracts/contracts-assume1.C: New test.
+ * g++.dg/contracts/contracts-assume2.C: New test.
+ * g++.dg/contracts/contracts-assume3.C: New test.
+ * g++.dg/contracts/contracts-assume4.C: New test.
+ * g++.dg/contracts/contracts-assume5.C: New test.
+ * g++.dg/contracts/contracts-assume6.C: New test.
+ * g++.dg/contracts/contracts-comdat1.C: New test.
+ * g++.dg/contracts/contracts-config1.C: New test.
+ * g++.dg/contracts/contracts-constexpr1.C: New test.
+ * g++.dg/contracts/contracts-constexpr2.C: New test.
+ * g++.dg/contracts/contracts-constexpr3.C: New test.
+ * g++.dg/contracts/contracts-conversion1.C: New test.
+ * g++.dg/contracts/contracts-ctor-dtor1.C: New test.
+ * g++.dg/contracts/contracts-ctor-dtor2.C: New test.
+ * g++.dg/contracts/contracts-cv1.C: New test.
+ * g++.dg/contracts/contracts-deduced1.C: New test.
+ * g++.dg/contracts/contracts-deduced2.C: New test.
+ * g++.dg/contracts/contracts-friend1.C: New test.
+ * g++.dg/contracts/contracts-ft1.C: New test.
+ * g++.dg/contracts/contracts-ignore1.C: New test.
+ * g++.dg/contracts/contracts-ignore2.C: New test.
+ * g++.dg/contracts/contracts-large-return.C: New test.
+ * g++.dg/contracts/contracts-multiline1.C: New test.
+ * g++.dg/contracts/contracts-multiple-inheritance1.C: New test.
+ * g++.dg/contracts/contracts-multiple-inheritance2.C: New test.
+ * g++.dg/contracts/contracts-nested-class1.C: New test.
+ * g++.dg/contracts/contracts-nested-class2.C: New test.
+ * g++.dg/contracts/contracts-nocopy1.C: New test.
+ * g++.dg/contracts/contracts-override.C: New test.
+ * g++.dg/contracts/contracts-post1.C: New test.
+ * g++.dg/contracts/contracts-post2.C: New test.
+ * g++.dg/contracts/contracts-post3.C: New test.
+ * g++.dg/contracts/contracts-post4.C: New test.
+ * g++.dg/contracts/contracts-post5.C: New test.
+ * g++.dg/contracts/contracts-post6.C: New test.
+ * g++.dg/contracts/contracts-pre1.C: New test.
+ * g++.dg/contracts/contracts-pre10.C: New test.
+ * g++.dg/contracts/contracts-pre2.C: New test.
+ * g++.dg/contracts/contracts-pre2a1.C: New test.
+ * g++.dg/contracts/contracts-pre2a2.C: New test.
+ * g++.dg/contracts/contracts-pre3.C: New test.
+ * g++.dg/contracts/contracts-pre4.C: New test.
+ * g++.dg/contracts/contracts-pre5.C: New test.
+ * g++.dg/contracts/contracts-pre6.C: New test.
+ * g++.dg/contracts/contracts-pre7.C: New test.
+ * g++.dg/contracts/contracts-pre9.C: New test.
+ * g++.dg/contracts/contracts-redecl1.C: New test.
+ * g++.dg/contracts/contracts-redecl2.C: New test.
+ * g++.dg/contracts/contracts-redecl3.C: New test.
+ * g++.dg/contracts/contracts-redecl4.C: New test.
+ * g++.dg/contracts/contracts-redecl5.C: New test.
+ * g++.dg/contracts/contracts-redecl6.C: New test.
+ * g++.dg/contracts/contracts-redecl7.C: New test.
+ * g++.dg/contracts/contracts-redecl8.C: New test.
+ * g++.dg/contracts/contracts-tmpl-attr1.C: New test.
+ * g++.dg/contracts/contracts-tmpl-spec1.C: New test.
+ * g++.dg/contracts/contracts-tmpl-spec2.C: New test.
+ * g++.dg/contracts/contracts-tmpl-spec3.C: New test.
+ * g++.dg/contracts/contracts1.C: New test.
+ * g++.dg/contracts/contracts10.C: New test.
+ * g++.dg/contracts/contracts11.C: New test.
+ * g++.dg/contracts/contracts12.C: New test.
+ * g++.dg/contracts/contracts13.C: New test.
+ * g++.dg/contracts/contracts14.C: New test.
+ * g++.dg/contracts/contracts15.C: New test.
+ * g++.dg/contracts/contracts16.C: New test.
+ * g++.dg/contracts/contracts17.C: New test.
+ * g++.dg/contracts/contracts18.C: New test.
+ * g++.dg/contracts/contracts19.C: New test.
+ * g++.dg/contracts/contracts2.C: New test.
+ * g++.dg/contracts/contracts20.C: New test.
+ * g++.dg/contracts/contracts22.C: New test.
+ * g++.dg/contracts/contracts24.C: New test.
+ * g++.dg/contracts/contracts25.C: New test.
+ * g++.dg/contracts/contracts3.C: New test.
+ * g++.dg/contracts/contracts35.C: New test.
+ * g++.dg/contracts/contracts4.C: New test.
+ * g++.dg/contracts/contracts5.C: New test.
+ * g++.dg/contracts/contracts6.C: New test.
+ * g++.dg/contracts/contracts7.C: New test.
+ * g++.dg/contracts/contracts8.C: New test.
+ * g++.dg/contracts/contracts9.C: New test.
+ * g++.dg/modules/contracts-1_a.C: New test.
+ * g++.dg/modules/contracts-1_b.C: New test.
+ * g++.dg/modules/contracts-2_a.C: New test.
+ * g++.dg/modules/contracts-2_b.C: New test.
+ * g++.dg/modules/contracts-2_c.C: New test.
+ * g++.dg/modules/contracts-3_a.C: New test.
+ * g++.dg/modules/contracts-3_b.C: New test.
+ * g++.dg/modules/contracts-4_a.C: New test.
+ * g++.dg/modules/contracts-4_b.C: New test.
+ * g++.dg/modules/contracts-4_c.C: New test.
+ * g++.dg/modules/contracts-4_d.C: New test.
+ * g++.dg/modules/contracts-tpl-friend-1_a.C: New test.
+ * g++.dg/modules/contracts-tpl-friend-1_b.C: New test.
+ * g++.dg/contracts/backtrace_handler/Makefile: New test.
+ * g++.dg/contracts/backtrace_handler/README: New test.
+ * g++.dg/contracts/backtrace_handler/example_out.txt: New test.
+ * g++.dg/contracts/backtrace_handler/example_pretty.txt: New test.
+ * g++.dg/contracts/backtrace_handler/prettytrace.sh: New test.
+ * g++.dg/contracts/except_preload_handler/Makefile: New test.
+ * g++.dg/contracts/except_preload_handler/README: New test.
+ * g++.dg/contracts/except_preload_handler/assert_fail.cpp: New test.
+ * g++.dg/contracts/except_preload_handler/handle_contract_violation.cpp: New test.
+ * g++.dg/contracts/noexcept_preload_handler/Makefile: New test.
+ * g++.dg/contracts/noexcept_preload_handler/README: New test.
+ * g++.dg/contracts/noexcept_preload_handler/assert_fail.cpp: New test.
+ * g++.dg/contracts/noexcept_preload_handler/handle_contract_violation.cpp: New test.
+ * g++.dg/contracts/preload_handler/Makefile: New test.
+ * g++.dg/contracts/preload_handler/README: New test.
+ * g++.dg/contracts/preload_handler/assert_fail.cpp: New test.
+ * g++.dg/contracts/preload_handler/handle_contract_violation.cpp: New test.
+ * g++.dg/contracts/preload_nocontinue_handler/Makefile: New test.
+ * g++.dg/contracts/preload_nocontinue_handler/README: New test.
+ * g++.dg/contracts/preload_nocontinue_handler/assert_fail.cpp: New test.
+ * g++.dg/contracts/preload_nocontinue_handler/handle_contract_violation.cpp: New test.
+ * g++.dg/contracts/preload_nocontinue_handler/nocontinue.cpp: New test.
+
+2022-11-19 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107582
+ * gcc.dg/analyzer/feasibility-4.c: New test.
+ * gcc.dg/analyzer/feasibility-pr107582-1.c: New test.
+ * gcc.dg/analyzer/feasibility-pr107582-2.c: New test.
+
+2022-11-18 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/analyzer/analyzer-debugging-fns-1.c: New test.
+ * gcc.dg/analyzer/attr-const-3.c: Increase the
+ "analyzer-max-svalue-depth" from 0 to 4 to ensure that
+ "__analyzer_eval" is recognized.
+
+2022-11-18 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * gcc.target/riscv/zbb-min-max-02.c: New test.
+
+2022-11-18 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * gcc.target/riscv/zbs-if_then_else-01.c: New test.
+
+2022-11-18 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * gcc.target/riscv/zbs-bclri.c: Rename
+ * gcc.target/riscv/zbs-bclri-01.c: Renamed from above.
+ * gcc.target/riscv/zbs-bclri-02.c: New test.
+ * gcc.target/riscv/zbs-binvi.c: New test.
+ * gcc.target/riscv/zbs-bseti.c: New test.
+
+2022-11-18 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * gcc.target/riscv/zba-shNadd-04.c: New test.
+
+2022-11-18 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * gcc.target/riscv/zba-shNadd-05.c: New test.
+
+2022-11-18 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * gcc.target/riscv/branch-1.c: New test.
+
+2022-11-18 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * gcc.target/riscv/zbs-bseti-02.c: New test.
+
+2022-11-18 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107576
+ * gfortran.dg/null_actual_3.f90: New test.
+
+2022-11-18 Andrew Pinski <apinski@marvell.com>
+
+ * gcc.dg/redecl-22.c: New test.
+
+2022-11-18 Andrew Pinski <apinski@marvell.com>
+
+ PR c/106764
+ PR c/106765
+ PR c/107307
+ * gcc.dg/redecl-19.c: New test.
+ * gcc.dg/redecl-20.c: New test.
+ * gcc.dg/redecl-21.c: New test.
+
+2022-11-18 Yixuan Chen <chenyixuan@iscas.ac.cn>
+
+ * gcc.dg/pr25521.c: Fix testcase for architectures that use .srodata.
+
+2022-11-18 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/aarch64/ldapr-sext.c: Adjust expected output.
+
+2022-11-18 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
+
+ * lib/target-supports.exp (check_is_prog_name_available):
+ New.
+ * lib/target-supports-dg.exp
+ (dg-require-prog-name-available): New.
+ * g++.dg/modules/modules.exp: Verify avilability of module
+ mapper.
+
+2022-11-18 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/aarch64/ldapr-ext.c: Rename to...
+ * gcc.target/aarch64/ldapr-zext.c: ... This. Fix expected assembly.
+ * gcc.target/aarch64/ldapr-sext.c: New test.
+
+2022-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/cpp2a/decomp5.C: New test.
+ * g++.dg/cpp2a/decomp6.C: New test.
+ * g++.dg/cpp2a/decomp7.C: New test.
+ * g++.dg/cpp2a/concepts-placeholder7.C: Adjust expected diagnostics.
+ * g++.dg/cpp2a/concepts-placeholder8.C: Likewise.
+ * g++.dg/cpp2a/concepts-placeholder9.C: New test.
+ * g++.dg/cpp2a/concepts-placeholder10.C: New test.
+
+2022-11-18 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107647
+ * gcc.target/i386/pr107647.c: New testcase.
+
+2022-11-18 Jinyang He <hejinyang@loongson.cn>
+
+ PR target/107713
+ * gcc.target/loongarch/pr107713-1.c: New test.
+ * gcc.target/loongarch/pr107713-2.c: New test.
+
+2022-11-18 Marek Polacek <polacek@redhat.com>
+
+ PR c++/104066
+ * g++.dg/cpp2a/constinit18.C: New test.
+
+2022-11-17 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/107732
+ * gcc.dg/tree-ssa/pr107732.c: New test.
+
+2022-11-17 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107711
+ * gcc.dg/analyzer/named-constants-Wunused-macros.c: New test.
+
+2022-11-17 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * gcc.target/riscv/zbs-bclri.c: New test.
+
+2022-11-17 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * gcc.target/riscv/zbs-bexti.c: New test.
+
+2022-11-17 mtsamis <manolis.tsamis@vrull.eu>
+
+ * gcc.target/riscv/shrink-wrap-1.c: New test.
+
+2022-11-17 Lili Cui <lili.cui@intel.com>
+
+ * gcc.target/i386/pieces-memset-50.c: New test.
+
+2022-11-17 Tamar Christina <tamar.christina@arm.com>
+
+ PR tree-optimization/107717
+ * gcc.target/aarch64/sve2/pr107717.c: New test.
+
+2022-11-17 Jia-Wei Chen <jiawei@iscas.ac.cn>
+
+ * gcc.target/riscv/rvv/base/spill-sp-adjust.c: New test.
+
+2022-11-16 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/analyzer/named-constants-via-command-line.c: New test.
+ * gcc.dg/analyzer/named-constants-via-macros-3.c: New test.
+ * gcc.dg/analyzer/named-constants-via-macros-4.c: New test.
+ * gcc.dg/analyzer/named-constants-via-macros-empty.c: New test.
+ * gcc.dg/analyzer/named-constants-via-macros-gc.c: New test.
+ * gcc.dg/analyzer/named-constants-via-macros-traditional.c: New test.
+ * gcc.dg/analyzer/named-constants-via-macros-undef.c: New test.
+
+2022-11-16 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107711
+ * gcc.dg/analyzer/fdump-analyzer-1.c: New test.
+
+2022-11-16 Steve Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/107707
+ * gfortran.dg/pr107707.f90: New test.
+
+2022-11-16 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106649
+ * g++.dg/cpp0x/constexpr-ctor2.C: Expect an error in c++20_down only.
+ * g++.dg/cpp0x/constexpr-default-ctor.C: Likewise.
+ * g++.dg/cpp0x/constexpr-diag3.C: Likewise.
+ * g++.dg/cpp0x/constexpr-ex1.C: Likewise.
+ * g++.dg/cpp0x/constexpr-friend.C: Likewise.
+ * g++.dg/cpp0x/constexpr-generated1.C: Likewise.
+ * g++.dg/cpp0x/constexpr-ice5.C: Likewise.
+ * g++.dg/cpp0x/constexpr-ice6.C: Likewise.
+ * g++.dg/cpp0x/constexpr-memfn1.C: Likewise.
+ * g++.dg/cpp0x/constexpr-neg2.C: Likewise.
+ * g++.dg/cpp0x/constexpr-non-const-arg.C: Likewise.
+ * g++.dg/cpp0x/constexpr-reinterpret1.C: Likewise.
+ * g++.dg/cpp0x/pr65327.C: Likewise.
+ * g++.dg/cpp1y/constexpr-105050.C: Likewise.
+ * g++.dg/cpp1y/constexpr-89285-2.C: Likewise.
+ * g++.dg/cpp1y/constexpr-89285.C: Likewise.
+ * g++.dg/cpp1y/constexpr-89785-2.C: Likewise.
+ * g++.dg/cpp1y/constexpr-neg1.C: Likewise.
+ * g++.dg/cpp1y/constexpr-nsdmi7b.C: Likewise.
+ * g++.dg/cpp1y/constexpr-throw.C: Likewise.
+ * g++.dg/cpp23/constexpr-nonlit3.C: Remove dg-error.
+ * g++.dg/cpp23/constexpr-nonlit6.C: Call the test functions.
+ * g++.dg/cpp23/feat-cxx2b.C: Adjust the expected value of
+ __cpp_constexpr.
+ * g++.dg/cpp2a/consteval3.C: Remove dg-error.
+ * g++.dg/cpp2a/constexpr-new7.C: Expect an error in c++20_down only.
+ * g++.dg/cpp2a/constexpr-try5.C: Remove dg-error.
+ * g++.dg/cpp2a/spaceship-constexpr1.C: Expect an error in c++20_down
+ only.
+ * g++.dg/cpp2a/spaceship-eq3.C: Likewise.
+ * g++.dg/diagnostic/constexpr1.C: Remove dg-error.
+ * g++.dg/gomp/pr79664.C: Use -Winvalid-constexpr -pedantic-errors.
+ * g++.dg/ubsan/vptr-4.C: Likewise.
+ * g++.dg/cpp23/constexpr-nonlit10.C: New test.
+ * g++.dg/cpp23/constexpr-nonlit11.C: New test.
+ * g++.dg/cpp23/constexpr-nonlit12.C: New test.
+ * g++.dg/cpp23/constexpr-nonlit13.C: New test.
+ * g++.dg/cpp23/constexpr-nonlit14.C: New test.
+ * g++.dg/cpp23/constexpr-nonlit15.C: New test.
+ * g++.dg/cpp23/constexpr-nonlit16.C: New test.
+ * g++.dg/cpp23/constexpr-nonlit8.C: New test.
+ * g++.dg/cpp23/constexpr-nonlit9.C: New test.
+
+2022-11-16 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107681
+ * gfortran.dg/pr107681.f90: New test.
+
+2022-11-16 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107680
+ * gfortran.dg/pr107680.f90: New test.
+
+2022-11-16 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * gcc.target/riscv/zbs-bext.c: Add testcases.
+ * gcc.target/riscv/zbs-bexti.c: Add testcases.
+
+2022-11-16 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * gcc.target/riscv/zbs-bext.c: Add testcases.
+ * gcc.target/riscv/zbs-bexti.c: Add testcases.
+
+2022-11-16 Hans-Peter Nilsson <hp@axis.com>
+
+ * lib/gcc-dg.exp (gcc-transform-out-of-tree): New proc.
+ * g++.dg/gcov/gcov.exp, gcc.misc-tests/gcov.exp: Call
+ gcc-transform-out-of-tree instead of transform.
+
+2022-11-16 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107686
+ * gcc.dg/pr107686.c: New testcase.
+
+2022-11-16 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/107679
+ * gfortran.dg/pr107679.f90: New testcase.
+
+2022-11-16 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/cpp2a/is-layout-compatible3.C: Expect enums with different
+ alignas to be layout compatible, while classes with different
+ alignas on members layout incompatible.
+ * g++.dg/DRs/dr2583.C: New test.
+
+2022-11-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/107624
+ * g++.dg/cpp23/static-operator-call4.C: New test.
+ * g++.dg/cpp23/subscript10.C: New test.
+ * g++.dg/cpp23/subscript11.C: New test.
+
+2022-11-16 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/plugin/analyzer_kernel_plugin.c
+ (copy_across_boundary_fn::matches_call_types_p): New.
+ * gcc.dg/plugin/analyzer_known_fns_plugin.c
+ (known_function_returns_42::matches_call_types_p): New.
+ (known_function_attempt_to_copy::matches_call_types_p): New.
+
+2022-11-16 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/cpp2a/volatile1.C (fn2, fn3, racoon): Adjust expected
+ diagnostics.
+ * g++.dg/cpp2a/volatile3.C (fn2, fn3, racoon): Likewise.
+ * g++.dg/cpp2a/volatile5.C (f): Likewise.
+ * g++.dg/ext/vector25.C (foo): Don't expect a warning.
+ * g++.dg/cpp1y/new1.C (test_unused): Likewise.
+
+2022-11-16 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/cpp2a/concepts-dr2428.C: New test.
+
+2022-11-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107668
+ * gcc.dg/ubsan/pr107668.c: New test.
+
+2022-11-16 Kewen Lin <linkw@linux.ibm.com>
+
+ PR rtl-optimization/90259
+ * g++.target/powerpc/pr90259.C: New.
+
+2022-11-15 Marek Polacek <polacek@redhat.com>
+
+ PR c++/107492
+ * g++.dg/warn/Wignored-qualifiers3.C: New test.
+
+2022-11-15 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * gcc.target/riscv/builtin_pause.c: New test.
+
+2022-11-15 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106140
+ * gcc.dg/analyzer/fd-accept.c: New test.
+ * gcc.dg/analyzer/fd-bind.c: New test.
+ * gcc.dg/analyzer/fd-connect.c: New test.
+ * gcc.dg/analyzer/fd-datagram-socket.c: New test.
+ * gcc.dg/analyzer/fd-glibc-byte-stream-connection-server.c: New test.
+ * gcc.dg/analyzer/fd-glibc-byte-stream-socket.c: New test.
+ * gcc.dg/analyzer/fd-glibc-datagram-client.c: New test.
+ * gcc.dg/analyzer/fd-glibc-datagram-socket.c: New test.
+ * gcc.dg/analyzer/fd-glibc-make_named_socket.h: New test.
+ * gcc.dg/analyzer/fd-listen.c: New test.
+ * gcc.dg/analyzer/fd-manpage-getaddrinfo-client.c: New test.
+ * gcc.dg/analyzer/fd-mappage-getaddrinfo-server.c: New test.
+ * gcc.dg/analyzer/fd-socket-meaning.c: New test.
+ * gcc.dg/analyzer/fd-socket-misuse.c: New test.
+ * gcc.dg/analyzer/fd-stream-socket-active-open.c: New test.
+ * gcc.dg/analyzer/fd-stream-socket-passive-open.c: New test.
+ * gcc.dg/analyzer/fd-stream-socket.c: New test.
+ * gcc.dg/analyzer/fd-symbolic-socket.c: New test.
+ * gcc.dg/analyzer/pr104369-1.c: Add -Wno-analyzer-too-complex and
+ -Wno-analyzer-fd-leak to options.
+ * gcc.dg/analyzer/pr104369-2.c: Add -Wno-analyzer-fd-leak to
+ options.
+
+2022-11-15 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/analyzer/analyzer-decls.h
+ (__analyzer_dump_named_constant): New decl.
+ * gcc.dg/analyzer/fd-4.c (void): Likewise.
+ (O_ACCMODE): Define.
+ * gcc.dg/analyzer/fd-access-mode-enum.c: New test, based on .
+ * gcc.dg/analyzer/fd-5.c: ...this. Rename to...
+ * gcc.dg/analyzer/fd-access-mode-macros.c: ...this.
+ (O_ACCMODE): Define.
+ * gcc.dg/analyzer/fd-access-mode-target-headers.c: New test, also
+ based on fd-5.c.
+ (test_sm_fd_constants): New.
+ * gcc.dg/analyzer/fd-dup-1.c (O_ACCMODE): Define.
+ * gcc.dg/analyzer/named-constants-via-enum.c: New test.
+ * gcc.dg/analyzer/named-constants-via-enum-and-macro.c: New test.
+ * gcc.dg/analyzer/named-constants-via-macros-2.c: New test.
+ * gcc.dg/analyzer/named-constants-via-macros.c: New test.
+
+2022-11-15 Lewis Hyatt <lhyatt@gmail.com>
+
+ * c-c++-common/cpp/macro-trace-1.c: New test.
+
+2022-11-15 Martin Liska <mliska@suse.cz>
+
+ * c-c++-common/asan/global-overflow-1.c: Update
+ expected format.
+ * c-c++-common/asan/heap-overflow-1.c: Likewise.
+ * c-c++-common/asan/strlen-overflow-1.c: Likewise.
+ * c-c++-common/asan/strncpy-overflow-1.c: Likewise.
+ * c-c++-common/hwasan/heap-overflow.c: Likewise.
+ * g++.dg/asan/asan_mem_test.cc: Likewise.
+ * g++.dg/asan/asan_oob_test.cc: Likewise.
+ * g++.dg/asan/asan_str_test.cc: Likewise.
+ * g++.dg/asan/asan_test.cc: Likewise.
+ * g++.dg/asan/large-func-test-1.C: Likewise.
+
+2022-11-15 Patrick Palka <ppalka@redhat.com>
+
+ * g++.dg/template/crash55.C: Don't expect additional
+ C++98-specific diagnostics.
+ * g++.dg/template/ref3.C: Remove C++98-specific xfail.
+
+2022-11-15 Martin Liska <mliska@suse.cz>
+
+ Revert:
+ 2022-11-09 Martin Liska <mliska@suse.cz>
+
+ PR c++/107599
+ * c-c++-common/diagnostic-format-json-2.c: Fix expected URL.
+ * c-c++-common/diagnostic-format-json-3.c: Likewise.
+ * c-c++-common/diagnostic-format-json-4.c: Likewise.
+ * gfortran.dg/diagnostic-format-json-2.F90: Likewise.
+ * gfortran.dg/diagnostic-format-json-3.F90: Likewise.
+
+2022-11-15 Andre Vieira <andre.simoesdiasvieira@arm.com>
+
+ * gcc.target/aarch64/ldapr-ext.c: New test.
+
+2022-11-15 Andre Vieira <andre.simoesdiasvieira@arm.com>
+ Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/aarch64/ldapr.c: New test.
+
+2022-11-15 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/DRs/dr2392.C: Add testcase for DR 2392.
+
+2022-11-15 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/cpp23/subscript9.C: New test.
+ * g++.dg/cpp23/feat-cxx2b.C: Expect a newer
+ __cpp_multidimensional_subscript value.
+ * g++.old-deja/g++.bugs/900210_10.C: Don't expect an error
+ for C++23 or later.
+
+2022-11-15 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/DRs/dr2604.C: New test.
+
+2022-11-15 Hongyu Wang <hongyu.wang@intel.com>
+
+ PR target/98167
+ * gcc.target/i386/pr98167.c: New test.
+
+2022-11-15 Marek Polacek <polacek@redhat.com>
+
+ * g++.dg/cpp23/elision4.C: Remove dg-warning.
+ * g++.dg/warn/Wdangling-reference1.C: Turn dg-warning into dg-bogus.
+ * g++.dg/warn/Wdangling-reference7.C: New test.
+
+2022-11-14 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/cpp2a/concepts-friend11.C: New test.
+
+2022-11-14 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/aarch64/cssc_1.c: New test.
+ * gcc.target/aarch64/cssc_2.c: New test.
+ * gcc.target/aarch64/cssc_3.c: New test.
+ * gcc.target/aarch64/cssc_4.c: New test.
+ * gcc.target/aarch64/cssc_5.c: New test.
+
+2022-11-14 Tamar Christina <tamar.christina@arm.com>
+
+ * gcc.target/aarch64/sve2/div-by-bitmask_1.c: New test.
+
+2022-11-14 Tamar Christina <tamar.christina@arm.com>
+
+ * gcc.target/aarch64/div-by-bitmask.c: New test.
+
+2022-11-14 Tamar Christina <tamar.christina@arm.com>
+
+ * gcc.dg/vect/vect-div-bitmask-1.c: New test.
+ * gcc.dg/vect/vect-div-bitmask-2.c: New test.
+ * gcc.dg/vect/vect-div-bitmask-3.c: New test.
+ * gcc.dg/vect/vect-div-bitmask.h: New file.
+
+2022-11-14 Tamar Christina <tamar.christina@arm.com>
+
+ * gcc.target/aarch64/simd/addsub_1.c: New test.
+ * gcc.target/aarch64/sve/addsub_1.c: New test.
+
+2022-11-14 Srinath Parvathaneni <srinath.parvathaneni@arm.com>
+
+ * gcc.target/arm/multilib.exp: Add tests for Cortex-X1C.
+
+2022-11-14 Haochen Jiang <haochen.jiang@intel.com>
+
+ * gcc.target/i386/amxbf16-dpbf16ps-2.c: Remove -amx-tile.
+ * gcc.target/i386/amxfp16-dpfp16ps-2.c: Ditto.
+ * gcc.target/i386/amxint8-dpbssd-2.c: Ditto.
+ * gcc.target/i386/amxint8-dpbsud-2.c: Ditto.
+ * gcc.target/i386/amxint8-dpbusd-2.c: Ditto.
+ * gcc.target/i386/amxint8-dpbuud-2.c: Ditto.
+
+2022-11-14 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/pr107554.c: Restrict to lp64.
+
+2022-11-14 Hongyu Wang <hongyu.wang@intel.com>
+
+ * gcc.dg/guality/loop-1.c: Add additional option
+ -mno-unroll-only-small-loops.
+ * gcc.target/i386/pr86270.c: Add -mno-unroll-only-small-loops.
+ * gcc.target/i386/pr93002.c: Likewise.
+
+2022-11-13 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106235
+ * gcc.dg/analyzer/taint-assert-BUG_ON.c: New test.
+ * gcc.dg/analyzer/taint-assert-macro-expansion.c: New test.
+ * gcc.dg/analyzer/taint-assert.c: New test.
+ * gcc.dg/analyzer/taint-assert-system-header.c: New test.
+ * gcc.dg/analyzer/test-assert.h: New header.
+ * gcc.dg/plugin/analyzer_gil_plugin.c
+ (gil_diagnostic::fixup_location): Add bool param.
+
+2022-11-13 José Rui Faustino de Sousa <jrfsousa@gmail.com>
+
+ PR fortran/94104
+ * gfortran.dg/parens_2.f90: Adjust to improved error message.
+ * gfortran.dg/PR94104a.f90: New test.
+ * gfortran.dg/PR94104b.f90: New test.
+
+2022-11-13 John David Anglin <danglin@gcc.gnu.org>
+
+ * g++.dg/guality/guality.exp: Skip on hppa*-*-hpux*.
+ * gcc.dg/guality/guality.exp: Likewise.
+ * gfortran.dg/guality/guality.exp: Likewise.
+
+2022-11-13 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * gcc.target/riscv/zbb-srai-andn.c: New test.
+
+2022-11-13 Philipp Tomsich <philipp.tomsich@vrull.eu>
+
+ * gcc.target/riscv/zba-shNadd-07.c: New test.
+
+2022-11-13 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/c11-float-8.c, gcc.dg/c11-limits-1.c,
+ gcc.dg/c11-stdarg-4.c, gcc.dg/c11-stdatomic-3.c,
+ gcc.dg/c11-stddef-1.c, gcc.dg/c11-stdint-1.c,
+ gcc.dg/c2x-float-13.c, gcc.dg/c2x-limits-1.c,
+ gcc.dg/c2x-stdarg-5.c, gcc.dg/c2x-stdatomic-1.c,
+ gcc.dg/c2x-stddef-1.c, gcc.dg/c2x-stdint-1.c: New tests.
+
+2022-11-12 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107444
+ * gfortran.dg/optional_absent_7.f90: Adjust regex.
+ * gfortran.dg/optional_absent_8.f90: New test.
+
+2022-11-12 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/c11-keywords-1.c: Also test constexpr.
+ * gcc.dg/c2x-constexpr-1.c, gcc.dg/c2x-constexpr-2a.c,
+ gcc.dg/c2x-constexpr-2b.c, gcc.dg/c2x-constexpr-3.c,
+ gcc.dg/c2x-constexpr-4.c, gcc.dg/c2x-constexpr-5.c,
+ gcc.dg/c2x-constexpr-6.c, gcc.dg/c2x-constexpr-7.c,
+ gcc.dg/c2x-constexpr-8.c, gcc.dg/c2x-constexpr-9.c,
+ gcc.dg/dfp/c2x-constexpr-dfp-1.c,
+ gcc.dg/dfp/c2x-constexpr-dfp-2.c, gcc.dg/gnu2x-constexpr-1.c,
+ gcc.target/i386/excess-precision-11.c,
+ gcc.target/i386/excess-precision-12.c: New tests.
+
+2022-11-12 Aldy Hernandez <aldyh@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.c-torture/execute/ieee/inf-4.c: New test.
+
+2022-11-12 Xi Ruoyao <xry111@xry111.site>
+
+ * gcc.target/loongarch/flogb.c: New test.
+
+2022-11-12 Xi Ruoyao <xry111@xry111.site>
+
+ * gcc.target/loongarch/fscaleb.c: New test.
+
+2022-11-12 Xi Ruoyao <xry111@xry111.site>
+
+ * gcc.target/loongarch/ftint.c: New test.
+ * gcc.target/loongarch/ftint-no-inexact.c: New test.
+
+2022-11-12 Xi Ruoyao <xry111@xry111.site>
+
+ * gcc.target/loongarch/frint.c: New test.
+
+2022-11-11 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106147
+ * g++.dg/analyzer/infinite-recursion-1.C: New test.
+ * g++.dg/analyzer/infinite-recursion-2.C: New test, copied from
+ g++.dg/warn/Winfinite-recursion-2.C.
+ * g++.dg/analyzer/infinite-recursion-3.C: New test, adapted from
+ g++.dg/warn/Winfinite-recursion-3.C.
+ * gcc.dg/analyzer/infinite-recursion-2.c: New test.
+ * gcc.dg/analyzer/infinite-recursion-3.c: New test.
+ * gcc.dg/analyzer/infinite-recursion-4-limited-buggy.c: New test.
+ * gcc.dg/analyzer/infinite-recursion-4-limited.c: New test.
+ * gcc.dg/analyzer/infinite-recursion-4-unlimited-buggy.c: New test.
+ * gcc.dg/analyzer/infinite-recursion-4-unlimited.c: New test.
+ * gcc.dg/analyzer/infinite-recursion-5.c: New test, adapted from
+ gcc.dg/Winfinite-recursion.c.
+ * gcc.dg/analyzer/infinite-recursion-alloca.c: New test.
+ * gcc.dg/analyzer/infinite-recursion-inlining.c: New test.
+ * gcc.dg/analyzer/infinite-recursion-multiline-1.c: New test.
+ * gcc.dg/analyzer/infinite-recursion-multiline-2.c: New test.
+ * gcc.dg/analyzer/infinite-recursion-variadic.c: New test.
+ * gcc.dg/analyzer/infinite-recursion.c: Add dg-warning directives
+ where infinite recursions occur.
+ * gcc.dg/analyzer/malloc-ipa-12.c: Likewise.
+ * gcc.dg/analyzer/pr105365.c: Likewise.
+ * gcc.dg/analyzer/pr105366.c: Likewise.
+ * gcc.dg/analyzer/pr97029.c: Likewise.
+
+2022-11-11 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/107523
+ * gcc.dg/pr107523.c: New.
+
+2022-11-11 Richard Biener <rguenther@suse.de>
+ Nikita Voronov <nik_1357@mail.ru>
+
+ PR tree-optimization/107554
+ * gcc.dg/pr107554.c: New testcase.
+
+2022-11-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107618
+ * gcc.dg/pr107618.c: New testcase.
+
+2022-11-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/84646
+ * g++.dg/tree-ssa/pr106922.C: Continue to scan earlier DCE dump.
+ * gcc.dg/tree-ssa/20030808-1.c: Likewise.
+
+2022-11-11 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
+ Monk Chiang <monk.chiang@sifive.com>
+
+ * gcc.target/riscv/rvv/base/macro.h: New test.
+ * gcc.target/riscv/rvv/base/spill-1.c: New test.
+ * gcc.target/riscv/rvv/base/spill-10.c: New test.
+ * gcc.target/riscv/rvv/base/spill-11.c: New test.
+ * gcc.target/riscv/rvv/base/spill-12.c: New test.
+ * gcc.target/riscv/rvv/base/spill-2.c: New test.
+ * gcc.target/riscv/rvv/base/spill-3.c: New test.
+ * gcc.target/riscv/rvv/base/spill-4.c: New test.
+ * gcc.target/riscv/rvv/base/spill-5.c: New test.
+ * gcc.target/riscv/rvv/base/spill-6.c: New test.
+ * gcc.target/riscv/rvv/base/spill-7.c: New test.
+ * gcc.target/riscv/rvv/base/spill-8.c: New test.
+ * gcc.target/riscv/rvv/base/spill-9.c: New test.
+
+2022-11-11 Jonathan Wakely <jwakely@redhat.com>
+
+ PR c/85487
+ * c-c++-common/pragma-region.c: New test.
+
+2022-11-11 Haochen Jiang <haochen.jiang@intel.com>
+
+ * gcc.target/i386/prefetchi-5.c: New test.
+
+2022-11-10 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/analyzer/deref-before-check-1.c: New test.
+ * gcc.dg/analyzer/deref-before-check-2.c: New test.
+ * gcc.dg/analyzer/deref-before-check-pr77425.c: New test.
+ * gcc.dg/analyzer/malloc-1.c (test_51): New test.
+
+2022-11-10 Marek Polacek <polacek@redhat.com>
+
+ * g++.dg/warn/Wdangling-reference6.C: New test.
+
+2022-11-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/84646
+ * gcc.dg/tree-ssa/ssa-ccp-42.c: New testcase.
+
+2022-11-10 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/loop-unswitch-18.c: New testcase.
+ * gcc.dg/tree-ssa/loopclosedphi.c: Disable unswitching,
+ adjust expected counts.
+ * gcc.dg/torture/pr71462.c: Add -w to ignore undefined
+ behavior diagnostics after now unswitching outer loops.
+
+2022-11-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/107585
+ PR target/107546
+ * gcc.dg/pr107585.c: New test.
+
+2022-11-09 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107559
+ * gfortran.dg/pr107559.f90: New test.
+
+2022-11-09 Martin Liska <mliska@suse.cz>
+
+ PR c++/107599
+ * c-c++-common/diagnostic-format-json-2.c: Fix expected URL.
+ * c-c++-common/diagnostic-format-json-3.c: Likewise.
+ * c-c++-common/diagnostic-format-json-4.c: Likewise.
+ * gfortran.dg/diagnostic-format-json-2.F90: Likewise.
+ * gfortran.dg/diagnostic-format-json-3.F90: Likewise.
+
+2022-11-09 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/107441
+ * gfortran.dg/coarray/pr107441-caf.f90: New test.
+ * gfortran.dg/optional_absent_6.f90: New test.
+ * gfortran.dg/optional_absent_7.f90: New test.
+
+2022-11-09 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/guality/param-6.c: New test.
+
+2022-11-09 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/cpp0x/attr-carries_dependency1.C: New test.
+
+2022-11-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107541
+ * gcc.dg/tree-ssa/pr107541.c (c): Use long long type rather than long.
+ (main): Punt if sizeof short isn't 2, or int 4, or long long 8.
+
+2022-11-09 Marek Polacek <polacek@redhat.com>
+
+ PR c++/107363
+ * g++.dg/cpp0x/Wredundant-move13.C: New test.
+
+2022-11-09 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr107540.c: New test.
+
+2022-11-08 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/101962
+ * gcc.dg/analyzer/data-model-23.c (test_3): New test.
+
+2022-11-08 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/24021
+ * gcc.dg/tree-ssa/vrp-float-plus.c: New test.
+
+2022-11-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/107389
+ * gcc.dg/pr107389.c: New testcase.
+
+2022-11-08 Kwok Cheung Yeung <kcy@codesourcery.com>
+
+ * gcc.target/gcn/math-builtins-1.c: New test.
+
+2022-11-08 Surya Kumari Jangala <jskumari@linux.ibm.com>
+
+ PR testsuite/107171
+ * gcc.target/powerpc/pr105586.c: Guard against unsupported
+ __int128.
+
+2022-11-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/107547
+ * gcc.dg/pr107547.c: New test.
+
+2022-11-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/107546
+ * gcc.target/i386/pr107546.c: New test.
+
+2022-11-08 konglin1 <lingling.kong@intel.com>
+
+ Revert:
+ 2022-11-08 konglin1 <lingling.kong@intel.com>
+
+ * gcc.target/i386/raoint-atomic-fetch.c: New test.
+
+2022-11-08 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/analyzer/errno-1.c: New test.
+
+2022-11-08 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/analyzer/strchr-1.c (test_literal): Detect writing to a
+ string literal. Verify that we emit the "when '__builtin_strchr'
+ returns non-NULL" message.
+
+2022-11-08 Jason Merrill <jason@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/cpp2a/spaceship-eq15.C: New test.
+ * g++.dg/cpp0x/defaulted3.C: Add const.
+ * g++.dg/cpp2a/bit-cast7.C: Add const.
+ * g++.dg/cpp2a/spaceship-rewrite1.C: Expect error.
+ * g++.dg/cpp2a/spaceship-rewrite5.C: Expect error.
+ * g++.old-deja/g++.jason/byval2.C: Expect error.
+ * g++.old-deja/g++.other/overload13.C: Add const.
+
+2022-11-08 Andrew MacLeod <amacleod@redhat.com>
+
+ * gcc.dg/pr104530.c: New.
+
+2022-11-07 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/55157
+ * gcc.dg/tree-ssa/pr55157.c: New test.
+
+2022-11-07 H.J. Lu <hjl.tools@gmail.com>
+
+ PR middle-end/102566
+ * g++.target/i386/pr102566-7.C
+
+2022-11-07 Nathan Sidwell <nathan@acm.org>
+
+ * g++.dg/abi/lambda-tpl1.h: Add more cases.
+ * g++.dg/abi/lambda-tpl1-17.C: Add checks.
+ * g++.dg/abi/lambda-tpl1-18.C: Likewise.
+ * g++.dg/abi/lambda-tpl1-18vs17.C: Likewise.
+
+2022-11-07 Alexander Monakov <amonakov@ispras.ru>
+
+ PR tree-optimization/107505
+ * gcc.dg/pr107505.c: New test.
+
+2022-11-07 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/107541
+ * gcc.dg/tree-ssa/pr107541.c: New test.
+
+2022-11-07 Tobias Burnus <tobias@codesourcery.com>
+
+ PR fortran/107508
+ * gfortran.dg/widechar_11.f90: New test.
+
+2022-11-07 konglin1 <lingling.kong@intel.com>
+
+ * gcc.target/i386/sse-22.c: Fix typo in pragma GCC target.
+
+2022-11-07 Kewen Lin <linkw@linux.ibm.com>
+
+ PR tree-optimization/107412
+ * gcc.target/powerpc/pr107412.c: New test.
+ * gcc.target/powerpc/p9-vec-length-epil-8.c: Adjust scan times for
+ folded LEN_LOAD.
+
+2022-11-07 Hu, Lin1 <lin1.hu@intel.com>
+
+ * g++.target/i386/mv16.C: Add grandridge.
+ * gcc.target/i386/funcspec-56.inc: Handle new march.
+
+2022-11-07 konglin1 <lingling.kong@intel.com>
+
+ * gcc.target/i386/raoint-atomic-fetch.c: New test.
+
+2022-11-07 konglin1 <lingling.kong@intel.com>
+
+ * g++.dg/other/i386-2.C: Add -mraoint.
+ * g++.dg/other/i386-3.C: Ditto.
+ * gcc.target/i386/funcspec-56.inc: Add new target attribute.
+ * gcc.target/i386/sse-12.c: Add -mraoint.
+ * gcc.target/i386/sse-13.c: Ditto.
+ * gcc.target/i386/sse-14.c: Ditto.
+ * gcc.target/i386/sse-22.c: Add raoint target.
+ * gcc.target/i386/sse-23.c: Ditto.
+ * lib/target-supports.exp: Add check_effective_target_raoint.
+ * gcc.target/i386/rao-helper.h: New test.
+ * gcc.target/i386/raoint-1.c: Ditto.
+ * gcc.target/i386/raoint-aadd-2.c: Ditto.
+ * gcc.target/i386/raoint-aand-2.c: Ditto.
+ * gcc.target/i386/raoint-aor-2.c: Ditto.
+ * gcc.target/i386/raoint-axor-2.c: Ditto.
+ * gcc.target/i386/x86gprintrin-1.c: Ditto.
+ * gcc.target/i386/x86gprintrin-2.c: Ditto.
+ * gcc.target/i386/x86gprintrin-3.c: Ditto.
+ * gcc.target/i386/x86gprintrin-4.c: Ditto.
+ * gcc.target/i386/x86gprintrin-5.c: Ditto.
+
+2022-11-07 Haochen Jiang <haochen.jiang@intel.com>
+
+ * g++.target/i386/mv16.C: Add graniterapids.
+ * gcc.target/i386/funcspec-56.inc: Handle new march.
+
+2022-11-07 Haochen Jiang <haochen.jiang@intel.com>
+ Hongtao Liu <hongtao.liu@intel.com>
+
+ * g++.dg/other/i386-2.C: Add -mprefetchi.
+ * g++.dg/other/i386-3.C: Ditto.
+ * gcc.target/i386/avx-1.c: Ditto.
+ * gcc.target/i386/funcspec-56.inc: Add new target attribute.
+ * gcc.target/i386/sse-13.c: Add -mprefetchi.
+ * gcc.target/i386/sse-23.c: Ditto.
+ * gcc.target/i386/x86gprintrin-1.c: Ditto.
+ * gcc.target/i386/x86gprintrin-2.c: Ditto.
+ * gcc.target/i386/x86gprintrin-3.c: Ditto.
+ * gcc.target/i386/x86gprintrin-4.c: Ditto.
+ * gcc.target/i386/x86gprintrin-5.c: Ditto.
+ * gcc.target/i386/prefetchi-1.c: New test.
+ * gcc.target/i386/prefetchi-2.c: Ditto.
+ * gcc.target/i386/prefetchi-3.c: Ditto.
+ * gcc.target/i386/prefetchi-4.c: Ditto.
+
+2022-11-06 Patrick Palka <ppalka@redhat.com>
+
+ * g++.dg/special/initpri3.C: New test.
+
+2022-11-06 Xi Ruoyao <xry111@xry111.site>
+
+ * gcc.target/loongarch/fcopysign.c: New test.
+
+2022-11-05 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * gdc.dg/attr_register2.d: Adjust test.
+
+2022-11-05 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * gdc.dg/Wbuiltin_declaration_mismatch2.d: Remove comparision tests.
+ * gdc.dg/simd2a.d: Update comparison tests.
+ * gdc.dg/simd2b.d: Likewise.
+ * gdc.dg/simd2c.d: Likewise.
+ * gdc.dg/simd2d.d: Likewise.
+ * gdc.dg/simd2e.d: Likewise.
+ * gdc.dg/simd2f.d: Likewise.
+ * gdc.dg/simd2g.d: Likewise.
+ * gdc.dg/simd2h.d: Likewise.
+ * gdc.dg/simd2i.d: Likewise.
+ * gdc.dg/simd2j.d: Likewise.
+
+2022-11-05 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR preprocessor/55971
+ * c-c++-common/raw-string-directive-1.c: New test.
+ * c-c++-common/raw-string-directive-2.c: New test.
+
+2022-11-04 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/cpp23/charset1.C: New testcase from C++23 P2314R4.
+
+2022-11-04 Jakub Jelinek <jakub@redhat.com>
+
+ * c-c++-common/cpp/named-universal-char-escape-1.c: Add tests for some
+ characters newly added in Unicode 15.0.0.
+
+2022-11-04 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * gcc.target/aarch64/mgeneral-regs_3.c: Fix testcase.
+
+2022-11-04 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/107342
+ * gcc.dg/tree-ssa/vrp122.c: New test.
+ * gcc.dg/tree-ssa/vrp123.c: New test.
+
+2022-11-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/opt99.adb: New test.
+ * gnat.dg/opt99_pkg1.ads, gnat.dg/opt99_pkg1.adb: New helper.
+ * gnat.dg/opt99_pkg2.ads: Likewise.
+
+2022-11-04 Javier Miranda <miranda@adacore.com>
+
+ * gnat.dg/abstract1.ads: Cleanup whitespaces.
+ * gnat.dg/abstract1.adb: Likewise and add -gnatws to silence new
+ warning.
+
+2022-11-04 Hongyu Wang <hongyu.wang@intel.com>
+ Haochen Jiang <haochen.jiang@intel.com>
+
+ * g++.dg/other/i386-2.C: Add -mamx-fp16.
+ * g++.dg/other/i386-3.C: Ditto.
+ * gcc.target/i386/sse-12.c: Ditto.
+ * gcc.target/i386/sse-13.c: Ditto.
+ * gcc.target/i386/sse-14.c: Ditto.
+ * gcc.target/i386/sse-22.c: Ditto.
+ * gcc.target/i386/sse-23.c: Ditto.
+ * lib/target-supports.exp: (check_effective_target_amx_fp16):
+ New proc.
+ * gcc.target/i386/funcspec-56.inc: Add new target attribute.
+ * gcc.target/i386/amx-check.h: Add AMX_FP16.
+ * gcc.target/i386/amx-helper.h: New file to support amx-fp16.
+ * gcc.target/i386/amxfp16-asmatt-1.c: New test.
+ * gcc.target/i386/amxfp16-asmintel-1.c: Ditto.
+ * gcc.target/i386/amxfp16-dpfp16ps-2.c: Ditto.
+
+2022-11-04 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
+
+ * gcc.target/arm/cmse/bitfield-1.c: Use overridable location.
+ * gcc.target/arm/cmse/bitfield-2.c: Likewise.
+ * gcc.target/arm/cmse/bitfield-3.c: Likewise.
+ * gcc.target/arm/cmse/cmse-20.c: Likewise.
+ * gcc.target/arm/cmse/struct-1.c: Likewise.
+ * gcc.target/arm/cmse/cmse.exp (cmse_sgstubs): New.
+
+2022-11-04 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
+ Yvan ROUX <yvan.roux@foss.st.com>
+
+ * g++.dg/modules/bad-mapper-3.C: Update dg-error pattern.
+
+2022-11-04 Haochen Jiang <haochen.jiang@intel.com>
+
+ * g++.target/i386/mv16.C: Add sierra forest.
+ * gcc.target/i386/funcspec-56.inc: Handle new march.
+
+2022-11-04 Haochen Jiang <haochen.jiang@intel.com>
+
+ * g++.dg/other/i386-2.C: Add -mcmpccxadd.
+ * g++.dg/other/i386-3.C: Ditto.
+ * gcc.target/i386/avx-1.c: Ditto.
+ * gcc.target/i386/funcspec-56.inc: Add new target attribute.
+ * gcc.target/i386/sse-13.c: Add -mcmpccxadd.
+ * gcc.target/i386/sse-23.c: Ditto.
+ * gcc.target/i386/x86gprintrin-1.c: Ditto.
+ * gcc.target/i386/x86gprintrin-2.c: Ditto.
+ * gcc.target/i386/x86gprintrin-3.c: Ditto.
+ * gcc.target/i386/x86gprintrin-4.c: Ditto.
+ * gcc.target/i386/x86gprintrin-5.c: Ditto.
+ * lib/target-supports.exp (check_effective_target_cmpccxadd):
+ New.
+ * gcc.target/i386/cmpccxadd-1.c: New test.
+ * gcc.target/i386/cmpccxadd-2.c: Ditto.
+
+2022-11-03 Marek Polacek <polacek@redhat.com>
+
+ PR c++/107488
+ * g++.dg/warn/Wdangling-reference5.C: New test.
+
+2022-11-03 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/107179
+ * g++.dg/cpp2a/concepts-requires31.C: New test.
+
+2022-11-03 Andrew MacLeod <amacleod@redhat.com>
+
+ * g++.dg/pr99966.C: New.
+ * gcc.dg/pr93917.c: New.
+ * gcc.dg/pr102650.c: New.
+
+2022-11-03 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/concepts/auto1.C:
+ * g++.dg/concepts/auto3.C:
+ * g++.dg/concepts/auto4.C:
+ * g++.dg/concepts/class-deduction1.C:
+ * g++.dg/concepts/class5.C:
+ * g++.dg/concepts/class6.C:
+ * g++.dg/concepts/debug1.C:
+ * g++.dg/concepts/decl-diagnose.C:
+ * g++.dg/concepts/deduction-constraint1.C:
+ * g++.dg/concepts/diagnostic1.C:
+ * g++.dg/concepts/dr1430.C:
+ * g++.dg/concepts/equiv.C:
+ * g++.dg/concepts/equiv2.C:
+ * g++.dg/concepts/expression.C:
+ * g++.dg/concepts/expression2.C:
+ * g++.dg/concepts/expression3.C:
+ * g++.dg/concepts/fn-concept1.C:
+ * g++.dg/concepts/fn-concept2.C:
+ * g++.dg/concepts/fn-concept3.C:
+ * g++.dg/concepts/fn1.C:
+ * g++.dg/concepts/fn10.C:
+ * g++.dg/concepts/fn2.C:
+ * g++.dg/concepts/fn3.C:
+ * g++.dg/concepts/fn4.C:
+ * g++.dg/concepts/fn5.C:
+ * g++.dg/concepts/fn6.C:
+ * g++.dg/concepts/fn8.C:
+ * g++.dg/concepts/fn9.C:
+ * g++.dg/concepts/generic-fn-err.C:
+ * g++.dg/concepts/generic-fn.C:
+ * g++.dg/concepts/inherit-ctor1.C:
+ * g++.dg/concepts/inherit-ctor3.C:
+ * g++.dg/concepts/intro1.C:
+ * g++.dg/concepts/intro2.C:
+ * g++.dg/concepts/intro3.C:
+ * g++.dg/concepts/intro4.C:
+ * g++.dg/concepts/intro5.C:
+ * g++.dg/concepts/intro6.C:
+ * g++.dg/concepts/intro7.C:
+ * g++.dg/concepts/locations1.C:
+ * g++.dg/concepts/partial-concept-id1.C:
+ * g++.dg/concepts/partial-concept-id2.C:
+ * g++.dg/concepts/partial-spec5.C:
+ * g++.dg/concepts/placeholder2.C:
+ * g++.dg/concepts/placeholder3.C:
+ * g++.dg/concepts/placeholder4.C:
+ * g++.dg/concepts/placeholder5.C:
+ * g++.dg/concepts/placeholder6.C:
+ * g++.dg/concepts/pr65634.C:
+ * g++.dg/concepts/pr65636.C:
+ * g++.dg/concepts/pr65681.C:
+ * g++.dg/concepts/pr65848.C:
+ * g++.dg/concepts/pr67249.C:
+ * g++.dg/concepts/pr67595.C:
+ * g++.dg/concepts/pr68434.C:
+ * g++.dg/concepts/pr71127.C:
+ * g++.dg/concepts/pr71128.C:
+ * g++.dg/concepts/pr71131.C:
+ * g++.dg/concepts/pr71385.C:
+ * g++.dg/concepts/pr85065.C:
+ * g++.dg/concepts/template-parm11.C:
+ * g++.dg/concepts/template-parm12.C:
+ * g++.dg/concepts/template-parm2.C:
+ * g++.dg/concepts/template-parm3.C:
+ * g++.dg/concepts/template-parm4.C:
+ * g++.dg/concepts/template-template-parm1.C:
+ * g++.dg/concepts/var-concept1.C:
+ * g++.dg/concepts/var-concept2.C:
+ * g++.dg/concepts/var-concept3.C:
+ * g++.dg/concepts/var-concept4.C:
+ * g++.dg/concepts/var-concept5.C:
+ * g++.dg/concepts/var-concept6.C:
+ * g++.dg/concepts/var-concept7.C:
+ * g++.dg/concepts/var-templ2.C:
+ * g++.dg/concepts/var-templ3.C:
+ * g++.dg/concepts/variadic1.C:
+ * g++.dg/concepts/variadic2.C:
+ * g++.dg/concepts/variadic3.C:
+ * g++.dg/concepts/variadic4.C:
+ * g++.dg/cpp2a/concepts-pr65575.C:
+ * g++.dg/cpp2a/concepts-pr66091.C:
+ * g++.dg/cpp2a/concepts-pr84980.C:
+ * g++.dg/cpp2a/concepts-pr85265.C: Pass -fconcepts-ts.
+ * g++.dg/cpp2a/concepts-pr84979-2.C:
+ * g++.dg/cpp2a/concepts-pr84979-3.C: Same diagnostics
+ in C++20 and below.
+
+2022-11-03 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/93413
+ * g++.dg/cpp2a/constexpr-virtual21.C: New test.
+
+2022-11-03 Kwok Cheung Yeung <kcy@codesourcery.com>
+
+ * gcc.target/gcn/unsafe-math-1.c: New.
+
+2022-11-03 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/plugin/analyzer_gil_plugin.c: Use std::unique_ptr for
+ state machines from plugins.
+
+2022-11-03 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/plugin/analyzer_kernel_plugin.c: Use std::unique_ptr for
+ known functions.
+ * gcc.dg/plugin/analyzer_known_fns_plugin.c: Likewise.
+
+2022-11-03 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/plugin/analyzer_kernel_plugin.c: Include "make-unique.h".
+ Use std::unique_ptr in bifurcation code.
+ * gcc.dg/plugin/analyzer_known_fns_plugin.c: Likewise.
+
+2022-11-03 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/plugin/analyzer_gil_plugin.c: Add define of
+ INCLUDE_MEMORY. Include "make-unique.h".
+ (gil_state_machine::check_for_pyobject_in_call): Use make_unique
+ when creating pending_diagnostic.
+ (gil_state_machine::on_stmt): Likewise.
+ (gil_state_machine::check_for_pyobject_usage_without_gil): Likewise.
+ * gcc.dg/plugin/analyzer_kernel_plugin.c: : Add define of
+ INCLUDE_MEMORY.
+ * gcc.dg/plugin/analyzer_known_fns_plugin.c: Likewise.
+
+2022-11-03 Andrew MacLeod <amacleod@redhat.com>
+
+ * gcc.dg/tree-ssa/vrp-update.c: New.
+
+2022-11-03 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/107486
+ * gcc.dg/analyzer/pipe-pr107486.c: New test.
+ * gcc.dg/analyzer/pipe-void-return.c: New test.
+
+2022-11-03 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/107404
+ * g++.target/i386/pr107404.C: New test.
+
+2022-11-03 Kewen Lin <linkw@linux.ibm.com>
+
+ PR testsuite/106806
+ * gcc.dg/tree-ssa/gen-vect-34.c: Adjust with vect_masked_load
+ effective target.
+
+2022-11-03 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/c2x-auto-1.c, gcc.dg/c2x-auto-2.c, gcc.dg/c2x-auto-3.c,
+ gcc.dg/c2x-auto-4.c, gcc.dg/gnu2x-auto-1.c: New tests.
+
+2022-11-02 Christoph Müllner <christoph.muellner@vrull.eu>
+
+ * gcc.target/riscv/zawrs.c: New test.
+
+2022-11-02 Xionghu Luo <xionghuluo@tencent.com>
+
+ PR target/100866
+ * gcc.target/powerpc/pr100866-2.c: New.
+
+2022-11-01 Nathan Sidwell <nathan@acm.org>
+
+ * g++.dg/abi/lambda-sig1-18.C: New.
+ * g++.dg/abi/lambda-sig1-18vs17.C: New.
+ * g++.dg/cpp1y/lambda-mangle-1-18.C: New.
+
+2022-11-01 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/107490
+ * gcc.dg/tree-ssa/pr107490.c: New test.
+
+2022-11-01 Andrew MacLeod <amacleod@redhat.com>
+
+ * gcc.dg/pr68217.c: Test [-INF, -INF][0, 0] instead of [-INF, 0].
+ * gcc.dg/tree-ssa/vrp-unreachable.c: New. Test unreachable removal.
+
+2022-11-01 Nathan Sidwell <nathan@acm.org>
+
+ * g++.dg/abi/lambda-sig1-17.C: New.
+ * g++.dg/abi/lambda-sig1.h: New.
+ * g++.dg/cpp1y/lambda-mangle-1.C: Extracted to ...
+ * g++.dg/cpp1y/lambda-mangle-1.h: ... here.
+ * g++.dg/cpp1y/lambda-mangle-1-11.C: New
+ * g++.dg/cpp1y/lambda-mangle-1-17.C
+
+2022-11-01 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr107057.c: New test.
+
+2022-11-01 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr55583.c: New test.
+
+2022-11-01 Cui,Lili <lili.cui@intel.com>
+
+ * gcc.dg/ipa/inlinehint-6.c: New test.
+
2022-10-31 Jakub Jelinek <jakub@redhat.com>
* g++.dg/cpp23/ext-floating12.C: New test.
@@ -531,7 +4686,7 @@
* g++.dg/cpp2a/concepts-friend10.C: New test.
2022-10-20 Artem Klimov <jakmobius@gmail.com>
- Alexander Monakov <amonakov@gcc.gnu.org>
+ Alexander Monakov <amonakov@gcc.gnu.org>
PR middle-end/99619
* gcc.dg/tls/vis-attr-gd.c: New test.
@@ -2247,7 +6402,7 @@
PR target/95720
* lib/g++.exp: Moved gluefile block to after flags have been
- prefixed for the target_compile call.
+ prefixed for the target_compile call.
* lib/gcc.exp: Likewise.
* lib/wrapper.exp: Reset adjusted state flag.
@@ -2747,7 +6902,7 @@
2022-09-02 Martin Liska <mliska@suse.cz>
* lib/gcc-dg.exp: Remove -gstabs option support, DBX-related
- macros and DBX debugging info support.
+ macros and DBX debugging info support.
* lib/gfortran-dg.exp: Likewise.
* lib/target-supports.exp: Likewise.
* g++.dg/cpp0x/alias-decl-debug-0.C: Removed.
@@ -6671,8 +10826,8 @@
Manolis Tsamis <manolis.tsamis@vrull.eu>
* gcc.dg/pr90838.c: Add additional flags (dg-additional-options)
- when compiling for riscv64 and subsume gcc.target/aarch64/pr90838.c
- and gcc.target/i386/pr95863-2.c.
+ when compiling for riscv64 and subsume gcc.target/aarch64/pr90838.c
+ and gcc.target/i386/pr95863-2.c.
* gcc.target/aarch64/pr90838.c: Removed.
* gcc.target/i386/pr95863-2.c: Removed.
* lib/target-supports.exp: Recognize RV32 or RV64 via XLEN
@@ -8308,7 +12463,7 @@
2022-04-05 Robin Dapp <rdapp@linux.ibm.com>
* gcc.target/s390/zvector/vec-double-compile.c: Expect vl
- instead of vc*.
+ instead of vc*.
* gcc.target/s390/zvector/vec-float-compile.c: Dito.
* gcc.target/s390/zvector/vec-signed-compile.c: Dito.
* gcc.target/s390/zvector/vec-unsigned-compile.c: Dito.
diff --git a/gcc/testsuite/c-c++-common/asan/global-overflow-1.c b/gcc/testsuite/c-c++-common/asan/global-overflow-1.c
index ec41223..b97801d 100644
--- a/gcc/testsuite/c-c++-common/asan/global-overflow-1.c
+++ b/gcc/testsuite/c-c++-common/asan/global-overflow-1.c
@@ -25,5 +25,5 @@ int main() {
/* { dg-skip-if "inaccurate debug info" { mips*-*-* } { "*" } { "-O0" } } */
/* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */
/* { dg-output " #0 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*global-overflow-1.c:20|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r).*" } */
-/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of global variable" } */
+/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes after global variable" } */
/* { dg-output ".*YYY\[^\n\r]* of size 10\[^\n\r]*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c
index 7ef048e..7d87448 100644
--- a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c
+++ b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c
@@ -25,7 +25,7 @@ int main(int argc, char **argv) {
/* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */
/* { dg-output " #0 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*heap-overflow-1.c:21|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\]).*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes after 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output " #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output " #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*heap-overflow-1.c:19|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/asan/pr106558.c b/gcc/testsuite/c-c++-common/asan/pr106558.c
new file mode 100644
index 0000000..d82b2dc
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr106558.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-w -fpermissive" } */
+/* { dg-shouldfail "asan" } */
+
+int a;
+int *b = &a;
+int **c = &b;
+int d[1];
+int *e = &d[1];
+
+static int f(int *g) {
+ *b = e;
+ *c = e;
+ *b = 2;
+ *g = 2;
+}
+
+int main() {
+ f(b);
+ return *b;
+}
+
+/* { dg-output "AddressSanitizer: global-buffer-overflow on address" } */
diff --git a/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c b/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c
index 86a79fd..34c20c8 100644
--- a/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c
+++ b/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c
@@ -21,4 +21,4 @@ int main () {
/* { dg-output "READ of size 2 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */
/* { dg-output " #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*strlen-overflow-1.c:19|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of global variable" } */
+/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes after global variable" } */
diff --git a/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c
index 3d43916..8342847 100644
--- a/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c
+++ b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c
@@ -16,7 +16,7 @@ int main(int argc, char **argv) {
/* { dg-output "WRITE of size \[0-9\]* at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output " #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)strncpy|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output " #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*strncpy-overflow-1.c:12|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\]).*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes after 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output " #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output " #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*strncpy-overflow-1.c:11|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-1.c b/gcc/testsuite/c-c++-common/auto-init-1.c
index df04358..3e6a498 100644
--- a/gcc/testsuite/c-c++-common/auto-init-1.c
+++ b/gcc/testsuite/c-c++-common/auto-init-1.c
@@ -1,6 +1,6 @@
/* Verify zero initialization for integer and pointer type automatic variables. */
/* { dg-do compile { target { ilp32 || lp64 } } } */
-/* { dg-options "-ftrivial-auto-var-init=zero -fdump-tree-gimple" } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fno-short-enums -fdump-tree-gimple" } */
#ifndef __cplusplus
# define bool _Bool
diff --git a/gcc/testsuite/c-c++-common/auto-init-2.c b/gcc/testsuite/c-c++-common/auto-init-2.c
index 6ac63bb..d356e50 100644
--- a/gcc/testsuite/c-c++-common/auto-init-2.c
+++ b/gcc/testsuite/c-c++-common/auto-init-2.c
@@ -1,6 +1,6 @@
/* Verify pattern initialization for integer and pointer type automatic variables. */
/* { dg-do compile { target { ilp32 || lp64 } } } */
-/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-tree-gimple" } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fno-short-enums -fdump-tree-gimple" } */
#ifndef __cplusplus
# define bool _Bool
diff --git a/gcc/testsuite/c-c++-common/cpp/macro-trace-1.c b/gcc/testsuite/c-c++-common/cpp/macro-trace-1.c
new file mode 100644
index 0000000..34cfbb3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/macro-trace-1.c
@@ -0,0 +1,4 @@
+/* This token is long enough to require an ad-hoc location. Make sure that
+ the macro trace still prints properly. */
+#define X "0123456789012345678901234567689" /* { dg-error {expected .* before string constant} } */
+X /* { dg-note {in expansion of macro 'X'} } */
diff --git a/gcc/testsuite/c-c++-common/cpp/named-universal-char-escape-1.c b/gcc/testsuite/c-c++-common/cpp/named-universal-char-escape-1.c
index 3c692f45..054eb50 100644
--- a/gcc/testsuite/c-c++-common/cpp/named-universal-char-escape-1.c
+++ b/gcc/testsuite/c-c++-common/cpp/named-universal-char-escape-1.c
@@ -117,6 +117,27 @@ typedef __CHAR32_TYPE__ char32_t;
|| U'\u0FD0' != U'\N{TIBETAN MARK BSKA- SHOG GI MGO RGYAN}' \
|| U'\uFE18' != U'\N{PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET}' \
|| U'\uFE18' != U'\N{PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRACKET}' \
+ || U'\u0CF3' != U'\N{KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT}' \
+ || U'\u0ECE' != U'\N{LAO YAMAKKAN}' \
+ || U'\U00010EFE' != U'\N{ARABIC SMALL LOW WORD QASR}' \
+ || U'\U00011241' != U'\N{KHOJKI VOWEL SIGN VOCALIC R}' \
+ || U'\U00011B06' != U'\N{DEVANAGARI SIGN WESTERN FIVE-LIKE BHALE}' \
+ || U'\U00011F0B' != U'\N{KAWI LETTER VOCALIC RR}' \
+ || U'\U0001342F' != U'\N{EGYPTIAN HIEROGLYPH V011D}' \
+ || U'\U00013451' != U'\N{EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT START AND BOTTOM}' \
+ || U'\U0001B132' != U'\N{HIRAGANA LETTER SMALL KO}' \
+ || U'\U0001B155' != U'\N{KATAKANA LETTER SMALL KO}' \
+ || U'\U0001D2C4' != U'\N{KAKTOVIK NUMERAL FOUR}' \
+ || U'\U0001DF27' != U'\N{LATIN SMALL LETTER N WITH MID-HEIGHT LEFT HOOK}' \
+ || U'\U0001E036' != U'\N{MODIFIER LETTER CYRILLIC SMALL ZHE}' \
+ || U'\U0001E05B' != U'\N{CYRILLIC SUBSCRIPT SMALL LETTER EL}' \
+ || U'\U0001E4E5' != U'\N{NAG MUNDARI LETTER ENN}' \
+ || U'\U0001F6DC' != U'\N{WIRELESS}' \
+ || U'\U0001F77E' != U'\N{QUAOAR}' \
+ || U'\U0001F7D9' != U'\N{NINE POINTED WHITE STAR}' \
+ || U'\U0001FA76' != U'\N{GREY HEART}' \
+ || U'\U0001FA88' != U'\N{FLUTE}' \
+ || U'\U0001FABC' != U'\N{JELLYFISH}' \
|| U'\uAC00' != U'\N{HANGUL SYLLABLE GA}' \
|| U'\uAC02' != U'\N{HANGUL SYLLABLE GAGG}' \
|| U'\uAD8D' != U'\N{HANGUL SYLLABLE GWEONJ}' \
@@ -134,6 +155,7 @@ typedef __CHAR32_TYPE__ char32_t;
|| U'\U0002A6DD' != U'\N{CJK UNIFIED IDEOGRAPH-2A6DD}' \
|| U'\U00020700' != U'\N{CJK UNIFIED IDEOGRAPH-20700}' \
|| U'\U0002B734' != U'\N{CJK UNIFIED IDEOGRAPH-2B734}' \
+ || U'\U0002B739' != U'\N{CJK UNIFIED IDEOGRAPH-2B739}' \
|| U'\U0002B740' != U'\N{CJK UNIFIED IDEOGRAPH-2B740}' \
|| U'\U0002B81D' != U'\N{CJK UNIFIED IDEOGRAPH-2B81D}' \
|| U'\U0002B820' != U'\N{CJK UNIFIED IDEOGRAPH-2B820}' \
@@ -142,6 +164,8 @@ typedef __CHAR32_TYPE__ char32_t;
|| U'\U0002EBE0' != U'\N{CJK UNIFIED IDEOGRAPH-2EBE0}' \
|| U'\U00030000' != U'\N{CJK UNIFIED IDEOGRAPH-30000}' \
|| U'\U0003134A' != U'\N{CJK UNIFIED IDEOGRAPH-3134A}' \
+ || U'\U00031350' != U'\N{CJK UNIFIED IDEOGRAPH-31350}' \
+ || U'\U000323AF' != U'\N{CJK UNIFIED IDEOGRAPH-323AF}' \
|| U'\U00017000' != U'\N{TANGUT IDEOGRAPH-17000}' \
|| U'\U000187F7' != U'\N{TANGUT IDEOGRAPH-187F7}' \
|| U'\U00018D00' != U'\N{TANGUT IDEOGRAPH-18D00}' \
diff --git a/gcc/testsuite/c-c++-common/gomp/pragma-omp-unknown.c b/gcc/testsuite/c-c++-common/gomp/pragma-omp-unknown.c
new file mode 100644
index 0000000..04881f7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pragma-omp-unknown.c
@@ -0,0 +1,10 @@
+/* { dg-do preprocess } */
+/* { dg-options "-fopenmp" } */
+
+#define X UNKNOWN1
+#pragma omp X
+/* { dg-final { scan-file pragma-omp-unknown.i "#pragma omp UNKNOWN1" } } */
+
+#define Y UNKNOWN2
+_Pragma("omp Y")
+/* { dg-final { scan-file pragma-omp-unknown.i "#pragma omp UNKNOWN2" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/target-teams-1.c b/gcc/testsuite/c-c++-common/gomp/target-teams-1.c
index 51b8d48..74d60e1 100644
--- a/gcc/testsuite/c-c++-common/gomp/target-teams-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/target-teams-1.c
@@ -81,5 +81,5 @@ foo (int a, int b, long c, long d)
/* { dg-final { scan-tree-dump-times "thread_limit\\(-1\\)" 3 "gimple" } } */
/* { dg-final { scan-tree-dump-times "num_teams\\(0\\)" 4 "gimple" } } */
/* { dg-final { scan-tree-dump-times "thread_limit\\(0\\)" 6 "gimple" } } */
-/* { dg-final { scan-tree-dump-times "num_teams\\(1\\)" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "num_teams\\(-2\\)" 2 "gimple" } } */
/* { dg-final { scan-tree-dump-times "thread_limit\\(1\\)" 0 "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/heap-overflow.c b/gcc/testsuite/c-c++-common/hwasan/heap-overflow.c
index bddb38c..a5a3771 100644
--- a/gcc/testsuite/c-c++-common/hwasan/heap-overflow.c
+++ b/gcc/testsuite/c-c++-common/hwasan/heap-overflow.c
@@ -24,6 +24,6 @@ int main(int argc, char **argv) {
/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
/* { dg-output "READ of size 1 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\].* \\(ptr/mem\\) in thread T0.*" } */
-/* { dg-output "located 0 bytes to the right of 10-byte region.*" } */
+/* { dg-output "located 0 bytes after 10-byte region.*" } */
/* { dg-output "allocated here:.*" } */
/* { dg-output "#1 0x\[0-9a-f\]+ +in _*main \[^\n\r]*heap-overflow.c:18" } */
diff --git a/gcc/testsuite/c-c++-common/pr57371-4.c b/gcc/testsuite/c-c++-common/pr57371-4.c
index d938ecd..f43f7c2 100644
--- a/gcc/testsuite/c-c++-common/pr57371-4.c
+++ b/gcc/testsuite/c-c++-common/pr57371-4.c
@@ -13,25 +13,25 @@ void nonfinite(unsigned short x) {
{
volatile int nonfinite_1;
nonfinite_1 = (float) x > QNAN;
- /* { dg-final { scan-tree-dump "nonfinite_1 = 0" "original" } } */
+ /* { dg-final { scan-tree-dump "nonfinite_1 = \\(float\\)" "original" } } */
}
{
volatile int nonfinite_2;
nonfinite_2 = (float) x >= QNAN;
- /* { dg-final { scan-tree-dump "nonfinite_2 = 0" "original" } } */
+ /* { dg-final { scan-tree-dump "nonfinite_2 = \\(float\\)" "original" } } */
}
{
volatile int nonfinite_3;
nonfinite_3 = (float) x < QNAN;
- /* { dg-final { scan-tree-dump "nonfinite_3 = 0" "original" } } */
+ /* { dg-final { scan-tree-dump "nonfinite_3 = \\(float\\)" "original" } } */
}
{
volatile int nonfinite_4;
nonfinite_4 = (float) x <= QNAN;
- /* { dg-final { scan-tree-dump "nonfinite_4 = 0" "original" } } */
+ /* { dg-final { scan-tree-dump "nonfinite_4 = \\(float\\)" "original" } } */
}
{
diff --git a/gcc/testsuite/c-c++-common/pr57371-5.c b/gcc/testsuite/c-c++-common/pr57371-5.c
new file mode 100644
index 0000000..8e18b0a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr57371-5.c
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fno-signaling-nans -fno-trapping-math -fdump-tree-original" } */
+
+/* We can not get rid of comparison in tests below because of
+ pending NaN exceptions.
+
+ TODO: avoid under -fno-trapping-math. */
+
+#define QNAN __builtin_nanf ("0")
+
+void nonfinite(unsigned short x) {
+ {
+ volatile int nonfinite_1;
+ nonfinite_1 = (float) x > QNAN;
+ /* { dg-final { scan-tree-dump "nonfinite_1 = 0" "original" } } */
+ }
+
+ {
+ volatile int nonfinite_2;
+ nonfinite_2 = (float) x >= QNAN;
+ /* { dg-final { scan-tree-dump "nonfinite_2 = 0" "original" } } */
+ }
+
+ {
+ volatile int nonfinite_3;
+ nonfinite_3 = (float) x < QNAN;
+ /* { dg-final { scan-tree-dump "nonfinite_3 = 0" "original" } } */
+ }
+
+ {
+ volatile int nonfinite_4;
+ nonfinite_4 = (float) x <= QNAN;
+ /* { dg-final { scan-tree-dump "nonfinite_4 = 0" "original" } } */
+ }
+
+ {
+ volatile int nonfinite_11;
+ nonfinite_11 = (float) x == QNAN;
+ /* { dg-final { scan-tree-dump "nonfinite_11 = 0" "original" } } */
+ }
+
+ {
+ volatile int nonfinite_12;
+ nonfinite_12 = (float) x != QNAN;
+ /* { dg-final { scan-tree-dump "nonfinite_12 = 1" "original" } } */
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/pragma-region.c b/gcc/testsuite/c-c++-common/pragma-region.c
new file mode 100644
index 0000000..8e0cbe1
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pragma-region.c
@@ -0,0 +1,11 @@
+/* { dg-options "-Wunknown-pragmas" } */
+/* { dg-final { scan-assembler "code_within_region" } } */
+/* { dg-final { scan-assembler "code_within_named_region" } } */
+
+#pragma region
+void code_within_region() { }
+#pragma endregion
+
+#pragma region ignored name
+void code_within_named_region() { }
+#pragma endregion // ignored comment
diff --git a/gcc/testsuite/c-c++-common/raw-string-directive-1.c b/gcc/testsuite/c-c++-common/raw-string-directive-1.c
new file mode 100644
index 0000000..d6525e1
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/raw-string-directive-1.c
@@ -0,0 +1,74 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" { target c } } */
+/* { dg-options "-std=c++11" { target c++ } } */
+
+/* Test that multi-line raw strings are lexed OK for all preprocessing
+ directives where one could appear. Test raw-string-directive-2.c
+ checks that #define is also processed properly. */
+
+/* Note that in cases where we cause GCC to produce a multi-line error
+ message, we construct the string so that the second line looks enough
+ like an error message for DejaGNU to process it as such, so that we
+ can use dg-warning or dg-error directives to check for it. */
+
+#warning R"delim(line1 /* { dg-warning "line1" } */
+file:15:1: warning: line2)delim" /* { dg-warning "line2" } */
+
+#error R"delim(line3 /* { dg-error "line3" } */
+file:18:1: error: line4)delim" /* { dg-error "line4" } */
+
+#define X1 R"(line 5
+line 6
+line 7
+line 8
+/*
+//
+line 9)" R"delim(
+line10)delim"
+
+#define X2(a) X1 #a R"(line 11
+/*
+line12
+)"
+
+#if R"(line 13 /* { dg-error "line13" } */
+file:35:1: error: line14)" /* { dg-error "line14\\)\"\" is not valid" } */
+#endif R"(line 15 /* { dg-warning "extra tokens at end of #endif" } */
+\
+line16)" ""
+
+#ifdef XYZ R"(line17 /* { dg-warning "extra tokens at end of #ifdef" } */
+\
+\
+line18)"
+#endif
+
+#if 1
+#else R"(line23 /* { dg-warning "extra tokens at end of #else" } */
+\
+
+line24)"
+#endif
+
+#if 0
+#elif R"(line 25 /* { dg-error "line25" } */
+file:55:1: error: line26)" /* { dg-error "line26\\)\"\" is not valid" } */
+#endif
+
+#line 60 R"(file:60:1: warning: this file has a space
+in it!)"
+#warning "line27" /* { dg-warning "line27" } */
+/* { dg-warning "this file has a space" "#line check" { target *-*-* } 60 } */
+#line 63 "file"
+
+#undef X1 R"(line28 /* { dg-warning "extra tokens at end of #undef" } */
+line29
+\
+)"
+
+#ident R"(line30
+line31)" R"(line 32 /* { dg-warning "extra tokens at end of #ident" } */
+line 33)"
+
+#pragma GCC diagnostic ignored R"(-Woption /* { dg-warning "-Wpragmas" } */
+-with-a-newline)"
diff --git a/gcc/testsuite/c-c++-common/raw-string-directive-2.c b/gcc/testsuite/c-c++-common/raw-string-directive-2.c
new file mode 100644
index 0000000..6fc673c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/raw-string-directive-2.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-options "-std=gnu99" { target c } } */
+/* { dg-options "-std=c++11" { target c++ } } */
+
+#define S1 R"(three
+line
+string)"
+
+#define S2 R"(pasted
+two line)" " string"
+
+#define X(a, b) a b R"(
+one more)"
+
+const char *s1 = S1;
+const char *s2 = S2;
+const char *s3 = X(S1, R"(
+with this line plus)");
+
+int main ()
+{
+ const char s1_correct[] = "three\nline\nstring";
+ if (__builtin_memcmp (s1, s1_correct, sizeof s1_correct))
+ __builtin_abort ();
+
+ const char s2_correct[] = "pasted\ntwo line string";
+ if (__builtin_memcmp (s2, s2_correct, sizeof s2_correct))
+ __builtin_abort ();
+
+ const char s3_correct[] = "three\nline\nstring\nwith this line plus\none more";
+ if (__builtin_memcmp (s3, s3_correct, sizeof s3_correct))
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/DRs/dr2392.C b/gcc/testsuite/g++.dg/DRs/dr2392.C
new file mode 100644
index 0000000..e24d6a7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/DRs/dr2392.C
@@ -0,0 +1,12 @@
+// DR 2392
+// { dg-do compile { target c++11 } }
+
+template <class T = void>
+constexpr int
+foo ()
+{
+ T t;
+ return 1;
+}
+
+using V = decltype (new int[foo ()]);
diff --git a/gcc/testsuite/g++.dg/DRs/dr2583.C b/gcc/testsuite/g++.dg/DRs/dr2583.C
new file mode 100644
index 0000000..e80834c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/DRs/dr2583.C
@@ -0,0 +1,45 @@
+// DR 2583 - Common initial sequence should consider over-alignment.
+// { dg-do compile { target c++11 } }
+
+#include <type_traits>
+
+struct A {
+ int i;
+ char c;
+};
+
+struct B {
+ int i;
+ alignas(8) char c;
+};
+
+struct C {
+ int i;
+ alignas(alignof(char)) char c;
+};
+
+struct D {
+ alignas(alignof(int)) int i;
+ char c;
+};
+
+struct S0 {
+ alignas(16) char x[128];
+ int i;
+};
+
+struct alignas(16) S1 {
+ char x[128];
+ int i;
+};
+
+#if __cpp_lib_is_layout_compatible >= 201907L
+static_assert (std::is_corresponding_member (&A::i, &B::i), "");
+static_assert (std::is_corresponding_member (&A::c, &B::c) == (alignof (char) == 8), "");
+static_assert (std::is_corresponding_member (&A::i, &C::i), "");
+static_assert (std::is_corresponding_member (&A::c, &C::c), "");
+static_assert (std::is_corresponding_member (&A::i, &D::i), "");
+static_assert (std::is_corresponding_member (&A::c, &D::c), "");
+static_assert (std::is_corresponding_member (&S0::x, &S1::x) == (alignof (char) == 16), "");
+static_assert (std::is_corresponding_member (&S0::i, &S1::i) == (alignof (char) == 16), "");
+#endif
diff --git a/gcc/testsuite/g++.dg/DRs/dr2604.C b/gcc/testsuite/g++.dg/DRs/dr2604.C
new file mode 100644
index 0000000..64bdf5d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/DRs/dr2604.C
@@ -0,0 +1,53 @@
+// DR 2604 - Attributes for an explicit specialization.
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wunused-parameter" }
+
+template<typename>
+[[noreturn]] void
+foo ([[maybe_unused]] int i)
+{
+ for (;;);
+}
+
+template<>
+void
+foo<int> (int i) // { dg-warning "unused parameter 'i'" }
+{
+}
+
+template<typename>
+void
+bar (int i) // { dg-warning "unused parameter 'i'" }
+{
+}
+
+template<>
+[[noreturn]] void
+bar<int> ([[maybe_unused]] int i)
+{
+ for (;;);
+}
+
+[[noreturn]] void
+baz ()
+{
+ foo<long> (0);
+}
+
+[[noreturn]] void
+qux ()
+{
+ foo<int> (0);
+} // { dg-warning "'noreturn' function does return" }
+
+[[noreturn]] void
+garply ()
+{
+ bar<long> (0);
+} // { dg-warning "'noreturn' function does return" }
+
+[[noreturn]] void
+corge ()
+{
+ bar<int> (0);
+}
diff --git a/gcc/testsuite/g++.dg/abi/lambda-sig1-18.C b/gcc/testsuite/g++.dg/abi/lambda-sig1-18.C
new file mode 100644
index 0000000..88692ed
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/lambda-sig1-18.C
@@ -0,0 +1,34 @@
+// { dg-do compile { target c++20 } }
+// { dg-options -fabi-version=18 }
+
+#include "lambda-sig1.h"
+
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlfE_clEf:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlfE0_clEf:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlTyfT_E_clIiEEDafS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlTyfT_E0_clIiEEDafS1_:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlTyT_E_clIiEEDaS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlTyT_E0_clIiEEDaS1_:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlfE_clEf:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlfE0_clEf:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlfE1_clEf:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlTyfT_E_clIiEEDafS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlTyfT_E0_clIiEEDafS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlTyfT_E1_clIiEEDafS1_:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlTyT_E_clIiEEDaS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlTyT_E0_clIiEEDaS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlTyT_E1_clIiEEDaS1_:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUliE_clEi:} } }
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUliE0_clEi:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUlTyiT_E_clIiEEDaiS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUlTyiT_E0_clIiEEDaiS1_:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUlTyT_E_clIiEEDaS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUlTyT_E0_clIiEEDaS1_:} } }
diff --git a/gcc/testsuite/g++.dg/abi/lambda-sig1-18vs17.C b/gcc/testsuite/g++.dg/abi/lambda-sig1-18vs17.C
new file mode 100644
index 0000000..b191fb3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/lambda-sig1-18vs17.C
@@ -0,0 +1,40 @@
+// { dg-do compile { target c++20 } }
+// { dg-options {-fabi-version=18 -Wabi=17} }
+
+#include "lambda-sig1.h"
+
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfT_E7_clIiEEDafS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlTyfT_E1_clIiEEDafS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlT_E5_clIiEEDaS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlTyT_E1_clIiEEDaS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfE6_cvPFvfEEv'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlfE1_cvPFvfEEv'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENUlfE6_4_FUNEf'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENUlfE1_4_FUNEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfE6_clEf'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlfE1_clEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfT_E4_clIiEEDafS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlTyfT_E0_clIiEEDafS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlT_E2_clIiEEDaS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlTyT_E0_clIiEEDaS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfE3_cvPFvfEEv'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlfE0_cvPFvfEEv'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENUlfE3_4_FUNEf'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENUlfE0_4_FUNEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfE3_clEf'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlfE0_clEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfT_E1_clIiEEDafS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlTyfT_E_clIiEEDafS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlT_E_clIiEEDaS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlTyT_E_clIiEEDaS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfE0_cvPFvfEEv'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlfE_cvPFvfEEv'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENUlfE0_4_FUNEf'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENUlfE_4_FUNEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfE0_clEf'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlfE_clEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlfT_E4_clIiEEDafS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlTyfT_E0_clIiEEDafS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlT_E2_clIiEEDaS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlTyT_E0_clIiEEDaS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlfE3_cvPFvfEEv'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlfE0_cvPFvfEEv'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENUlfE3_4_FUNEf'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENUlfE0_4_FUNEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlfE3_clEf'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlfE0_clEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlfT_E1_clIiEEDafS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlTyfT_E_clIiEEDafS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlT_E_clIiEEDaS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlTyT_E_clIiEEDaS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlfE0_cvPFvfEEv'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlfE_cvPFvfEEv'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENUlfE0_4_FUNEf'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENUlfE_4_FUNEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlfE0_clEf'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlfE_clEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUliT_E4_clIiEEDaiS1_'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUlTyiT_E0_clIiEEDaiS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUlT_E2_clIiEEDaS1_'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUlTyT_E0_clIiEEDaS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUliE3_cvPFviEEv'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUliE0_cvPFviEEv'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENUliE3_4_FUNEi'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENUliE0_4_FUNEi'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUliE3_clEi'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUliE0_clEi'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUliT_E1_clIiEEDaiS1_'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUlTyiT_E_clIiEEDaiS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUlT_E_clIiEEDaS1_'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUlTyT_E_clIiEEDaS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUliE0_cvPFviEEv'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUliE_cvPFviEEv'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENUliE0_4_FUNEi'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENUliE_4_FUNEi'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUliE0_clEi'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUliE_clEi'\) [^\n]*\n} }
diff --git a/gcc/testsuite/g++.dg/abi/lambda-tpl1-17.C b/gcc/testsuite/g++.dg/abi/lambda-tpl1-17.C
index b61aaf9..010f622 100644
--- a/gcc/testsuite/g++.dg/abi/lambda-tpl1-17.C
+++ b/gcc/testsuite/g++.dg/abi/lambda-tpl1-17.C
@@ -18,3 +18,9 @@
// { dg-final { scan-assembler {_ZNK6l_var3MUlRT_IJXspT0_EEEE_clI1XJLi1ELi2ELi3EEEEDaS1_:} } }
// { dg-final { scan-assembler {_ZNK6l_var4MUlR1YIJDpT_EEE_clIJ1US6_EEEDaS3_:} } }
// { dg-final { scan-assembler {_ZZ2FnILi1EEvvENKUlT_E_clIiEEDaS0_:} } }
+
+// { dg-final { scan-assembler {_ZZ1fvENKUlT_E_clIcLc0EEEDaS_:} } }
+// { dg-final { scan-assembler {_ZZ1fvENKUlT_E_clIiLi0EEEDaS_:} } }
+// { dg-final { scan-assembler {_ZZZ1fvENKUlT_E_clIcLc0EEEDaS_ENKUlcS_E_clIcEEDacS_:} } }
+// { dg-final { scan-assembler {_ZZZ1fvENKUlT_E_clIiLi0EEEDaS_ENKUliS_E_clIiEEDaiS_:} } }
+// { dg-final { scan-assembler {_ZZ1fvENKUlP1UIT_Lj0EEPS_IiLj0EEE0_clIcEEDaS2_S4_:} } }
diff --git a/gcc/testsuite/g++.dg/abi/lambda-tpl1-18.C b/gcc/testsuite/g++.dg/abi/lambda-tpl1-18.C
index dbeea40..66cce9a 100644
--- a/gcc/testsuite/g++.dg/abi/lambda-tpl1-18.C
+++ b/gcc/testsuite/g++.dg/abi/lambda-tpl1-18.C
@@ -23,3 +23,9 @@
// https://github.com/llvm/llvm-project/issues/58631
// { dg-final { scan-assembler {_ZZ2FnILi1EEvvENKUlTyT_E_clIiEEDaS0_:} } }
+
+// { dg-final { scan-assembler {_ZZ1fvENKUlTyTnT_S_E_clIcLc0EEEDaS_:} } }
+// { dg-final { scan-assembler {_ZZ1fvENKUlTyTnT_S_E_clIiLi0EEEDaS_:} } }
+// { dg-final { scan-assembler {_ZZZ1fvENKUlTyTnT_S_E_clIcLc0EEEDaS_ENKUlTycS_E_clIcEEDacS_:} } }
+// { dg-final { scan-assembler {_ZZZ1fvENKUlTyTnT_S_E_clIiLi0EEEDaS_ENKUlTyiS_E_clIiEEDaiS_:} } }
+// { dg-final { scan-assembler {_ZZ1fvENKUlTyP1UIT_Lj0EEPS_IiLj0EEE_clIcEEDaS2_S4_:} } }
diff --git a/gcc/testsuite/g++.dg/abi/lambda-tpl1-18vs17.C b/gcc/testsuite/g++.dg/abi/lambda-tpl1-18vs17.C
index 8bead73..6489db9 100644
--- a/gcc/testsuite/g++.dg/abi/lambda-tpl1-18vs17.C
+++ b/gcc/testsuite/g++.dg/abi/lambda-tpl1-18vs17.C
@@ -14,3 +14,8 @@
// { dg-regexp {[^\n]*lambda-tpl1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZNK10l_tpl_autoMUlT_T0_E_clIiiEEDaS_S0_'\) and '-fabi-version=18' \('_ZNK10l_tpl_autoMUlTyT_T0_E_clIiiEEDaS0_S1_'\) [^\n]*\n} }
// { dg-regexp {[^\n]*lambda-tpl1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZNK5l_tplMUlT_E_clIiEEDaS_'\) and '-fabi-version=18' \('_ZNK5l_tplMUlTyT_E_clIiEEDaS0_'\) [^\n]*\n} }
// { dg-regexp {[^\n]*lambda-tpl1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZNK6l_autoMUlT_E_clIiEEDaS_'\) and '-fabi-version=18' \('_ZNK6l_autoMUlT_E_clIiEEDaS0_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-tpl1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZ1fvENKUlT_E_clIiLi0EEEDaS_'\) and '-fabi-version=18' \('_ZZ1fvENKUlTyTnT_S_E_clIiLi0EEEDaS_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-tpl1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZZ1fvENKUlT_E_clIiLi0EEEDaS_ENKUliS_E_clIiEEDaiS_'\) and '-fabi-version=18' \('_ZZZ1fvENKUlTyTnT_S_E_clIiLi0EEEDaS_ENKUlTyiS_E_clIiEEDaiS_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-tpl1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZ1fvENKUlT_E_clIcLc0EEEDaS_'\) and '-fabi-version=18' \('_ZZ1fvENKUlTyTnT_S_E_clIcLc0EEEDaS_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-tpl1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZZ1fvENKUlT_E_clIcLc0EEEDaS_ENKUlcS_E_clIcEEDacS_'\) and '-fabi-version=18' \('_ZZZ1fvENKUlTyTnT_S_E_clIcLc0EEEDaS_ENKUlTycS_E_clIcEEDacS_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-tpl1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZ1fvENKUlP1UIT_Lj0EEPS_IiLj0EEE0_clIcEEDaS2_S4_'\) and '-fabi-version=18' \('_ZZ1fvENKUlTyP1UIT_Lj0EEPS_IiLj0EEE_clIcEEDaS2_S4_'\) [^\n]*\n} }
diff --git a/gcc/testsuite/g++.dg/abi/lambda-tpl1.h b/gcc/testsuite/g++.dg/abi/lambda-tpl1.h
index 5d6fe5e..376c3f6 100644
--- a/gcc/testsuite/g++.dg/abi/lambda-tpl1.h
+++ b/gcc/testsuite/g++.dg/abi/lambda-tpl1.h
@@ -56,4 +56,15 @@ void f ()
l_var4 (y);
Fn<1> ();
+
+ auto l1 = []<typename T, T v = T(0)> (T a) {
+ auto l2 = []<typename U> (T a, U b) {};
+
+ l2 (a, v);
+ };
+ auto l3 = []<typename T>(U<T, 0> *, U<int, 0> *) {};
+
+ l1 (1);
+ l1 ('1');
+ l3 ((U<char, 0> *)nullptr, nullptr);
}
diff --git a/gcc/testsuite/g++.dg/analyzer/fd-bind-pr107783.C b/gcc/testsuite/g++.dg/analyzer/fd-bind-pr107783.C
new file mode 100644
index 0000000..eb5e23c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/fd-bind-pr107783.C
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++11 } }
+
+struct minus {
+} _1;
+int _2;
+struct _Bind {
+ _Bind(_Bind &);
+};
+template <typename _Func, typename _BoundArgs>
+_Bind bind(_Func, _BoundArgs &&...);
+void test01() { bind(minus(), _2, _1); }
diff --git a/gcc/testsuite/g++.dg/analyzer/infinite-recursion-1.C b/gcc/testsuite/g++.dg/analyzer/infinite-recursion-1.C
new file mode 100644
index 0000000..33f3b33
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/infinite-recursion-1.C
@@ -0,0 +1,84 @@
+class widget
+{
+public:
+ virtual void draw ()
+ {
+ /* no-op */
+ }
+};
+
+class foo_widget : public widget
+{
+public:
+ void draw ();
+};
+
+void foo_widget::draw ()
+{
+ // Bogus attempt to chain up to base class leading to infinite recursion:
+ foo_widget::draw (); /* { dg-warning "infinite recursion" } */
+
+ // [...snip...]
+}
+
+/* Infinite recursion due to a buggy "operator int". */
+
+class boxed_int
+{
+ int m_val;
+public:
+ operator int ();
+};
+
+boxed_int::operator int ()
+{
+ return *this; /* { dg-warning "infinite recursion" } */
+}
+
+template <typename T>
+class buggy_getter
+{
+public:
+ T get_value () const
+ {
+ return get_value (); /* { dg-warning "infinite recursion" } */
+ }
+};
+
+int test_buggy_getter (buggy_getter<int> g)
+{
+ return g.get_value ();
+}
+
+/* Copy of g++.dg/warn/Winfinite-recursion.C */
+
+template <typename D>
+struct C
+{
+ void foo ()
+ {
+ static_cast<D *>(this)->foo (); /* { dg-warning "-Wanalyzer-infinite-recursion" } */
+ }
+};
+
+struct D : C<D>
+{
+ // this is missing:
+ // void foo() {}
+};
+
+void f (D *d)
+{
+ d->foo ();
+}
+
+
+struct E : C<D>
+{
+ void foo() {}
+};
+
+void g (E *e)
+{
+ e->foo ();
+}
diff --git a/gcc/testsuite/g++.dg/analyzer/infinite-recursion-2.C b/gcc/testsuite/g++.dg/analyzer/infinite-recursion-2.C
new file mode 100644
index 0000000..c582fbf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/infinite-recursion-2.C
@@ -0,0 +1,74 @@
+/* Copy of g++.dg/warn/Winfinite-recursion-2.C */
+
+/* { dg-do compile { target c++11 } } */
+
+namespace std
+{
+class type_info {
+public:
+ void k() const;
+};
+
+} // namespace std
+
+using std::type_info;
+
+template <int a> struct f { static constexpr int c = a; };
+struct h {
+ typedef int e;
+};
+
+template <unsigned long, typename...> struct m;
+template <unsigned long ab, typename i, typename j, typename... ac>
+struct m<ab, i, j, ac...> : m<ab + 1, i, ac...> {};
+template <unsigned long ab, typename j, typename... ac>
+struct m<ab, j, j, ac...> : f<ab> {};
+template <unsigned long, typename...> struct n;
+template <unsigned long ab, typename j, typename... ac>
+struct n<ab, j, ac...> : n<ab - 1, ac...> {};
+template <typename j, typename... ac> struct n<0, j, ac...> : h {};
+template <typename... l> class F {
+ template <typename i> struct I : m<0, i, l...> {};
+ template <int ab> struct s : n<ab, l...> {};
+ static const type_info *const b[];
+ struct G {
+ template <typename ag>
+ operator ag() const
+ {
+ return *this; /* { dg-warning "-Wanalyzer-infinite-recursion" } */
+ }
+ };
+ unsigned o;
+ G ah;
+
+public:
+ F();
+ long t() const { return o; }
+ const type_info &m_fn3() const { return *b[o]; }
+ template <int ab> typename s<ab>::e *m_fn4() const {
+ if (o != ab)
+ return nullptr;
+ return ah;
+ }
+ template <int ab> void m_fn5() const {
+ m_fn4<ab>();
+ const type_info &r = m_fn3();
+ r.k();
+ }
+ template <typename i> void u() const { m_fn5<I<i>::c>(); }
+};
+template <typename... l> const type_info *const F<l...>::b[] {&typeid(l)...};
+using am = unsigned char;
+class H {
+ enum bd : am { be = 2 };
+ using bf = F<int, int, H>;
+ bf ah;
+ template <typename bg> void v() const { ah.u<bg>(); }
+ void w() const;
+};
+void H::w() const {
+ bd d = bd(ah.t());
+ switch (d)
+ case be:
+ v<H>();
+}
diff --git a/gcc/testsuite/g++.dg/analyzer/infinite-recursion-3.C b/gcc/testsuite/g++.dg/analyzer/infinite-recursion-3.C
new file mode 100644
index 0000000..a749f62
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/infinite-recursion-3.C
@@ -0,0 +1,62 @@
+/* Adapted from g++.dg/warn/Winfinite-recursion-3.C */
+
+typedef __SIZE_TYPE__ size_t;
+
+/* Might throw. */
+void f ();
+
+void warn_f_call_r (int n)
+{
+ if (n > 7)
+ f ();
+ warn_f_call_r (n - 1);
+}
+
+void warn_f_do_while_call_r (int n)
+{
+ f ();
+ do
+ {
+ f ();
+ warn_f_do_while_call_r (n - 1);
+ }
+ while (1);
+}
+
+
+struct X
+{
+ X (int);
+ ~X ();
+};
+
+int warn_class_with_ctor (int n)
+{
+ X x (n);
+ return n + warn_class_with_ctor (n - 1);
+}
+
+
+int nowarn_throw (int n)
+{
+ if (n > 7)
+ throw "argument too big";
+
+ return n + nowarn_throw (n - 1);
+}
+
+extern int* eipa[];
+
+void warn_call_new (int i)
+{
+ eipa[i] = new int;
+
+ warn_call_new (i - 1);
+}
+
+void* operator new[] (size_t n)
+{
+ char *p = new char[n + sizeof (n)];
+ *(size_t*)p = n;
+ return p + sizeof n;
+}
diff --git a/gcc/testsuite/g++.dg/analyzer/named-functions.C b/gcc/testsuite/g++.dg/analyzer/named-functions.C
new file mode 100644
index 0000000..661a930
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/named-functions.C
@@ -0,0 +1,12 @@
+#define NULL ((void *)0)
+
+namespace my
+{
+ int socket (int, int, int);
+};
+
+void test_my_socket ()
+{
+ /* This shouldn't match the known function "::socket". */
+ my::socket (0, 0, 0); /* { dg-bogus "leak" } */
+}
diff --git a/gcc/testsuite/g++.dg/analyzer/pr108003.C b/gcc/testsuite/g++.dg/analyzer/pr108003.C
new file mode 100644
index 0000000..c93e959
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/pr108003.C
@@ -0,0 +1,37 @@
+/* Regression test for ICE. */
+/* { dg-additional-options "-Wno-analyzer-possible-null-argument" } */
+/* { dg-additional-options "-Wno-analyzer-malloc-leak" } */
+/* { dg-additional-options "-Wno-analyzer-possible-null-dereference" } */
+
+/* { dg-additional-options "-O1 --param analyzer-max-svalue-depth=5" } */
+
+struct locale {
+ class _Impl;
+ _Impl *_M_impl;
+
+ template <typename _Facet>
+ locale (const locale &, _Facet *);
+
+ static locale
+ classic ();
+};
+
+struct locale::_Impl {
+ _Impl (_Impl, int);
+};
+
+template <typename _Facet>
+locale::locale (const locale &, _Facet *)
+{
+ new _Impl (*_M_impl, 1);
+}
+
+struct codecvt {
+ virtual void do_max_lengththrow ();
+};
+
+void
+test01 ()
+{
+ locale (locale::classic (), new codecvt);
+}
diff --git a/gcc/testsuite/g++.dg/asan/asan_mem_test.cc b/gcc/testsuite/g++.dg/asan/asan_mem_test.cc
index 5fc4af7..7f6f3f4 100644
--- a/gcc/testsuite/g++.dg/asan/asan_mem_test.cc
+++ b/gcc/testsuite/g++.dg/asan/asan_mem_test.cc
@@ -31,18 +31,18 @@ void MemSetOOBTestTemplate(size_t length) {
MEMSET(array + length, 0, zero);
MEMSET(array + length + 1, 0, zero);
- // try to memset bytes to the right of array
+ // try to memset bytes after array
EXPECT_DEATH(MEMSET(array, 0, size + 1),
RightOOBWriteMessage(0));
EXPECT_DEATH(MEMSET((char*)(array + length) - 1, element, 6),
RightOOBWriteMessage(0));
EXPECT_DEATH(MEMSET(array + 1, element, size + sizeof(T)),
RightOOBWriteMessage(0));
- // whole interval is to the right
+ // whole interval is after
EXPECT_DEATH(MEMSET(array + length + 1, 0, 10),
RightOOBWriteMessage(sizeof(T)));
- // try to memset bytes to the left of array
+ // try to memset bytes before array
EXPECT_DEATH(MEMSET((char*)array - 1, element, size),
LeftOOBWriteMessage(1));
EXPECT_DEATH(MEMSET((char*)array - 5, 0, 6),
@@ -52,11 +52,11 @@ void MemSetOOBTestTemplate(size_t length) {
EXPECT_DEATH(memset(array - 5, element, size + 5 * sizeof(T)),
LeftOOBWriteMessage(5 * sizeof(T)));
}
- // whole interval is to the left
+ // whole interval is before
EXPECT_DEATH(MEMSET(array - 2, 0, sizeof(T)),
LeftOOBWriteMessage(2 * sizeof(T)));
- // try to memset bytes both to the left & to the right
+ // try to memset bytes both before & after
EXPECT_DEATH(MEMSET((char*)array - 2, element, size + 4),
LeftOOBWriteMessage(2));
@@ -108,7 +108,7 @@ TEST(AddressSanitizer, LargeOOBInMemset) {
// fprintf(stderr, " large oob memset: %p %p %zd\n", x1, x2, size);
// Do a memset on x1 with huge out-of-bound access that will end up in x2.
EXPECT_DEATH(Ident(memset)(x1, 0, size * 2),
- "is located 0 bytes to the right");
+ "is located 0 bytes after");
delete [] x1;
delete [] x2;
return;
@@ -137,25 +137,25 @@ void MemTransferOOBTestTemplate(size_t length) {
M::transfer(dest, src - 1, zero);
M::transfer(dest, src, zero);
- // try to change mem to the right of dest
+ // try to change mem after dest
EXPECT_DEATH(M::transfer(dest + 1, src, size),
RightOOBWriteMessage(0));
EXPECT_DEATH(M::transfer((char*)(dest + length) - 1, src, 5),
RightOOBWriteMessage(0));
- // try to change mem to the left of dest
+ // try to change mem before dest
EXPECT_DEATH(M::transfer(dest - 2, src, size),
LeftOOBWriteMessage(2 * sizeof(T)));
EXPECT_DEATH(M::transfer((char*)dest - 3, src, 4),
LeftOOBWriteMessage(3));
- // try to access mem to the right of src
+ // try to access mem after src
EXPECT_DEATH(M::transfer(dest, src + 2, size),
RightOOBReadMessage(0));
EXPECT_DEATH(M::transfer(dest, (char*)(src + length) - 3, 6),
RightOOBReadMessage(0));
- // try to access mem to the left of src
+ // try to access mem before src
EXPECT_DEATH(M::transfer(dest, src - 1, size),
LeftOOBReadMessage(sizeof(T)));
EXPECT_DEATH(M::transfer(dest, (char*)src - 6, 7),
diff --git a/gcc/testsuite/g++.dg/asan/asan_oob_test.cc b/gcc/testsuite/g++.dg/asan/asan_oob_test.cc
index 7d3f557..05fa722 100644
--- a/gcc/testsuite/g++.dg/asan/asan_oob_test.cc
+++ b/gcc/testsuite/g++.dg/asan/asan_oob_test.cc
@@ -33,7 +33,7 @@ void OOBTest() {
for (int size = sizeof(T); size < 20; size += 5) {
for (int i = -5; i < 0; i++) {
const char *str =
- "is located.*%d byte.*to the left";
+ "is located.*%d byte.*before";
sprintf(expected_str, str, abs(i));
EXPECT_DEATH(oob_test<T>(size, i), expected_str);
}
@@ -43,7 +43,7 @@ void OOBTest() {
for (int i = size - sizeof(T) + 1; i <= (int)(size + 2 * sizeof(T)); i++) {
const char *str =
- "is located.*%d byte.*to the right";
+ "is located.*%d byte.*after";
int off = i >= size ? (i - size) : 0;
// we don't catch unaligned partially OOB accesses.
if (i % sizeof(T)) continue;
@@ -53,9 +53,9 @@ void OOBTest() {
}
EXPECT_DEATH(oob_test<T>(kLargeMalloc, -1),
- "is located.*1 byte.*to the left");
+ "is located.*1 byte.*before");
EXPECT_DEATH(oob_test<T>(kLargeMalloc, kLargeMalloc),
- "is located.*0 byte.*to the right");
+ "is located.*0 byte.*after");
}
// TODO(glider): the following tests are EXTREMELY slow on Darwin:
@@ -89,7 +89,7 @@ TEST(AddressSanitizer, OOBRightTest) {
} else {
int outside_bytes = offset > alloc_size ? (offset - alloc_size) : 0;
const char *str =
- "is located.%d *byte.*to the right";
+ "is located.%d *byte.*after";
char expected_str[100];
sprintf(expected_str, str, outside_bytes);
EXPECT_DEATH(asan_write_sized_aligned(addr, access_size),
@@ -106,7 +106,7 @@ TEST(AddressSanitizer, LargeOOBRightTest) {
for (size_t i = 16; i <= 256; i *= 2) {
size_t size = large_power_of_two - i;
char *p = Ident(new char[size]);
- EXPECT_DEATH(p[size] = 0, "is located 0 bytes to the right");
+ EXPECT_DEATH(p[size] = 0, "is located 0 bytes after");
delete [] p;
}
}
diff --git a/gcc/testsuite/g++.dg/asan/asan_str_test.cc b/gcc/testsuite/g++.dg/asan/asan_str_test.cc
index 207de42..56e1369 100644
--- a/gcc/testsuite/g++.dg/asan/asan_str_test.cc
+++ b/gcc/testsuite/g++.dg/asan/asan_str_test.cc
@@ -19,7 +19,7 @@ static char global_string[] = "global";
static size_t global_string_length = 6;
// Input to a test is a zero-terminated string str with given length
-// Accesses to the bytes to the left and to the right of str
+// Accesses to the bytes to the left and after str
// are presumed to produce OOB errors
void StrLenOOBTestTemplate(char *str, size_t length, bool is_global) {
// Normal strlen calls
@@ -30,7 +30,7 @@ void StrLenOOBTestTemplate(char *str, size_t length, bool is_global) {
}
// Arg of strlen is not malloced, OOB access
if (!is_global) {
- // We don't insert RedZones to the left of global variables
+ // We don't insert RedZones before global variables
EXPECT_DEATH(Ident(strlen(str - 1)), LeftOOBReadMessage(1));
EXPECT_DEATH(Ident(strlen(str - 5)), LeftOOBReadMessage(5));
}
diff --git a/gcc/testsuite/g++.dg/asan/asan_test.cc b/gcc/testsuite/g++.dg/asan/asan_test.cc
index dbf1a6a..0d97680 100644
--- a/gcc/testsuite/g++.dg/asan/asan_test.cc
+++ b/gcc/testsuite/g++.dg/asan/asan_test.cc
@@ -286,7 +286,7 @@ TEST(AddressSanitizer, SignalTest) {
static void TestLargeMalloc(size_t size) {
char buff[1024];
- sprintf(buff, "is located 1 bytes to the left of %lu-byte", (long)size);
+ sprintf(buff, "is located 1 bytes before %lu-byte", (long)size);
EXPECT_DEATH(Ident((char*)malloc(size))[-1] = 0, buff);
}
@@ -301,7 +301,7 @@ TEST(AddressSanitizer, HugeMallocTest) {
if (SANITIZER_WORDSIZE != 64 || ASAN_AVOID_EXPENSIVE_TESTS) return;
size_t n_megs = 4100;
EXPECT_DEATH(Ident((char*)malloc(n_megs << 20))[-1] = 0,
- "is located 1 bytes to the left|"
+ "is located 1 bytes before|"
"AddressSanitizer failed to allocate");
}
@@ -316,9 +316,9 @@ TEST(AddressSanitizer, memalign) {
for (int align = 16; align <= (1 << 23); align *= 2) {
size_t size = align * 5;
EXPECT_DEATH(MemalignRun(align, size, -1),
- "is located 1 bytes to the left");
+ "is located 1 bytes before");
EXPECT_DEATH(MemalignRun(align, size, size + 1),
- "is located 1 bytes to the right");
+ "is located 1 bytes after");
}
}
#endif // SANITIZER_TEST_HAS_MEMALIGN
@@ -696,7 +696,7 @@ TEST(AddressSanitizer, Store128Test) {
EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),
"WRITE of size 16");
EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),
- "located 0 bytes to the right of 12-byte");
+ "located 0 bytes after 12-byte");
free(a);
}
#endif
@@ -709,7 +709,7 @@ string RightOOBErrorMessage(int oob_distance, bool is_write) {
#if !GTEST_USES_SIMPLE_RE
"buffer-overflow.*%s.*"
#endif
- "located %d bytes to the right",
+ "located %d bytes after",
#if !GTEST_USES_SIMPLE_RE
is_write ? "WRITE" : "READ",
#endif
@@ -733,7 +733,7 @@ string LeftOOBErrorMessage(int oob_distance, bool is_write) {
#if !GTEST_USES_SIMPLE_RE
ASAN_PCRE_DOTALL "%s.*"
#endif
- "located %d bytes to the left",
+ "located %d bytes before",
#if !GTEST_USES_SIMPLE_RE
is_write ? "WRITE" : "READ",
#endif
@@ -752,7 +752,7 @@ string LeftOOBReadMessage(int oob_distance) {
string LeftOOBAccessMessage(int oob_distance) {
assert(oob_distance > 0);
char expected_str[100];
- sprintf(expected_str, "located %d bytes to the left", oob_distance);
+ sprintf(expected_str, "located %d bytes before", oob_distance);
return string(expected_str);
}
@@ -774,7 +774,7 @@ char* MallocAndMemsetString(size_t size) {
EXPECT_DEATH(READ_N_BYTES, \
ASAN_PCRE_DOTALL \
"AddressSanitizer: heap-buffer-overflow" \
- ".* is located 0 bytes to the right of 10-byte region"); \
+ ".* is located 0 bytes after 10-byte region"); \
close(fd); \
delete [] x; \
@@ -976,23 +976,23 @@ TEST(AddressSanitizer, GlobalTest) {
glob5[Ident(4)] = 0;
EXPECT_DEATH(glob5[Ident(5)] = 0,
- "0 bytes to the right of global variable.*glob5.* size 5");
+ "0 bytes after global variable.*glob5.* size 5");
EXPECT_DEATH(glob5[Ident(5+6)] = 0,
- "6 bytes to the right of global variable.*glob5.* size 5");
+ "6 bytes after global variable.*glob5.* size 5");
Ident(static110); // avoid optimizations
static110[Ident(0)] = 0;
static110[Ident(109)] = 0;
EXPECT_DEATH(static110[Ident(110)] = 0,
- "0 bytes to the right of global variable");
+ "0 bytes after global variable");
EXPECT_DEATH(static110[Ident(110+7)] = 0,
- "7 bytes to the right of global variable");
+ "7 bytes after global variable");
Ident(func_static15); // avoid optimizations
func_static15[Ident(0)] = 0;
EXPECT_DEATH(func_static15[Ident(15)] = 0,
- "0 bytes to the right of global variable");
+ "0 bytes after global variable");
EXPECT_DEATH(func_static15[Ident(15 + 9)] = 0,
- "9 bytes to the right of global variable");
+ "9 bytes after global variable");
Ident(fs1);
Ident(fs2);
@@ -1000,12 +1000,12 @@ TEST(AddressSanitizer, GlobalTest) {
// We don't create left redzones, so this is not 100% guaranteed to fail.
// But most likely will.
- EXPECT_DEATH(fs2[Ident(-1)] = 0, "is located.*of global variable");
+ EXPECT_DEATH(fs2[Ident(-1)] = 0, "is located.*global variable");
EXPECT_DEATH(Ident(Ident(ConstGlob)[8]),
- "is located 1 bytes to the right of .*ConstGlob");
+ "is located 1 bytes after .*ConstGlob");
EXPECT_DEATH(Ident(Ident(StaticConstGlob)[5]),
- "is located 2 bytes to the right of .*StaticConstGlob");
+ "is located 2 bytes after .*StaticConstGlob");
// call stuff from another file.
GlobalsTest(0);
diff --git a/gcc/testsuite/g++.dg/asan/large-func-test-1.C b/gcc/testsuite/g++.dg/asan/large-func-test-1.C
index ac9deb8..a43235ba 100644
--- a/gcc/testsuite/g++.dg/asan/large-func-test-1.C
+++ b/gcc/testsuite/g++.dg/asan/large-func-test-1.C
@@ -40,7 +40,7 @@ int main() {
// { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" }
// { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" }
// { dg-output " #0 0x\[0-9a-f\]+ +(in \[^\n\r]*LargeFunction\[^\n\r]*(large-func-test-1.C:18|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\]).*(\n|\r\n|\r)" }
-// { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 44 bytes to the right of 400-byte region.*(\n|\r\n|\r)" }
+// { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 44 bytes after 400-byte region.*(\n|\r\n|\r)" }
// { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" }
// { dg-output " #0( 0x\[0-9a-f\]+ +(in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" }
// { dg-output " #1|) 0x\[0-9a-f\]+ +(in (operator new|(wrap|)_*_Zn\[aw\]\[mj\])|\[(\])\[^\n\r]*(\n|\r\n|\r)" }
diff --git a/gcc/testsuite/g++.dg/concepts/auto1.C b/gcc/testsuite/g++.dg/concepts/auto1.C
index e053306..abf7886 100644
--- a/gcc/testsuite/g++.dg/concepts/auto1.C
+++ b/gcc/testsuite/g++.dg/concepts/auto1.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T1, class T2> class A { };
diff --git a/gcc/testsuite/g++.dg/concepts/auto3.C b/gcc/testsuite/g++.dg/concepts/auto3.C
index 27a6afa..868a56c 100644
--- a/gcc/testsuite/g++.dg/concepts/auto3.C
+++ b/gcc/testsuite/g++.dg/concepts/auto3.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class...> class tuple {};
diff --git a/gcc/testsuite/g++.dg/concepts/auto4.C b/gcc/testsuite/g++.dg/concepts/auto4.C
index 8bf3fa9..6c98455 100644
--- a/gcc/testsuite/g++.dg/concepts/auto4.C
+++ b/gcc/testsuite/g++.dg/concepts/auto4.C
@@ -1,6 +1,6 @@
// PR c++/85006
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename... Ts> struct A {};
diff --git a/gcc/testsuite/g++.dg/concepts/class-deduction1.C b/gcc/testsuite/g++.dg/concepts/class-deduction1.C
index 3359700..7f427d0 100644
--- a/gcc/testsuite/g++.dg/concepts/class-deduction1.C
+++ b/gcc/testsuite/g++.dg/concepts/class-deduction1.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T>
concept bool Isint = __is_same_as(T,int);
diff --git a/gcc/testsuite/g++.dg/concepts/class5.C b/gcc/testsuite/g++.dg/concepts/class5.C
index ac9d7e8..5f8ece9 100644
--- a/gcc/testsuite/g++.dg/concepts/class5.C
+++ b/gcc/testsuite/g++.dg/concepts/class5.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool One() { return sizeof(T) >= 4; }
diff --git a/gcc/testsuite/g++.dg/concepts/class6.C b/gcc/testsuite/g++.dg/concepts/class6.C
index f2345b1..a1c5e16 100644
--- a/gcc/testsuite/g++.dg/concepts/class6.C
+++ b/gcc/testsuite/g++.dg/concepts/class6.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool One() { return sizeof(T) >= 4; }
diff --git a/gcc/testsuite/g++.dg/concepts/debug1.C b/gcc/testsuite/g++.dg/concepts/debug1.C
index b9a5444..fb48567 100644
--- a/gcc/testsuite/g++.dg/concepts/debug1.C
+++ b/gcc/testsuite/g++.dg/concepts/debug1.C
@@ -1,6 +1,6 @@
// PR c++/84551
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename> concept bool C() { return true; }
diff --git a/gcc/testsuite/g++.dg/concepts/decl-diagnose.C b/gcc/testsuite/g++.dg/concepts/decl-diagnose.C
index 6a461a5..96038fd 100644
--- a/gcc/testsuite/g++.dg/concepts/decl-diagnose.C
+++ b/gcc/testsuite/g++.dg/concepts/decl-diagnose.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
typedef concept int CINT; // { dg-error "'concept' cannot appear in a typedef declaration" }
diff --git a/gcc/testsuite/g++.dg/concepts/deduction-constraint1.C b/gcc/testsuite/g++.dg/concepts/deduction-constraint1.C
index eba5771..d510fe0 100644
--- a/gcc/testsuite/g++.dg/concepts/deduction-constraint1.C
+++ b/gcc/testsuite/g++.dg/concepts/deduction-constraint1.C
@@ -1,6 +1,6 @@
// PR c++/67007
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class U>
concept bool A =
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic1.C b/gcc/testsuite/g++.dg/concepts/diagnostic1.C
index 29c78c4..207c36c 100644
--- a/gcc/testsuite/g++.dg/concepts/diagnostic1.C
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic1.C
@@ -1,6 +1,6 @@
// PR c++/67159
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts -fconcepts-diagnostics-depth=2" }
+// { dg-options "-fconcepts-ts -fconcepts-diagnostics-depth=2" }
template <class T, class U>
concept bool SameAs = __is_same_as(T, U);
diff --git a/gcc/testsuite/g++.dg/concepts/dr1430.C b/gcc/testsuite/g++.dg/concepts/dr1430.C
index 05c9152..c22a782 100644
--- a/gcc/testsuite/g++.dg/concepts/dr1430.C
+++ b/gcc/testsuite/g++.dg/concepts/dr1430.C
@@ -1,6 +1,6 @@
// PR c++/66092
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
#include <type_traits>
diff --git a/gcc/testsuite/g++.dg/concepts/equiv.C b/gcc/testsuite/g++.dg/concepts/equiv.C
index 640c2b5..a5d0c18 100644
--- a/gcc/testsuite/g++.dg/concepts/equiv.C
+++ b/gcc/testsuite/g++.dg/concepts/equiv.C
@@ -1,5 +1,5 @@
// { dg-do link { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// Check equivalence of short- and longhand declarations.
diff --git a/gcc/testsuite/g++.dg/concepts/equiv2.C b/gcc/testsuite/g++.dg/concepts/equiv2.C
index dff719b..48a2664 100644
--- a/gcc/testsuite/g++.dg/concepts/equiv2.C
+++ b/gcc/testsuite/g++.dg/concepts/equiv2.C
@@ -1,5 +1,5 @@
// { dg-do link { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// template<typename T>
diff --git a/gcc/testsuite/g++.dg/concepts/explicit-spec1a.C b/gcc/testsuite/g++.dg/concepts/explicit-spec1a.C
new file mode 100644
index 0000000..ec67874
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/explicit-spec1a.C
@@ -0,0 +1,11 @@
+// A version of explicit-spec1.C where the template g has trailing instead of
+// template requirements.
+// PR c++/107864
+// { dg-do compile { target concepts } }
+
+template<typename T> concept C = __is_class(T);
+struct Y { int n; } y;
+template<class T> void g(T) requires C<T> { }
+int called;
+template<> void g(Y) { called = 3; }
+int main() { g(y); }
diff --git a/gcc/testsuite/g++.dg/concepts/expression.C b/gcc/testsuite/g++.dg/concepts/expression.C
index ba4c48d..3da0c96 100644
--- a/gcc/testsuite/g++.dg/concepts/expression.C
+++ b/gcc/testsuite/g++.dg/concepts/expression.C
@@ -1,5 +1,5 @@
// { dg-do run { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// TODO: ICE on gimplify 16?
diff --git a/gcc/testsuite/g++.dg/concepts/expression2.C b/gcc/testsuite/g++.dg/concepts/expression2.C
index 4bb5bc7..2f7aafc 100644
--- a/gcc/testsuite/g++.dg/concepts/expression2.C
+++ b/gcc/testsuite/g++.dg/concepts/expression2.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1()
diff --git a/gcc/testsuite/g++.dg/concepts/expression3.C b/gcc/testsuite/g++.dg/concepts/expression3.C
index 67646811..a2d340d 100644
--- a/gcc/testsuite/g++.dg/concepts/expression3.C
+++ b/gcc/testsuite/g++.dg/concepts/expression3.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C()
diff --git a/gcc/testsuite/g++.dg/concepts/fn-concept1.C b/gcc/testsuite/g++.dg/concepts/fn-concept1.C
index d1b4c0c..4908d11 100644
--- a/gcc/testsuite/g++.dg/concepts/fn-concept1.C
+++ b/gcc/testsuite/g++.dg/concepts/fn-concept1.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool Tuple() { // { dg-error "multiple statements" }
diff --git a/gcc/testsuite/g++.dg/concepts/fn-concept2.C b/gcc/testsuite/g++.dg/concepts/fn-concept2.C
index 899988c..2876505 100644
--- a/gcc/testsuite/g++.dg/concepts/fn-concept2.C
+++ b/gcc/testsuite/g++.dg/concepts/fn-concept2.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept auto C1() { return 0; } // { dg-error "16:concept .concept auto C1\\(\\). declared with a deduced return type" }
diff --git a/gcc/testsuite/g++.dg/concepts/fn-concept3.C b/gcc/testsuite/g++.dg/concepts/fn-concept3.C
index ecb7f6b..88ed5a8 100644
--- a/gcc/testsuite/g++.dg/concepts/fn-concept3.C
+++ b/gcc/testsuite/g++.dg/concepts/fn-concept3.C
@@ -1,6 +1,6 @@
// PR c++/92746
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T> concept bool C3() { return true; }
static_assert(noexcept(C3<int>()), "function concept should be treated as if noexcept(true) specified");
diff --git a/gcc/testsuite/g++.dg/concepts/fn1.C b/gcc/testsuite/g++.dg/concepts/fn1.C
index f23c057..e22cbf7 100644
--- a/gcc/testsuite/g++.dg/concepts/fn1.C
+++ b/gcc/testsuite/g++.dg/concepts/fn1.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C() { return __is_class(T); }
diff --git a/gcc/testsuite/g++.dg/concepts/fn10.C b/gcc/testsuite/g++.dg/concepts/fn10.C
index 8d0a2e1..83099de 100644
--- a/gcc/testsuite/g++.dg/concepts/fn10.C
+++ b/gcc/testsuite/g++.dg/concepts/fn10.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// Test that constraint satisfaction checks work even when
// processing template declarations.
diff --git a/gcc/testsuite/g++.dg/concepts/fn2.C b/gcc/testsuite/g++.dg/concepts/fn2.C
index 1c1280c..e0ac36f 100644
--- a/gcc/testsuite/g++.dg/concepts/fn2.C
+++ b/gcc/testsuite/g++.dg/concepts/fn2.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C() { return __is_class(T); }
diff --git a/gcc/testsuite/g++.dg/concepts/fn3.C b/gcc/testsuite/g++.dg/concepts/fn3.C
index 07b8e3a..3e076f6 100644
--- a/gcc/testsuite/g++.dg/concepts/fn3.C
+++ b/gcc/testsuite/g++.dg/concepts/fn3.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
#include <cassert>
diff --git a/gcc/testsuite/g++.dg/concepts/fn4.C b/gcc/testsuite/g++.dg/concepts/fn4.C
index bbaac46..6418677 100644
--- a/gcc/testsuite/g++.dg/concepts/fn4.C
+++ b/gcc/testsuite/g++.dg/concepts/fn4.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C() { return __is_class(T); }
diff --git a/gcc/testsuite/g++.dg/concepts/fn5.C b/gcc/testsuite/g++.dg/concepts/fn5.C
index bf27713..3decf4e 100644
--- a/gcc/testsuite/g++.dg/concepts/fn5.C
+++ b/gcc/testsuite/g++.dg/concepts/fn5.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// Check shorthand notation.
diff --git a/gcc/testsuite/g++.dg/concepts/fn6.C b/gcc/testsuite/g++.dg/concepts/fn6.C
index 031e87f..57c4cfb 100644
--- a/gcc/testsuite/g++.dg/concepts/fn6.C
+++ b/gcc/testsuite/g++.dg/concepts/fn6.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// Redefinition errors.
diff --git a/gcc/testsuite/g++.dg/concepts/fn8.C b/gcc/testsuite/g++.dg/concepts/fn8.C
index 32df5a5..594270f 100644
--- a/gcc/testsuite/g++.dg/concepts/fn8.C
+++ b/gcc/testsuite/g++.dg/concepts/fn8.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool Class() { return __is_class(T); }
diff --git a/gcc/testsuite/g++.dg/concepts/fn9.C b/gcc/testsuite/g++.dg/concepts/fn9.C
index 2f5e88b..51edd2f 100644
--- a/gcc/testsuite/g++.dg/concepts/fn9.C
+++ b/gcc/testsuite/g++.dg/concepts/fn9.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
#include <cassert>
diff --git a/gcc/testsuite/g++.dg/concepts/generic-fn-err.C b/gcc/testsuite/g++.dg/concepts/generic-fn-err.C
index 816072d..e4909eb 100644
--- a/gcc/testsuite/g++.dg/concepts/generic-fn-err.C
+++ b/gcc/testsuite/g++.dg/concepts/generic-fn-err.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C() { return __is_class(T); }
diff --git a/gcc/testsuite/g++.dg/concepts/generic-fn.C b/gcc/testsuite/g++.dg/concepts/generic-fn.C
index 257608a..983b370 100644
--- a/gcc/testsuite/g++.dg/concepts/generic-fn.C
+++ b/gcc/testsuite/g++.dg/concepts/generic-fn.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
#include <cassert>
#include <type_traits>
diff --git a/gcc/testsuite/g++.dg/concepts/inherit-ctor1.C b/gcc/testsuite/g++.dg/concepts/inherit-ctor1.C
index b137791..98c260c 100644
--- a/gcc/testsuite/g++.dg/concepts/inherit-ctor1.C
+++ b/gcc/testsuite/g++.dg/concepts/inherit-ctor1.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C = __is_class(T);
diff --git a/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C b/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C
index 6b7a7a4..76308ff 100644
--- a/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C
+++ b/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C() { return __is_class(T); }
diff --git a/gcc/testsuite/g++.dg/concepts/intro1.C b/gcc/testsuite/g++.dg/concepts/intro1.C
index 5f9bb7e..0dd9b64 100644
--- a/gcc/testsuite/g++.dg/concepts/intro1.C
+++ b/gcc/testsuite/g++.dg/concepts/intro1.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C = __is_class(T);
diff --git a/gcc/testsuite/g++.dg/concepts/intro2.C b/gcc/testsuite/g++.dg/concepts/intro2.C
index 206777d..5c6906c 100644
--- a/gcc/testsuite/g++.dg/concepts/intro2.C
+++ b/gcc/testsuite/g++.dg/concepts/intro2.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
#include <cassert>
diff --git a/gcc/testsuite/g++.dg/concepts/intro3.C b/gcc/testsuite/g++.dg/concepts/intro3.C
index f02f1be..c92338e 100644
--- a/gcc/testsuite/g++.dg/concepts/intro3.C
+++ b/gcc/testsuite/g++.dg/concepts/intro3.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename ... T>
concept bool C1 = true;
diff --git a/gcc/testsuite/g++.dg/concepts/intro4.C b/gcc/testsuite/g++.dg/concepts/intro4.C
index 0b275e1..5ddd162 100644
--- a/gcc/testsuite/g++.dg/concepts/intro4.C
+++ b/gcc/testsuite/g++.dg/concepts/intro4.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename ... T>
concept bool C1 = true;
diff --git a/gcc/testsuite/g++.dg/concepts/intro5.C b/gcc/testsuite/g++.dg/concepts/intro5.C
index bbfef7b..cb1c5da 100644
--- a/gcc/testsuite/g++.dg/concepts/intro5.C
+++ b/gcc/testsuite/g++.dg/concepts/intro5.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T, typename U = int>
concept bool C()
diff --git a/gcc/testsuite/g++.dg/concepts/intro6.C b/gcc/testsuite/g++.dg/concepts/intro6.C
index 233c5bc..b718d13 100644
--- a/gcc/testsuite/g++.dg/concepts/intro6.C
+++ b/gcc/testsuite/g++.dg/concepts/intro6.C
@@ -1,6 +1,6 @@
// PR c++/67003
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
namespace X {
template<class>
diff --git a/gcc/testsuite/g++.dg/concepts/intro7.C b/gcc/testsuite/g++.dg/concepts/intro7.C
index 343fe7a..0c452a7 100644
--- a/gcc/testsuite/g++.dg/concepts/intro7.C
+++ b/gcc/testsuite/g++.dg/concepts/intro7.C
@@ -1,6 +1,6 @@
// PR c++/66985
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <template <class> class T>
concept bool Valid = requires { typename T<int>; };
diff --git a/gcc/testsuite/g++.dg/concepts/locations1.C b/gcc/testsuite/g++.dg/concepts/locations1.C
index fbad42f..ea22743 100644
--- a/gcc/testsuite/g++.dg/concepts/locations1.C
+++ b/gcc/testsuite/g++.dg/concepts/locations1.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
struct S
{
diff --git a/gcc/testsuite/g++.dg/concepts/partial-concept-id1.C b/gcc/testsuite/g++.dg/concepts/partial-concept-id1.C
index 6b66b78..09c9d4f 100644
--- a/gcc/testsuite/g++.dg/concepts/partial-concept-id1.C
+++ b/gcc/testsuite/g++.dg/concepts/partial-concept-id1.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool Type = true;
diff --git a/gcc/testsuite/g++.dg/concepts/partial-concept-id2.C b/gcc/testsuite/g++.dg/concepts/partial-concept-id2.C
index 2c14576..089f40f 100644
--- a/gcc/testsuite/g++.dg/concepts/partial-concept-id2.C
+++ b/gcc/testsuite/g++.dg/concepts/partial-concept-id2.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// Make sure that we check partial concept ids
// with variable concepts.
diff --git a/gcc/testsuite/g++.dg/concepts/partial-spec5.C b/gcc/testsuite/g++.dg/concepts/partial-spec5.C
index bec6715..954c072 100644
--- a/gcc/testsuite/g++.dg/concepts/partial-spec5.C
+++ b/gcc/testsuite/g++.dg/concepts/partial-spec5.C
@@ -1,6 +1,6 @@
// PR c++/67138
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T>
concept bool _Auto = true;
diff --git a/gcc/testsuite/g++.dg/concepts/placeholder2.C b/gcc/testsuite/g++.dg/concepts/placeholder2.C
index 0c6f91a..f1c3b9c 100644
--- a/gcc/testsuite/g++.dg/concepts/placeholder2.C
+++ b/gcc/testsuite/g++.dg/concepts/placeholder2.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1 = sizeof(T) == 0;
diff --git a/gcc/testsuite/g++.dg/concepts/placeholder3.C b/gcc/testsuite/g++.dg/concepts/placeholder3.C
index d90e5cf..6b79ef6 100644
--- a/gcc/testsuite/g++.dg/concepts/placeholder3.C
+++ b/gcc/testsuite/g++.dg/concepts/placeholder3.C
@@ -1,6 +1,6 @@
// PR c++/66218
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T, class U>
concept bool Same = __is_same_as(T, U);
diff --git a/gcc/testsuite/g++.dg/concepts/placeholder4.C b/gcc/testsuite/g++.dg/concepts/placeholder4.C
index ab9d8e6..1645161 100644
--- a/gcc/testsuite/g++.dg/concepts/placeholder4.C
+++ b/gcc/testsuite/g++.dg/concepts/placeholder4.C
@@ -1,6 +1,6 @@
// PR c++/66218
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T, class U>
concept bool Same = __is_same_as(T, U);
diff --git a/gcc/testsuite/g++.dg/concepts/placeholder5.C b/gcc/testsuite/g++.dg/concepts/placeholder5.C
index 3f29c93..21a6b31 100644
--- a/gcc/testsuite/g++.dg/concepts/placeholder5.C
+++ b/gcc/testsuite/g++.dg/concepts/placeholder5.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T, class U>
concept bool Same = __is_same_as(T, U);
diff --git a/gcc/testsuite/g++.dg/concepts/placeholder6.C b/gcc/testsuite/g++.dg/concepts/placeholder6.C
index 20b9c93..c7f62d1 100644
--- a/gcc/testsuite/g++.dg/concepts/placeholder6.C
+++ b/gcc/testsuite/g++.dg/concepts/placeholder6.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <int I> struct B { static const int i = I; };
template <int I> concept bool Few = I < 10;
diff --git a/gcc/testsuite/g++.dg/concepts/pr65634.C b/gcc/testsuite/g++.dg/concepts/pr65634.C
index 5fcb38a..650d10e 100644
--- a/gcc/testsuite/g++.dg/concepts/pr65634.C
+++ b/gcc/testsuite/g++.dg/concepts/pr65634.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1() {
diff --git a/gcc/testsuite/g++.dg/concepts/pr65636.C b/gcc/testsuite/g++.dg/concepts/pr65636.C
index f927c9a..69091dc 100644
--- a/gcc/testsuite/g++.dg/concepts/pr65636.C
+++ b/gcc/testsuite/g++.dg/concepts/pr65636.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
using TD = int;
diff --git a/gcc/testsuite/g++.dg/concepts/pr65681.C b/gcc/testsuite/g++.dg/concepts/pr65681.C
index 67153d6..cf34911 100644
--- a/gcc/testsuite/g++.dg/concepts/pr65681.C
+++ b/gcc/testsuite/g++.dg/concepts/pr65681.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C = requires (T t) { t.mf(); };
diff --git a/gcc/testsuite/g++.dg/concepts/pr65848.C b/gcc/testsuite/g++.dg/concepts/pr65848.C
index ea3077d..76e6f6f 100644
--- a/gcc/testsuite/g++.dg/concepts/pr65848.C
+++ b/gcc/testsuite/g++.dg/concepts/pr65848.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// Performance test... This should be fast.
diff --git a/gcc/testsuite/g++.dg/concepts/pr67249.C b/gcc/testsuite/g++.dg/concepts/pr67249.C
index 382eba1..75f0ea0 100644
--- a/gcc/testsuite/g++.dg/concepts/pr67249.C
+++ b/gcc/testsuite/g++.dg/concepts/pr67249.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<class T> concept bool C1 = true;
template<class A, class B> struct Pair {};
diff --git a/gcc/testsuite/g++.dg/concepts/pr67595.C b/gcc/testsuite/g++.dg/concepts/pr67595.C
index 37adf93..33122d2 100644
--- a/gcc/testsuite/g++.dg/concepts/pr67595.C
+++ b/gcc/testsuite/g++.dg/concepts/pr67595.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class X> concept bool allocatable = requires{{new X}->X *; };
template <class X> concept bool semiregular = allocatable<X>;
diff --git a/gcc/testsuite/g++.dg/concepts/pr68434.C b/gcc/testsuite/g++.dg/concepts/pr68434.C
index 16868ba..ff6a898 100644
--- a/gcc/testsuite/g++.dg/concepts/pr68434.C
+++ b/gcc/testsuite/g++.dg/concepts/pr68434.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class>
concept bool C1 () {
diff --git a/gcc/testsuite/g++.dg/concepts/pr71127.C b/gcc/testsuite/g++.dg/concepts/pr71127.C
index 224eaa3..e76aec1 100644
--- a/gcc/testsuite/g++.dg/concepts/pr71127.C
+++ b/gcc/testsuite/g++.dg/concepts/pr71127.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<template<typename> class T>
concept bool C = T<int>::value;
diff --git a/gcc/testsuite/g++.dg/concepts/pr71128.C b/gcc/testsuite/g++.dg/concepts/pr71128.C
index a150e37..351a646 100644
--- a/gcc/testsuite/g++.dg/concepts/pr71128.C
+++ b/gcc/testsuite/g++.dg/concepts/pr71128.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C() { return true; }
diff --git a/gcc/testsuite/g++.dg/concepts/pr71131.C b/gcc/testsuite/g++.dg/concepts/pr71131.C
index 675d66d..8da43af 100644
--- a/gcc/testsuite/g++.dg/concepts/pr71131.C
+++ b/gcc/testsuite/g++.dg/concepts/pr71131.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<template<typename> class T>
concept bool C = true;
diff --git a/gcc/testsuite/g++.dg/concepts/pr71385.C b/gcc/testsuite/g++.dg/concepts/pr71385.C
index fb75425..66ca52b 100644
--- a/gcc/testsuite/g++.dg/concepts/pr71385.C
+++ b/gcc/testsuite/g++.dg/concepts/pr71385.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<class T>
concept bool Addable(){
diff --git a/gcc/testsuite/g++.dg/concepts/pr85065.C b/gcc/testsuite/g++.dg/concepts/pr85065.C
index 52a4264..72f2aca 100644
--- a/gcc/testsuite/g++.dg/concepts/pr85065.C
+++ b/gcc/testsuite/g++.dg/concepts/pr85065.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<int> concept bool C = true;
diff --git a/gcc/testsuite/g++.dg/concepts/template-parm11.C b/gcc/testsuite/g++.dg/concepts/template-parm11.C
index 257e7c6..b376a49 100644
--- a/gcc/testsuite/g++.dg/concepts/template-parm11.C
+++ b/gcc/testsuite/g++.dg/concepts/template-parm11.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool NameProvider()
diff --git a/gcc/testsuite/g++.dg/concepts/template-parm12.C b/gcc/testsuite/g++.dg/concepts/template-parm12.C
index cb3e2c6..81d0818 100644
--- a/gcc/testsuite/g++.dg/concepts/template-parm12.C
+++ b/gcc/testsuite/g++.dg/concepts/template-parm12.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// Conceptized version of template/ttp23.C
template <class T> concept bool Foo = true;
diff --git a/gcc/testsuite/g++.dg/concepts/template-parm2.C b/gcc/testsuite/g++.dg/concepts/template-parm2.C
index d708fd0..dc6983a 100644
--- a/gcc/testsuite/g++.dg/concepts/template-parm2.C
+++ b/gcc/testsuite/g++.dg/concepts/template-parm2.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1 = __is_same_as(T, int);
diff --git a/gcc/testsuite/g++.dg/concepts/template-parm3.C b/gcc/testsuite/g++.dg/concepts/template-parm3.C
index 028149c..2e6bd2c 100644
--- a/gcc/testsuite/g++.dg/concepts/template-parm3.C
+++ b/gcc/testsuite/g++.dg/concepts/template-parm3.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1 = __is_same_as(T, int);
diff --git a/gcc/testsuite/g++.dg/concepts/template-parm4.C b/gcc/testsuite/g++.dg/concepts/template-parm4.C
index d93dbc7..8f8ad63 100644
--- a/gcc/testsuite/g++.dg/concepts/template-parm4.C
+++ b/gcc/testsuite/g++.dg/concepts/template-parm4.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1 = __is_same_as(T, int);
diff --git a/gcc/testsuite/g++.dg/concepts/template-template-parm1.C b/gcc/testsuite/g++.dg/concepts/template-template-parm1.C
index d701859..019a933 100644
--- a/gcc/testsuite/g++.dg/concepts/template-template-parm1.C
+++ b/gcc/testsuite/g++.dg/concepts/template-template-parm1.C
@@ -1,6 +1,6 @@
// PR c++/66937
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
#include <tuple>
diff --git a/gcc/testsuite/g++.dg/concepts/var-concept1.C b/gcc/testsuite/g++.dg/concepts/var-concept1.C
index 21a4915..3a3b340 100644
--- a/gcc/testsuite/g++.dg/concepts/var-concept1.C
+++ b/gcc/testsuite/g++.dg/concepts/var-concept1.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1 = __is_class(T);
diff --git a/gcc/testsuite/g++.dg/concepts/var-concept2.C b/gcc/testsuite/g++.dg/concepts/var-concept2.C
index 5e1faec..0ef2322 100644
--- a/gcc/testsuite/g++.dg/concepts/var-concept2.C
+++ b/gcc/testsuite/g++.dg/concepts/var-concept2.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1 = __is_class(T);
diff --git a/gcc/testsuite/g++.dg/concepts/var-concept3.C b/gcc/testsuite/g++.dg/concepts/var-concept3.C
index 144c0ea..6fd96a5 100644
--- a/gcc/testsuite/g++.dg/concepts/var-concept3.C
+++ b/gcc/testsuite/g++.dg/concepts/var-concept3.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1 = __is_class(T);
diff --git a/gcc/testsuite/g++.dg/concepts/var-concept4.C b/gcc/testsuite/g++.dg/concepts/var-concept4.C
index a7839ee..7ae9f36 100644
--- a/gcc/testsuite/g++.dg/concepts/var-concept4.C
+++ b/gcc/testsuite/g++.dg/concepts/var-concept4.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T, typename U>
concept bool Same = __is_same_as(T, U);
diff --git a/gcc/testsuite/g++.dg/concepts/var-concept5.C b/gcc/testsuite/g++.dg/concepts/var-concept5.C
index d8fa298..cc7f4af 100644
--- a/gcc/testsuite/g++.dg/concepts/var-concept5.C
+++ b/gcc/testsuite/g++.dg/concepts/var-concept5.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T1, typename T2>
concept bool C1 = true;
diff --git a/gcc/testsuite/g++.dg/concepts/var-concept6.C b/gcc/testsuite/g++.dg/concepts/var-concept6.C
index 80984a7..d2270df 100644
--- a/gcc/testsuite/g++.dg/concepts/var-concept6.C
+++ b/gcc/testsuite/g++.dg/concepts/var-concept6.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T>
concept int C = true; // { dg-error "bool" }
diff --git a/gcc/testsuite/g++.dg/concepts/var-concept7.C b/gcc/testsuite/g++.dg/concepts/var-concept7.C
index 2cfe266..026fe9f 100644
--- a/gcc/testsuite/g++.dg/concepts/var-concept7.C
+++ b/gcc/testsuite/g++.dg/concepts/var-concept7.C
@@ -1,6 +1,6 @@
// PR c++/85133
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename> concept bool C; // { dg-error "no initializer" }
diff --git a/gcc/testsuite/g++.dg/concepts/var-templ2.C b/gcc/testsuite/g++.dg/concepts/var-templ2.C
index 1b8890a..2eb419a 100644
--- a/gcc/testsuite/g++.dg/concepts/var-templ2.C
+++ b/gcc/testsuite/g++.dg/concepts/var-templ2.C
@@ -1,6 +1,6 @@
// PR c++/67139
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T>
constexpr typename T::type::value_type _v = T::type::value;
diff --git a/gcc/testsuite/g++.dg/concepts/var-templ3.C b/gcc/testsuite/g++.dg/concepts/var-templ3.C
index cc5ee5f..662511e 100644
--- a/gcc/testsuite/g++.dg/concepts/var-templ3.C
+++ b/gcc/testsuite/g++.dg/concepts/var-templ3.C
@@ -1,6 +1,6 @@
// PR c++/68666
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
struct A {
template <class>
diff --git a/gcc/testsuite/g++.dg/concepts/variadic1.C b/gcc/testsuite/g++.dg/concepts/variadic1.C
index c3bc7f6..c590f28 100644
--- a/gcc/testsuite/g++.dg/concepts/variadic1.C
+++ b/gcc/testsuite/g++.dg/concepts/variadic1.C
@@ -1,6 +1,6 @@
// PR c++/66712
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T, class...Args>
concept bool _Constructible_ =
diff --git a/gcc/testsuite/g++.dg/concepts/variadic2.C b/gcc/testsuite/g++.dg/concepts/variadic2.C
index 7b22009..1776b95 100644
--- a/gcc/testsuite/g++.dg/concepts/variadic2.C
+++ b/gcc/testsuite/g++.dg/concepts/variadic2.C
@@ -1,5 +1,5 @@
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T> concept bool Copyable = requires (T t) { T(t); };
template <class T> concept bool Constructable = requires { T(); };
diff --git a/gcc/testsuite/g++.dg/concepts/variadic3.C b/gcc/testsuite/g++.dg/concepts/variadic3.C
index bd2f381..07c2401 100644
--- a/gcc/testsuite/g++.dg/concepts/variadic3.C
+++ b/gcc/testsuite/g++.dg/concepts/variadic3.C
@@ -1,6 +1,6 @@
// PR c++/70036
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T> concept bool C = true;
diff --git a/gcc/testsuite/g++.dg/concepts/variadic4.C b/gcc/testsuite/g++.dg/concepts/variadic4.C
index d6eea49..1dfa2e6 100644
--- a/gcc/testsuite/g++.dg/concepts/variadic4.C
+++ b/gcc/testsuite/g++.dg/concepts/variadic4.C
@@ -1,6 +1,6 @@
// PR c++/73456
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename...> struct list {};
diff --git a/gcc/testsuite/g++.dg/contracts/backtrace_handler/Makefile b/gcc/testsuite/g++.dg/contracts/backtrace_handler/Makefile
new file mode 100644
index 0000000..4f01a95
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/backtrace_handler/Makefile
@@ -0,0 +1,13 @@
+CXXFLAGS=--std=c++17 -g
+
+default: assert_fail libhandle_contract_violation.so
+
+run: default
+ LD_PRELOAD=./libhandle_contract_violation.so ./assert_fail
+
+./libhandle_contract_violation.so: ./handle_contract_violation.cpp
+ ${CXX} ${CXXFLAGS} -shared -fPIC -o $@ $<
+
+clean:
+ rm -fr ./libhandle_contract_violation.so ./assert_fail
+
diff --git a/gcc/testsuite/g++.dg/contracts/backtrace_handler/README b/gcc/testsuite/g++.dg/contracts/backtrace_handler/README
new file mode 100644
index 0000000..df729f0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/backtrace_handler/README
@@ -0,0 +1,12 @@
+build and install gcc to $prefix, then to see the raw backtrace info run:
+LD_LIBRARY_PATH=$prefix/lib64 CXX=$prefix/bin/g++ make run
+
+for a filtered view using addr2line, see ./prettytrace.sh:
+LD_LIBRARY_PATH=$prefix/lib64 CXX=$prefix/bin/g++ make run |& ./prettytrace.sh
+
+prettytrace.sh relies on addr2line and c++filt to lookup and demangle names,
+and misc coreutils
+
+example_out.txt has an example of the raw output while example_pretty.txt
+shows the corresponding prettified output
+
diff --git a/gcc/testsuite/g++.dg/contracts/backtrace_handler/assert_fail.cpp b/gcc/testsuite/g++.dg/contracts/backtrace_handler/assert_fail.cpp
new file mode 100644
index 0000000..08c64bc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/backtrace_handler/assert_fail.cpp
@@ -0,0 +1,23 @@
+void fun1() {
+ int x = 0;
+ [[ assert: x < 0 ]];
+}
+namespace tns {
+ void fun2() {
+ fun1();
+ }
+}
+template<typename T>
+void fun3(T a) {
+ tns::fun2();
+}
+void fun4() {
+ fun3(5);
+}
+int main(int, char**) {
+ void (*fp)() = nullptr;
+ fp = fun4;
+ fp();
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/backtrace_handler/example_out.txt b/gcc/testsuite/g++.dg/contracts/backtrace_handler/example_out.txt
new file mode 100644
index 0000000..903ef22
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/backtrace_handler/example_out.txt
@@ -0,0 +1,12 @@
+LD_PRELOAD=./libhandle_contract_violation.so ./assert_fail
+contract violation: assert_fail.cpp:3: fun1::x < 0 is false [with contract level=default]
+violation occurs here:
+./assert_fail[0x4011ad]
+./assert_fail[0x4011e0]
+./assert_fail[0x401230]
+./assert_fail[0x4011f1]
+./assert_fail[0x401219]
+/usr/lib/libc.so.6(__libc_start_main+0xf3)[0x7f26e4fa9223]
+./assert_fail[0x4010be]
+[0x0]
+end of violation
diff --git a/gcc/testsuite/g++.dg/contracts/backtrace_handler/example_pretty.txt b/gcc/testsuite/g++.dg/contracts/backtrace_handler/example_pretty.txt
new file mode 100644
index 0000000..9d5d481
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/backtrace_handler/example_pretty.txt
@@ -0,0 +1,8 @@
+LD_PRELOAD=./libhandle_contract_violation.so ./assert_fail
+contract violation: assert_fail.cpp:3: fun1::x < 0 is false [with contract level=default]
+violation occurs here:
+ assert_fail.cpp:fun1():4
+ assert_fail.cpp:tns::fun2():8
+ assert_fail.cpp:void fun3<int>(int):13
+ assert_fail.cpp:fun4():16
+ assert_fail.cpp:main:21
diff --git a/gcc/testsuite/g++.dg/contracts/backtrace_handler/handle_contract_violation.cpp b/gcc/testsuite/g++.dg/contracts/backtrace_handler/handle_contract_violation.cpp
new file mode 100644
index 0000000..bfbb97e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/backtrace_handler/handle_contract_violation.cpp
@@ -0,0 +1,26 @@
+#include <iostream>
+#include <contract>
+#include <execinfo.h>
+#include <unistd.h>
+
+static constexpr int MAX_BACKTRACE_DEPTH = 128;
+
+void handle_contract_violation(const std::contract_violation &violation) {
+ size_t _backtraceSize{0};
+ void *_backtrace[MAX_BACKTRACE_DEPTH]{};
+
+ _backtraceSize = backtrace(_backtrace, MAX_BACKTRACE_DEPTH);
+ if(_backtraceSize == MAX_BACKTRACE_DEPTH)
+ std::cerr << "warning: backtrace may have been truncated" << std::endl;
+
+ std::cerr << "contract violation: " << violation.file_name()
+ << ":" << violation.line_number()
+ << ": " << violation.comment() << " is false"
+ << " [with contract level=" << violation.assertion_level() << "]" << std::endl
+ << "violation occurs here:" << std::endl;
+ // skip the stack frame of handle_contract_violation and
+ // on_contract_violation to get to wherever the assert was
+ backtrace_symbols_fd(_backtrace + 2, _backtraceSize - 1, STDERR_FILENO);
+ std::cerr << "end of violation" << std::endl;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/backtrace_handler/prettytrace.sh b/gcc/testsuite/g++.dg/contracts/backtrace_handler/prettytrace.sh
new file mode 100755
index 0000000..1978cd1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/backtrace_handler/prettytrace.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+inViolation="false"
+sed 's/^/:/' /dev/stdin | while read -r line; do
+ line="$(echo "$line" | sed 's/^://')"
+
+ if [[ "${inViolation}" == "false" ]]; then
+ echo "$line"
+ if [[ -n "$(echo "$line" | grep 'violation occurs here:')" ]]; then
+ inViolation="true"
+ fi
+ continue
+ fi
+
+ if [[ -n "$(echo "$line" | grep 'end of violation')" ]]; then
+ inViolation="false"
+ continue
+ fi
+
+ addr="$(echo "$line" | sed -r 's/.*\[0x([a-f0-9]+)\]$/\1/')"
+ bin="$(echo "$line" | sed -r 's/^([^([]*).*/\1/')"
+ [[ -n "${bin}" ]] || continue
+ t="$(addr2line -e "$bin" "$addr" -f)"
+ file="$(echo "$t" | tail -1 | tr ':' '\n' | head -1)"
+ file="$(echo "$file" | sed -r "s:^$(pwd)/?::")"
+ line="$(echo "$t" | tail -1 | tr ':' '\n' | tail -1 | cut -d' ' -f1)"
+ func="$(echo "$t" | head -1 | c++filt)"
+ [[ $file != "??" ]] && echo " $file:$func:$line"
+done
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-access1.C b/gcc/testsuite/g++.dg/contracts/contracts-access1.C
new file mode 100644
index 0000000..a3a2982
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-access1.C
@@ -0,0 +1,128 @@
+// ensure that that preconditions can access public, protected, and private
+// members of the current and base classes
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+
+struct Base
+{
+ int pub{-1};
+
+ virtual int b()
+ [[ pre: pub > 0 ]]
+ [[ pre: pro > 0 ]]
+ [[ pre: pri > 0 ]]
+ {
+ return pub * pro * pri;
+ }
+
+ protected:
+ int pro{-1};
+ int pri{-1};
+};
+
+struct Child : Base
+{
+ int fun()
+ [[ pre: pub > 0 ]]
+ [[ pre: pro > 0 ]]
+ [[ pre: pri > 0 ]]
+ {
+ return pub * pro;
+ }
+};
+
+struct VChild : Base
+{
+ int b()
+ [[ pre: pub > 0 ]]
+ [[ pre: pro > 0 ]]
+ [[ pre: pri > 0 ]]
+ {
+ return pub * pro;
+ }
+};
+
+template<typename B>
+struct TChild : B
+{
+ int fun()
+ [[ pre: B::pub > 0 ]]
+ [[ pre: B::pro > 0 ]]
+ [[ pre: B::pri > 0 ]]
+ {
+ return B::pub * B::pro;
+ }
+};
+
+struct PubBase
+{
+ int pub{-1};
+ int pro{-1};
+ int pri{-1};
+};
+
+struct PubChild : PubBase
+{
+ int fun()
+ [[ pre: pub > 0 ]]
+ [[ pre: pro > 0 ]]
+ [[ pre: pri > 0 ]]
+ {
+ return pub * pro;
+ }
+};
+
+template<typename B>
+struct TPubChild : B
+{
+ int fun()
+ [[ pre: B::pub > 0 ]]
+ [[ pre: B::pro > 0 ]]
+ [[ pre: B::pri > 0 ]]
+ {
+ return B::pub * B::pro;
+ }
+};
+
+int main()
+{
+ Base base{};
+ base.b();
+
+ Child child{};
+ child.fun();
+
+ VChild vchild{};
+ vchild.b();
+
+ TChild<Base> tchild{};
+ tchild.fun();
+
+ PubChild pubchild{};
+ pubchild.fun();
+
+ TPubChild<PubBase> tpubchild;
+ tpubchild.fun();
+
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 11 Base::b .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 12 Base::b .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 13 Base::b .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 26 Child::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 27 Child::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 28 Child::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 37 VChild::b .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 38 VChild::b .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 39 VChild::b .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 49 TChild<Base>::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 50 TChild<Base>::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 51 TChild<Base>::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 67 PubChild::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 68 PubChild::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 69 PubChild::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 79 TPubChild<PubBase>::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 80 TPubChild<PubBase>::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 81 TPubChild<PubBase>::fun .*(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-assume1.C b/gcc/testsuite/g++.dg/contracts/contracts-assume1.C
new file mode 100644
index 0000000..71388501
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-assume1.C
@@ -0,0 +1,30 @@
+// test that assumed contracts do instatiate templates
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+template<typename T>
+int f(T t)
+{
+ return -t;
+}
+
+int dummy()
+{
+ [[ assert assume: f(1.0) > 0 ]];
+ return -1;
+}
+
+template<>
+int f(double t) // { dg-error "specialization of.*after instantiation" }
+{
+ return -1.0;
+}
+
+int main()
+{
+ dummy();
+ f(1);
+ f(1.0);
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-assume2.C b/gcc/testsuite/g++.dg/contracts/contracts-assume2.C
new file mode 100644
index 0000000..af163ed
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-assume2.C
@@ -0,0 +1,34 @@
+// ensure that assert contracts can be turned into compile time assumptions
+// and that they can be used for optimization.
+//
+// Even though x == -1, the assert contract tells the compiler that it is
+// safe to assume the x <= 0 branch is never taken fun can be transformed into
+// just
+// printf("%d: test x>0\n", x);
+// return 0;
+// we ensure this by matching on the output and expecting a 0 return code from
+// main -- unlike contracts-ignore2 which expects a failing return code
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-role=default:never,assume,ignore -O1" }
+#include <cstdio>
+
+int fun(int x) {
+ [[assert audit: x > 0]];
+ if(x <= 0)
+ {
+ printf("%d: test x<=0 opt out\n", x);
+ return -1;
+ }
+ else
+ {
+ printf("%d: test x>0\n", x);
+ return 0;
+ }
+}
+
+int main(int, char**) {
+ volatile int x = -1;
+ return fun(x);
+}
+
+// { dg-output "-1: test x>0(\n|\r\n|\r)*" }
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-assume3.C b/gcc/testsuite/g++.dg/contracts/contracts-assume3.C
new file mode 100644
index 0000000..8dad6bb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-assume3.C
@@ -0,0 +1,19 @@
+// test that assumed contracts that reference undefined entities do not cause
+// a link failure
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts" }
+
+int f(int t);
+
+int dummy()
+{
+ [[ assert assume: f(1) > 0 ]];
+ return -1;
+}
+
+int main()
+{
+ dummy();
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-assume4.C b/gcc/testsuite/g++.dg/contracts/contracts-assume4.C
new file mode 100644
index 0000000..7954f53
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-assume4.C
@@ -0,0 +1,19 @@
+// test that assumed constexpr contracts that reference undefined entities do
+// not cause constexpr eval failure
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts" }
+
+constexpr int f(int t); // { dg-warning "used but never defined" }
+
+constexpr int dummy()
+{
+ [[ assert assume: f(1) > 0 ]];
+ return -1;
+}
+
+int main()
+{
+ constexpr int n = dummy();
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-assume5.C b/gcc/testsuite/g++.dg/contracts/contracts-assume5.C
new file mode 100644
index 0000000..372c0de
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-assume5.C
@@ -0,0 +1,34 @@
+// test that assumed constexpr contracts that reference defined entities, or
+// undefined entities in unevaluated context, cause constexpr eval failure when
+// the predicate is constexpr false
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+constexpr int f(int t)
+{
+ return -1;
+}
+
+constexpr int dummy()
+{
+ [[ assert assume: f(1) > 0 ]];
+ return -1;
+}
+
+constexpr int undef(int t);
+
+constexpr int dummy2()
+{
+ [[ assert assume: sizeof(decltype(undef(1))) < 0 ]];
+ return -1;
+}
+
+int main()
+{
+ constexpr int n = dummy(); // { dg-message "in .constexpr. expansion" }
+ // { dg-error "contract predicate" "" { target *-*-* } 14 }
+ constexpr int m = dummy2(); // { dg-message "in .constexpr. expansion" }
+ // { dg-error "contract predicate" "" { target *-*-* } 22 }
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-assume6.C b/gcc/testsuite/g++.dg/contracts/contracts-assume6.C
new file mode 100644
index 0000000..931c4d0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-assume6.C
@@ -0,0 +1,61 @@
+// ensure that non-defined entities in assume contracts do not error
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+template<typename T>
+T id2(T n);
+
+int fun(int n)
+ [[ pre assume: id2(n) > 0 ]]
+ [[ pre: n > 0 ]]
+{
+ return -n;
+}
+
+template<typename T>
+T tfun(T n)
+ [[ pre assume: id2(n) > 0 ]]
+ [[ pre: n > 0 ]]
+{
+ return -n;
+}
+
+template<typename T>
+constexpr T id(T n); // { dg-warning "used but never defined" }
+
+template<typename T>
+constexpr T cfun(T n)
+ [[ pre assume: id(n) > 0 ]]
+ [[ pre: id(n) > 0 ]] // { dg-error "used before its definition" }
+{
+ return -n;
+}
+
+template<typename T>
+constexpr T id3(T n)
+{
+ return n;
+}
+
+template<typename T>
+constexpr T cfun2(T n)
+ [[ pre assume: id3(n) > 0 ]] // { dg-error "contract predicate" }
+{
+ return -n;
+}
+
+template<typename T>
+constexpr T cfun3(T n)
+ [[ pre: id3(n) > 0 ]] // { dg-error "contract predicate" }
+{
+ return -n;
+}
+
+int main() {
+ constexpr int n = cfun(-5);
+ constexpr int n2 = cfun2(-5);
+ constexpr int n3 = cfun3(-5);
+ fun(-5);
+ tfun(-5);
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-comdat1.C b/gcc/testsuite/g++.dg/contracts/contracts-comdat1.C
new file mode 100644
index 0000000..3384ae6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-comdat1.C
@@ -0,0 +1,19 @@
+// Contract condition functions should be local symbols in a comdat group with
+// the guarded function.
+
+// { dg-do compile { target { c++20 && comdat_group } } }
+// { dg-additional-options -fcontracts }
+// { dg-final { scan-assembler-not "_Z1fi.pre,comdat" } }
+// { dg-final { scan-assembler-not {(weak|globl)[^\n]*_Z1fi.pre} } }
+
+inline int f(int i)
+ [[ pre: i > 0 ]]
+{
+ return i;
+}
+
+int main()
+{
+ if (f(42) != 42)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-config1.C b/gcc/testsuite/g++.dg/contracts/contracts-config1.C
new file mode 100644
index 0000000..9e32bac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-config1.C
@@ -0,0 +1,36 @@
+// Small test to ensure that the level and role information printed by various
+// contract configurations is correct.
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-role=default:maybe,maybe,ignore" }
+
+int fun(int n)
+ [[ post default r: r > 0 ]]
+{
+ return -n;
+}
+
+int main(int, char **)
+{
+ [[ assert default: false ]];
+ [[ assert: false ]];
+ [[ assert audit: false ]];
+ [[ assert default %new_role: false ]];
+ [[ assert %new_role: false ]];
+ [[ assert audit %new_role: false ]];
+ [[ assert check_maybe_continue: false ]];
+ [[ assert %default: false ]];
+ [[ assert audit %default: false ]];
+ fun(5);
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*main false default default 1.*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*main false default default 1.*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*main false audit default 1.*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*main false default new_role 1.*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*main false default new_role 1.*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*main false audit new_role 1.*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*main false 1.*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*main false default default 1.*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*main false audit default 1.*(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-constexpr1.C b/gcc/testsuite/g++.dg/contracts/contracts-constexpr1.C
new file mode 100644
index 0000000..4c11135
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-constexpr1.C
@@ -0,0 +1,74 @@
+// ensure that passing pre/post do not affect constexpr functions
+// ensure that failing pre/post generate an error at runtime in constexpr funcs
+// { dg-do run }
+// { dg-options "-std=c++20 -fcontracts -fcontract-continuation-mode=on" }
+
+constexpr int wfun(int a)
+ [[ pre: a > 0 ]]
+ [[ post r: r > 0 ]]
+{
+ return a;
+}
+
+constexpr int ffun(int a)
+ [[ pre: a > 0 ]]
+ [[ post r: r > 0 ]]
+{
+ return a;
+}
+
+template<typename T>
+constexpr int tfun(T a)
+ [[ pre: a > 0 ]]
+ [[ post r: r > 0 ]]
+{
+ return a;
+}
+
+template<typename T>
+constexpr int wtfun(T a)
+ [[ pre: a > 0 ]]
+ [[ post r: r > 0 ]]
+{
+ return a;
+}
+
+template<typename T>
+constexpr int ftfun(T a)
+ [[ pre: a > 0 ]]
+ [[ post r: r > 0 ]]
+{
+ return a;
+}
+
+constexpr int explicitfn(int a)
+ [[ pre ignore: a > 0 ]]
+ [[ pre check_maybe_continue: a > 0 ]]
+ [[ post ignore r: r > 0 ]]
+ [[ post check_maybe_continue r: r > 0 ]]
+{
+ return a;
+}
+
+int main(int, char **) {
+ constexpr int a = wfun(10);
+ int b = ffun(-10);
+ constexpr int c = wtfun(10);
+ int d = ftfun(-10);
+
+ int e = explicitfn(-10);
+
+ int z = ftfun(-10.0);
+
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 14 ffun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 15 ffun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 38 ftfun<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 39 ftfun<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 46 explicitfn .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 48 explicitfn .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 38 ftfun<double> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 39 ftfun<double> .*(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-constexpr2.C b/gcc/testsuite/g++.dg/contracts/contracts-constexpr2.C
new file mode 100644
index 0000000..d0d41f0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-constexpr2.C
@@ -0,0 +1,58 @@
+// ensure that failing pre/post can fail at constexpr time
+// { dg-do compile }
+// { dg-options "-std=c++20 -fcontracts -fcontract-continuation-mode=on" }
+
+constexpr int ffun(int a)
+ [[ pre: a > 0 ]]
+ [[ post r: r > 10 ]]
+{
+ return a;
+}
+
+template<typename T>
+constexpr int ftfun(T a)
+ [[ pre: a > 0 ]]
+ [[ post r: r > 10 ]]
+{
+ return a;
+}
+
+constexpr int explicitfn(int a)
+ [[ pre ignore: a > 0 ]]
+ [[ pre check_maybe_continue: a > 0 ]]
+ [[ post ignore r: r > 10 ]]
+ [[ post check_maybe_continue r: r > 10 ]]
+{
+ return a;
+}
+
+template<typename T>
+constexpr int ftfun2(T a)
+ [[ pre: a > 0 ]]
+ [[ post r: r > 10 ]]
+{
+ return a;
+}
+
+int main(int, char **) {
+ constexpr int a = ffun(-10);
+ // { dg-error "contract predicate" "" { target *-*-* } 6 }
+ constexpr int b = ftfun(-10);
+ // { dg-error "contract predicate" "" { target *-*-* } 14 }
+ constexpr int c = explicitfn(-10);
+ // { dg-error "contract predicate" "" { target *-*-* } 22 }
+ constexpr int d = ftfun2(-10.0);
+ // { dg-error "contract predicate" "" { target *-*-* } 31 }
+
+ constexpr int e = ffun(5);
+ // { dg-error "contract predicate" "" { target *-*-* } 7 }
+ constexpr int f = ftfun(5);
+ // { dg-error "contract predicate" "" { target *-*-* } 15 }
+ constexpr int g = explicitfn(5);
+ // { dg-error "contract predicate" "" { target *-*-* } 24 }
+ constexpr int h = ftfun2(5.5);
+ // { dg-error "contract predicate" "" { target *-*-* } 32 }
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-constexpr3.C b/gcc/testsuite/g++.dg/contracts/contracts-constexpr3.C
new file mode 100644
index 0000000..8826220
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-constexpr3.C
@@ -0,0 +1,10 @@
+// An assumed contract shouldn't break constant evaluation.
+
+// { dg-do compile { target c++20 } }
+// { dg-additional-options -fcontracts }
+
+bool b;
+
+constexpr int f() [[ pre assume: b ]] { return 42; }
+
+static_assert (f() > 0);
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-conversion1.C b/gcc/testsuite/g++.dg/contracts/contracts-conversion1.C
new file mode 100644
index 0000000..ff5e23f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-conversion1.C
@@ -0,0 +1,19 @@
+// Test to ensure that diagnostic location for condition conversion is in the
+// right place.
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+
+template<typename T>
+void fn()
+ [[ pre: T{} ]] // { dg-error "no match" }
+{
+}
+
+struct Z { };
+
+int main(int, char**) {
+ fn<int>();
+ fn<Z>();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-ctor-dtor1.C b/gcc/testsuite/g++.dg/contracts/contracts-ctor-dtor1.C
new file mode 100644
index 0000000..bcd6096
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-ctor-dtor1.C
@@ -0,0 +1,177 @@
+// Tests to ensure that contracts are properly emitted for constructors,
+// destructors, and their intersection with templates.
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+bool pre_{false}, post_{false};
+bool delegate_{false};
+
+struct S
+{
+ S() [[ pre: pre_ ]] [[ post: post_ ]];
+ ~S() [[ pre: pre_ ]] [[ post: post_ ]];
+};
+
+S::S() { return; }
+S::~S() { return; }
+
+struct SInline
+{
+ SInline() [[ pre: pre_ ]] [[ post: post_ ]] { return; }
+ ~SInline() [[ pre: pre_ ]] [[ post: post_ ]] { return; }
+};
+
+struct SDelegate0
+{
+ SDelegate0(int) [[ pre: pre_ ]] [[ post: post_ ]] { return; }
+ SDelegate0() : SDelegate0(0) { return; }
+ ~SDelegate0() [[ pre: pre_ ]] [[ post: post_ ]] { return; }
+};
+
+struct SDelegate1
+{
+ SDelegate1(int) { return; }
+ SDelegate1() [[ pre: pre_ ]] [[ post: post_ ]] : SDelegate1(0) { return; }
+ ~SDelegate1() [[ pre: pre_ ]] [[ post: post_ ]] { return; }
+};
+
+struct SDelegate2
+{
+ SDelegate2(int) [[ pre: pre_ ]] [[ post: post_ ]] { return; }
+ SDelegate2() [[ pre: pre_ && delegate_ ]] [[ post: post_ && delegate_ ]] : SDelegate2(0) { return; }
+ ~SDelegate2() [[ pre: pre_ ]] [[ post: post_ ]] { return; }
+};
+
+struct SDelegate3
+{
+ SDelegate3(int) [[ pre: pre_ ]] [[ post: post_ ]] { return; }
+ SDelegate3() [[ pre: pre_ && delegate_ ]] [[ post: post_ && delegate_ ]] : SDelegate3(0) { return; }
+ ~SDelegate3() [[ pre: pre_ ]] [[ post: post_ ]] { return; }
+};
+
+template<typename T>
+struct S1
+{
+ S1() [[ pre: pre_ ]] [[ post: post_ ]] { }
+};
+
+struct S2
+{
+ template<typename T>
+ S2(T) [[ pre: pre_ ]] [[ post: post_ ]] { }
+};
+
+template<typename T>
+struct S3
+{
+ template<typename S>
+ S3(S) [[ pre: pre_ ]] [[ post: post_ ]] { }
+};
+
+struct G0
+{
+ G0() [[ post: x > 0 ]] {}
+ ~G0() [[ pre: x > 0 ]] {}
+ int x{-1};
+};
+
+struct G1
+{
+ G1() [[ post: this->x > 0 ]] {}
+ ~G1() [[ pre: this->x > 0 ]] {}
+ int x{-1};
+};
+
+int x{-1};
+
+struct G2
+{
+ G2() [[ pre: ::x > 0 ]] {}
+ ~G2() [[ post: ::x > 0 ]] {}
+ int x{1};
+};
+
+void test0()
+{
+ S s;
+ SInline si;
+ SDelegate0 sd0;
+ SDelegate1 sd1;
+ SDelegate2 sd2;
+ SDelegate3 sd3;
+ S1<int> s1_i;
+ S1<double> s1_d;
+ S2 s2_i{1};
+ S2 s2_d{.1};
+ S3<int> s3_i_i{1};
+ S3<int> s3_i_d{.1};
+ S3<double> s3_d_i{1};
+ S3<double> s3_d_d{.1};
+}
+
+void test1()
+{
+ G0 g0;
+ G1 g1;
+ G2 g2;
+}
+
+int main(int, char**)
+{
+ test0();
+ test1();
+ return 0;
+};
+
+// test0
+// { dg-output "default std::handle_contract_violation called: .*.C 11 S::S .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 11 S::S .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 20 SInline::SInline .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 20 SInline::SInline .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 26 SDelegate0::SDelegate0 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 26 SDelegate0::SDelegate0 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 34 SDelegate1::SDelegate1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 34 SDelegate1::SDelegate1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 41 SDelegate2::SDelegate2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 40 SDelegate2::SDelegate2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 40 SDelegate2::SDelegate2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 41 SDelegate2::SDelegate2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 48 SDelegate3::SDelegate3 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 47 SDelegate3::SDelegate3 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 47 SDelegate3::SDelegate3 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 48 SDelegate3::SDelegate3 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 55 S1<int>::S1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 55 S1<int>::S1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 55 S1<double>::S1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 55 S1<double>::S1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 61 S2::S2<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 61 S2::S2<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 61 S2::S2<double> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 61 S2::S2<double> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 68 S3<int>::S3<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 68 S3<int>::S3<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 68 S3<int>::S3<double> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 68 S3<int>::S3<double> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 68 S3<double>::S3<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 68 S3<double>::S3<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 68 S3<double>::S3<double> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 68 S3<double>::S3<double> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 49 SDelegate3::~SDelegate3 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 49 SDelegate3::~SDelegate3 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 42 SDelegate2::~SDelegate2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 42 SDelegate2::~SDelegate2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 35 SDelegate1::~SDelegate1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 35 SDelegate1::~SDelegate1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 28 SDelegate0::~SDelegate0 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 28 SDelegate0::~SDelegate0 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 21 SInline::~SInline .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 21 SInline::~SInline .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 12 S::~S .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 12 S::~S .*(\n|\r\n|\r)*" }
+
+// test1
+// { dg-output "default std::handle_contract_violation called: .*.C 73 G0::G0 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 80 G1::G1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 81 G1::~G1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 74 G0::~G0 .*(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-ctor-dtor2.C b/gcc/testsuite/g++.dg/contracts/contracts-ctor-dtor2.C
new file mode 100644
index 0000000..ba3b767
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-ctor-dtor2.C
@@ -0,0 +1,35 @@
+// Tests to ensure that an invalid this parm cannot be used in pre on ctors or
+// in post on dtors.
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+struct F0
+{
+ F0() [[ pre: x > 0 ]]; // { dg-error "invalid use of member" }
+ ~F0() [[ post: x > 0 ]]; // { dg-error "invalid use of member" }
+ int x{-1};
+};
+
+struct F1
+{
+ F1() [[ pre: this->x > 0 ]]; // { dg-error "may not be used" }
+ ~F1() [[ post: this->x > 0 ]]; // { dg-error "may not be used" }
+ int x{-1};
+};
+
+struct F2
+{
+ F2()
+ [[ post ret: false ]] // { dg-error "does not return a value" }
+ {
+ }
+ ~F2()
+ [[ post r: false ]] // { dg-error "does not return a value" }
+ {
+ }
+ void f()
+ [[ post r: false ]] // { dg-error "does not return a value" }
+ {
+ }
+};
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-cv1.C b/gcc/testsuite/g++.dg/contracts/contracts-cv1.C
new file mode 100644
index 0000000..8266b4f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-cv1.C
@@ -0,0 +1,37 @@
+// Tests to ensure that contracts have a properly cv qualified this
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+struct S
+{
+ int g() const { return x_; }
+ int f() { return x_; }
+
+ void mem_c() const
+ [[ pre: f() ]] // { dg-error "discards qualifiers" }
+ {
+ }
+ void mem_nc()
+ [[ pre: f() ]]
+ {
+ }
+
+ void memc_c() const
+ [[ pre: g() ]]
+ {
+ }
+ void memc_nc()
+ [[ pre: g() ]]
+ {
+ }
+
+ private:
+ int x_{-10};
+};
+
+int main(int, char**)
+{
+ S s;
+ return 0;
+};
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-deduced1.C b/gcc/testsuite/g++.dg/contracts/contracts-deduced1.C
new file mode 100644
index 0000000..200ec73
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-deduced1.C
@@ -0,0 +1,108 @@
+// Tests to ensure that deduced return types work with postconditions using
+// the return value on defining declarations.
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts --param ggc-min-heapsize=0 --param ggc-min-expand=0" }
+
+auto undeduced(int z)
+{
+ if (!(sizeof(decltype(undeduced(5))) > 4)) // { dg-error "before deduction" }
+ return 5;
+ return 4;
+}
+
+// defining declaration, fine
+auto g0(int a) [[ pre: a < 0 ]] [[ post r: r > 0 ]]
+{
+ return -a * 1.2;
+}
+
+// non defining post using nondeduced identifier, fine
+int g1(int m) [[ post r: r == m ]];
+
+int g1(int n) [[ post s: s == n ]]
+{
+ return -n;
+}
+
+int g2(int z)
+ [[ pre: sizeof(decltype(g2(5))) > 4 ]]; // { dg-error "not declared" }
+
+int g3(int z)
+ [[ pre: sizeof(decltype(g2(5))) > 4 ]]
+{
+ return -z;
+}
+
+// deduced that doesn't use return, good
+auto g4(int m) [[ post: m ]];
+
+auto g4(int m) [[ post: m ]]
+{
+ return -m;
+}
+
+auto g5(int m) [[ pre: m ]];
+
+auto g5(int m) [[ pre: m ]]
+{
+ return -m;
+}
+
+template<typename T>
+auto g6(T t) [[ post r: r == t ]];
+
+template<typename S>
+auto g6(S s) [[ post q: q == s ]]
+{
+ return s;
+}
+
+template<typename T>
+T g7(T t) [[ post r: r == t ]];
+
+template<typename S>
+S g7(S s) [[ post q: q == s ]]
+{
+ return s;
+}
+
+template<typename T>
+auto g8(T t) [[ post r: r == t && sizeof(decltype(::g8(t))) > 2 ]]; // { dg-error "not been declared" }
+
+// This failure is related to the fact that we've invalidated the previous
+// contract.
+template<typename S>
+auto g8(S s) [[ post q: q == s && sizeof(decltype(::g8(s))) > 2 ]] // { dg-error "mismatched" }
+{
+ return s;
+}
+
+// non defining pre, bad
+auto f0(int z)
+ [[ pre: sizeof(decltype(f0(5))) > 4 ]]; // { dg-error "not declared" }
+
+// defining pre, still ill formed
+auto f1(int z)
+ [[ pre: sizeof(decltype(f1(5))) > 4 ]] // { dg-error "not declared" }
+{
+ return '5';
+}
+
+// undeduced using postcon, OK
+auto f2(int m) [[ post r: r == m ]];
+
+auto f2(int n) [[ post s: s == n ]]
+{
+ return n;
+}
+
+template<typename T>
+void f3(T t) [[ post r: false ]] // { dg-error "function does not return a value" }
+{
+}
+
+int main(int, char**)
+{
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-deduced2.C b/gcc/testsuite/g++.dg/contracts/contracts-deduced2.C
new file mode 100644
index 0000000..da9c019
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-deduced2.C
@@ -0,0 +1,84 @@
+// check that contracts work around deduced return types
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+
+auto g0(int a) [[ pre: a < 0 ]] [[ post r: r > 0 ]]
+{
+ return -a * 1.2;
+}
+
+int g1(int m) [[ post r: r == m ]];
+
+int g1(int n) [[ post s: s == n ]]
+{
+ return -n;
+}
+
+int g2(int z)
+{
+ return -z;
+}
+
+int g3(int z)
+ [[ pre: sizeof(decltype(g2(5))) > 4 ]]
+{
+ return -z;
+}
+
+auto g4(int m) [[ post: m ]];
+
+auto g4(int m) [[ post: m ]]
+{
+ return -m;
+}
+
+auto g5(int m) [[ pre: m ]];
+
+auto g5(int m) [[ pre: m ]]
+{
+ return -m;
+}
+
+template<typename T>
+auto g6(T t) [[ post r: r == t ]];
+
+template<typename S>
+auto g6(S s) [[ post q: q == s ]]
+{
+ return -s;
+}
+
+// template<typename T>
+// T g7(T t) [[ post r: r == t ]];
+
+template<typename S>
+S g7(S s) [[ post q: q == s ]]
+{
+ return -s;
+}
+
+int main(int, char**) {
+ g0(5);
+ g1(6);
+ g2(1);
+ g3(1);
+ g4(0);
+ g5(0);
+ g6(5);
+ g6(5.5);
+ g7(5);
+ g7(6.6);
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 5 g0 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 5 g0 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 12 g1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 23 g3 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 30 g4 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 37 g5 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 46 g6<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 46 g6<double> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 55 g7<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 55 g7<double> .*(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-friend1.C b/gcc/testsuite/g++.dg/contracts/contracts-friend1.C
new file mode 100644
index 0000000..0ccfbe2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-friend1.C
@@ -0,0 +1,40 @@
+// ensure contracts on friend declarations are a complete class context
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+
+struct X {
+ friend void fn0(X x) [[ pre: x.a > 0 ]] { }
+
+ friend void fn2(X x);
+ static void fns0(X x) [[ pre: x.a > 0 ]] { }
+ static void fns1(X x) [[ pre: x.a > 0 ]];
+ static void fns2(X x);
+
+ friend void fn(X &x) { x.a = -5; }
+
+private:
+ int a{10};
+};
+
+void fn2(X x) [[ pre: x.a > 0 ]] { }
+void X::fns1(X x) { }
+void X::fns2(X x) [[ pre: x.a > 0 ]] { }
+
+int main(int, char**) {
+ X x;
+ fn(x); // no contract
+
+ fn0(x);
+ fn2(x);
+
+ X::fns0(x);
+ X::fns1(x);
+ X::fns2(x);
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 6 fn0 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 19 fn2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 9 X::fns0 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 10 X::fns1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 21 X::fns2 .*(\n|\r\n|\r)*" }
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-ft1.C b/gcc/testsuite/g++.dg/contracts/contracts-ft1.C
new file mode 100644
index 0000000..e5d5be7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-ft1.C
@@ -0,0 +1,14 @@
+// { dg-do compile }
+
+#ifdef __cpp_contracts
+static_assert (false);
+#endif
+
+#ifdef __cpp_contracts_literal_semantics
+static_assert (false);
+#endif
+
+#ifdef __cpp_contracts_roles
+static_assert (false);
+#endif
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-ignore1.C b/gcc/testsuite/g++.dg/contracts/contracts-ignore1.C
new file mode 100644
index 0000000..c8ae656
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-ignore1.C
@@ -0,0 +1,30 @@
+// test that ignored contracts do instatiate templates
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+template<typename T>
+int f(T t)
+{
+ return -t;
+}
+
+int dummy()
+{
+ [[ assert ignore: f(1.0) > 0 ]];
+ return -1;
+}
+
+template<>
+int f(double t) // { dg-error "specialization of.*after instantiation" }
+{
+ return -1.0;
+}
+
+int main()
+{
+ dummy();
+ f(1);
+ f(1.0);
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-ignore2.C b/gcc/testsuite/g++.dg/contracts/contracts-ignore2.C
new file mode 100644
index 0000000..5cf800a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-ignore2.C
@@ -0,0 +1,26 @@
+// baseline for testing assert contracts being turned into compile time
+// assumptions; see contracts-assume2 for the assumed case
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts" }
+#include <cstdio>
+
+int fun(int x) {
+ [[assert audit: x > 0]];
+ if(x <= 0)
+ {
+ printf("%d: test x<=0 opt out\n", x);
+ return -1;
+ }
+ else
+ {
+ printf("%d: test x>0\n", x);
+ return 0;
+ }
+}
+
+int main(int, char**) {
+ volatile int x = -1;
+ return fun(x);
+}
+
+// { dg-shouldfail "" }
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-large-return.C b/gcc/testsuite/g++.dg/contracts/contracts-large-return.C
new file mode 100644
index 0000000..ea8e73a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-large-return.C
@@ -0,0 +1,15 @@
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+struct Foo
+{
+ int x;
+ bool y;
+ long z[4];
+};
+
+Foo foo() [[ pre: true ]]
+{
+ return {};
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-multiline1.C b/gcc/testsuite/g++.dg/contracts/contracts-multiline1.C
new file mode 100644
index 0000000..8145c61
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-multiline1.C
@@ -0,0 +1,19 @@
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+
+int main(int, char **)
+{
+ int x = 5;
+ int y = 10;
+ [[ assert:
+ x
+ <
+ 10
+ &&
+ y
+ >
+ 123
+ ]];
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 8 main x < 10 && y > 123.*(\n|\r\n|\r)*" }
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-multiple-inheritance1.C b/gcc/testsuite/g++.dg/contracts/contracts-multiple-inheritance1.C
new file mode 100644
index 0000000..3f2f5ed
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-multiple-inheritance1.C
@@ -0,0 +1,15 @@
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+
+struct BaseA {
+ virtual int fun(int n) [[ pre: n > 0 ]] { return -n; }
+};
+
+struct BaseB {
+ virtual int fun(int n) [[ pre: n > 0 ]] { return -n; }
+};
+
+struct Child : public BaseA, BaseB {
+ int fun(int n) [[ pre: n > 0 ]] { return -n; }
+};
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-multiple-inheritance2.C b/gcc/testsuite/g++.dg/contracts/contracts-multiple-inheritance2.C
new file mode 100644
index 0000000..37bdac1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-multiple-inheritance2.C
@@ -0,0 +1,33 @@
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+
+struct BaseA {
+ virtual int fun(int n) [[ pre: n > 0 ]] { return -n; }
+};
+
+struct BaseB {
+ virtual int fun(int n) [[ pre: n < 0 ]] { return -n; }
+};
+
+struct Child1 : public BaseA, BaseB {
+ int fun(int n) [[ pre: n > 0 ]] { return -n; } // { dg-error "mismatched" }
+};
+
+struct Child2 : public BaseA, BaseB {
+ int fun(int n) [[ pre: n < 0 ]] { return -n; } // { dg-error "mismatched" }
+};
+
+struct Child3 : public BaseA, BaseB {
+ int fun(int n) { return -n; }
+};
+
+struct Child4 : public BaseA {
+ int fun(int n);
+};
+
+int Child4::fun(int n)
+ [[ pre: n != 0 ]] // { dg-error "mismatched" }
+{
+ return -n;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-nested-class1.C b/gcc/testsuite/g++.dg/contracts/contracts-nested-class1.C
new file mode 100644
index 0000000..9f91ff4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-nested-class1.C
@@ -0,0 +1,24 @@
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+void gfn3(int n) [[ pre: n > 0 ]];
+
+struct Outer {
+ struct Inner {
+ void fn(int n) [[ pre: n > 0 && bob > 1 ]];
+ void fn2(int n) [[ pre: n > 0 && bob > 1 ]];
+ };
+
+ void fn(int m) [[ pre: m > 1 ]];
+ friend void Inner::fn(int n) [[ pre: n > 0 && bob > 1 ]]; // { dg-error "not declared" }
+
+ friend void gfn(int p) [[ pre: p > 0 ]];
+ friend void gfn(int q) [[ pre: q > 1 ]]; // { dg-error "'q' was not declared" }
+
+ // This should be okay.
+ friend void gfn2(int q);
+ friend void gfn2(int p) [[ pre: p > 0 ]] { }
+
+ static int bob;
+};
+int Outer::bob{-1};
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-nested-class2.C b/gcc/testsuite/g++.dg/contracts/contracts-nested-class2.C
new file mode 100644
index 0000000..43e75ed
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-nested-class2.C
@@ -0,0 +1,40 @@
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+
+void gfn3(int n) [[ pre: n > 0 ]];
+
+struct Outer {
+ struct Inner {
+ void fn(int n) [[ pre: n > 0 && bob > 1 ]];
+ };
+
+ void fn(int m) [[ pre: m > 1 ]];
+
+ friend void gfn1(int q);
+ friend void gfn1(int p) [[ pre: p > 0 ]] { }
+
+ friend void gfn2(int q, Outer *);
+ friend void gfn2(int p, Outer *) [[ pre: p > 0 ]] { }
+
+ friend void gfn3(int n);
+
+ static int bob;
+};
+int Outer::bob{-1};
+
+void Outer::Inner::fn(int x) { }
+void Outer::fn(int y) { }
+
+void gfn3(int n) { }
+void gfn1(int q);
+
+int main(int, char **) {
+ Outer::Inner in;
+ in.fn(-5);
+ Outer out;
+ out.fn(-6);
+ gfn1(-7);
+ gfn2(-8, &out);
+ gfn3(-9);
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-nocopy1.C b/gcc/testsuite/g++.dg/contracts/contracts-nocopy1.C
new file mode 100644
index 0000000..4608a4d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-nocopy1.C
@@ -0,0 +1,24 @@
+// Contracts shouldn't introduce more copies.
+
+// { dg-do compile { target c++20 } }
+// { dg-additional-options -fcontracts }
+
+struct A
+{
+ int i;
+ A(int i): i(i) { }
+ A(const A&) = delete;
+};
+
+A f(A a)
+ [[ pre: a.i > 0 ]]
+ [[ post r: r.i > 0 ]]
+{
+ return {a.i};
+}
+
+int main()
+{
+ if (f({42}).i != 42)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-override.C b/gcc/testsuite/g++.dg/contracts/contracts-override.C
new file mode 100644
index 0000000..f96aa98
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-override.C
@@ -0,0 +1,43 @@
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+struct Foo {
+ virtual int f0(int n) [[ pre: false ]] { return n; }
+ virtual int f1(int n) [[ pre: false ]] { return n; }
+ virtual int f2(int n) [[ pre: false ]] { return n; }
+ virtual int f3(int n) [[ pre: false ]] { return n; }
+ virtual int f4(int n) [[ pre: false ]] { return n; }
+ virtual int f5(int n) [[ pre: false ]] { return n; }
+ virtual int f6(int n) [[ pre: false ]] { return n; }
+ virtual int f7(int n) [[ pre: false ]] { return n; }
+ virtual int f8(int n) [[ pre: false ]] { return n; }
+ virtual int f9(int n) [[ pre: false ]] { return n; }
+ virtual int f10(int n) [[ pre: false ]] { return n; }
+ virtual int f11(int n) [[ pre: n > 0 ]] [[ pre: n > 1 ]] { return n; }
+ virtual int f12(int n) [[ pre: n > 0 ]] [[ pre: n > 1 ]] { return n; }
+};
+
+struct Bar : Foo {
+ [[ pre: n > -1 ]] int f0(int n = 0) override { return -n; } // { dg-error "contracts must appertain" }
+ int [[ pre: n > -2 ]] f1(int n = 0) override { return -n; } // { dg-error "contracts must appertain" }
+ int f2 [[ pre: n > -3 ]] (int n = 0) override { return -n; } // { dg-error "contracts must appertain" }
+ int f4([[ pre: n > -4 ]] int n = 0) override { return -n; } // { dg-error "contracts must appertain" }
+ int f5(int [[ pre: n > -5 ]] n = 0) override { return -n; } // { dg-error "contracts must appertain" }
+ int f6(int n [[ pre: n > -6 ]] = 0) override { return -n; } // { dg-error "contracts must appertain" }
+ int f7(int n = [[ pre: n > -7 ]] 0) override { return -n; }
+ // { dg-error "expected identifier" "" { target *-*-* } .-1 }
+ // { dg-error "expected .\{. before numeric" "" { target *-*-* } .-2 }
+ // { dg-error "invalid user-defined conversion" "" { target *-*-* } .-3 }
+ // { dg-error "expected .,." "" { target *-*-* } .-4 }
+ int f8(int n = 0 [[ pre: n > -8 ]]) override { return -n; }
+ // { dg-error "shall only introduce an attribute" "" { target *-*-* } .-1 }
+ int f9(int n = 0) [[ pre: n > -9 ]] override { return -n; } // { dg-error "mismatched contract" }
+
+ // The grammar doesn't appear to permit contracts after the virt-specifiers
+ // but the parser will happily add these to an attribute list that is not
+ // owned by the function declarator.
+ int f10(int n = 0) override [[ pre: n > -10 ]] { return -n; } // { dg-error "contracts must appertain" }
+ int f11(int n) [[ pre: n > 1 ]] override [[ pre: n > 0 ]] { return -n; } // { dg-error "contracts must appertain" }
+ int f12(int n) [[ pre: n > 0 ]] override [[ pre: n > 1 ]] { return -n; } // { dg-error "contracts must appertain" }
+};
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-post1.C b/gcc/testsuite/g++.dg/contracts/contracts-post1.C
new file mode 100644
index 0000000..451760e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-post1.C
@@ -0,0 +1,74 @@
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+int f1(int n)
+ [[pre: n >= 0]]
+ [[post r: r >= 0]]
+ [[post r: !(r < 0)]]
+{
+ return n;
+}
+
+int f2(int n)
+ [[post: true]]
+{
+ return 0;
+}
+
+int f3(int n)
+ [[post r: r >= n]]
+{
+ return n + 1;
+}
+
+int f4(int n)
+ [[post: x > 0]] // { dg-error "not declared" }
+{
+ return 0;
+}
+
+void f5()
+ [[post: true]]
+{ }
+
+void f6()
+ [[post r: true]] // { dg-error "function does not return a value" }
+{ }
+
+int f7(int n)
+ [[post: n > 0]]
+{
+ return x; // { dg-error "not declared" }
+}
+
+void f8(int n)
+ [[post: n > 0]]
+{
+ return;
+}
+
+void f9(int n)
+ [[post: n > 0]]
+{
+ return n; // { dg-error "return-statement with a value" }
+}
+
+int f10(int n)
+ [[post: n > 0]]
+{
+ return; // { dg-error "return-statement with no value" }
+}
+
+void f11()
+ [[post: true]]
+{
+ constexpr int n = 0;
+ return n; // { dg-error "return-statement with a value" }
+}
+
+int f12()
+ [[post: true]]
+{
+ return; // { dg-error "return-statement with no value" }
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-post2.C b/gcc/testsuite/g++.dg/contracts/contracts-post2.C
new file mode 100644
index 0000000..7665f82
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-post2.C
@@ -0,0 +1,13 @@
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts" }
+
+int f1(int n)
+ [[post r: r == n]]
+{
+ return n;
+}
+
+int main()
+{
+ f1(0);
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-post3.C b/gcc/testsuite/g++.dg/contracts/contracts-post3.C
new file mode 100644
index 0000000..9f1dffd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-post3.C
@@ -0,0 +1,15 @@
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts" }
+// { dg-shouldfail "assert violation" }
+// { dg-output "default std::handle_contract_violation called" }
+
+int f1(int n)
+ [[post r: r > n]]
+{
+ return n;
+}
+
+int main()
+{
+ f1(0);
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-post4.C b/gcc/testsuite/g++.dg/contracts/contracts-post4.C
new file mode 100644
index 0000000..af770c3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-post4.C
@@ -0,0 +1,36 @@
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+struct S
+{
+ S() [[post: n == 0]]
+ : n(0)
+ { }
+
+ ~S() [[post: true]]
+ { }
+
+ int f1()
+ [[post r: n == r]]
+ {
+ return n;
+ }
+
+ int f2()
+ [[post r: r == x]] // { dg-error "not declared" }
+ {
+ return n;
+ }
+
+ void f3()
+ [[post r: n]] // { dg-error "does not return a value" }
+ {
+ }
+
+ int n = 0;
+};
+
+int main()
+{
+ // f1(0);
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-post5.C b/gcc/testsuite/g++.dg/contracts/contracts-post5.C
new file mode 100644
index 0000000..c9127fb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-post5.C
@@ -0,0 +1,19 @@
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+// Tests for function templates
+
+template<typename T>
+T f1(T n)
+ [[pre: n >= 0]]
+ [[post r: r >= 0]]
+ [[post r: !(r < 0)]]
+{
+ return n;
+}
+
+
+void driver()
+{
+ f1(0);
+} \ No newline at end of file
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-post6.C b/gcc/testsuite/g++.dg/contracts/contracts-post6.C
new file mode 100644
index 0000000..f8246fb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-post6.C
@@ -0,0 +1,30 @@
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+// Test for class members
+
+template<typename T>
+struct S
+{
+ S(T n)
+ [[post: true]]
+ : n(n)
+ { }
+
+ T f1(T n)
+ [[pre: n >= 0]]
+ [[post r: r >= 0]]
+ [[post r: !(r < 0)]]
+ {
+ return n;
+ }
+
+ T n;
+};
+
+
+void driver()
+{
+ S<int> s1(0);
+ s1.f1(2);
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-pre1.C b/gcc/testsuite/g++.dg/contracts/contracts-pre1.C
new file mode 100644
index 0000000..908103c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-pre1.C
@@ -0,0 +1,36 @@
+// generic pre contract parsing checks
+// check omitted, 'default', 'audit', and 'axiom' contract levels parse
+// ensure that an invalid contrcat level 'off' errors
+// ensure that a predicate referencing an undefined variable errors
+// ensure that a missing colon after contract level errors
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+void f1(int x) [[ pre: x >= 0 ]] { }
+void f2(int x) [[ pre default: x >= 0 ]] { }
+void f3(int x) [[ pre audit: x >= 0 ]] { }
+void f4(int x) [[ pre axiom: x >= 0 ]] { }
+
+void finvalid(int x) [[ pre invalid: x >= 0 ]] { } // { dg-error "expected contract level" }
+void fundeclared() [[ pre: x >= 0 ]] { } // { dg-error ".x. was not declared in this scope" }
+void fmissingcolon(int x) [[ pre default x == 0]] { } // { dg-error "expected .:. before .x." }
+
+int Z;
+void (*fp1)(int x) [[ pre: Z > 0 ]]; // { dg-error "contracts must appertain" }
+void (*fp2 [[ pre: Z > 0 ]])(int x); // { dg-error "contracts must appertain" }
+typedef void (*fp3)(int x) [[ pre: Z > 0 ]]; // { dg-error "contracts must appertain" }
+typedef void (*fp4 [[ pre: Z > 0 ]])(int x); // { dg-error "contracts must appertain" }
+fp3 fn5(int a) [[ pre: a > 0 ]]; // { dg-bogus "contracts must appertain" }
+
+int xyz;
+[[ pre: xyz ]] struct Bar; // { dg-error "contracts must appertain" }
+// { dg-warning "attribute ignored" "" { target *-*-* } .-1 }
+struct [[ pre: xyz ]] Bar; // { dg-error "contracts must appertain" }
+struct Bar [[ pre: xyz ]]; // { dg-error "contracts must appertain" }
+struct Zoo {} x [[ pre: xyz ]]; // { dg-error "contracts must appertain" }
+
+void f6(int x) [[ pre: x > 0 ; // { dg-error "expected .]." }
+void f7(int x) [[ pre: x > 0 ]; // { dg-error "expected .]." }
+void f8(int x) [[ pre: x > 0 { }; // { dg-error "expected .]." }
+void f9(int x) [[ pre: x > 0 ] { }; // { dg-error "expected .]." }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-pre10.C b/gcc/testsuite/g++.dg/contracts/contracts-pre10.C
new file mode 100644
index 0000000..877e9ad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-pre10.C
@@ -0,0 +1,190 @@
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+
+struct M
+{
+ template<typename T>
+ int f(int a) [[ pre: a > 0 ]];
+
+ template<typename T>
+ int g(int a) [[ pre: a > 0 ]]
+ {
+ return -a;
+ }
+
+ template<typename T>
+ int f_arg(T a) [[ pre: a > 0 ]];
+
+ template<typename T>
+ int g_arg(T a) [[ pre: a > 0 ]]
+ {
+ return (int)-a;
+ }
+
+ template<typename T>
+ T f_ret(int a) [[ pre: a > 0 ]];
+
+ template<typename T>
+ T g_ret(int a) [[ pre: a > 0 ]]
+ {
+ return -a * 1.5;
+ }
+};
+
+template<typename T>
+int M::f(int a)
+{
+ return -a;
+}
+
+template<typename T>
+int M::f_arg(T a)
+{
+ return (int)-a;
+}
+
+template<typename T>
+T M::f_ret(int a)
+{
+ return -a * (T)1.5;
+}
+
+template<typename T>
+struct S
+{
+ template<typename Q>
+ int f(int a) [[ pre: a > 0 ]];
+
+ template<typename Q>
+ int g(int a) [[ pre: a > 0 ]]
+ {
+ return -a;
+ }
+};
+
+template<typename T>
+template<typename Q>
+int S<T>::f(int a)
+{
+ return -a;
+}
+
+#include <cstdio>
+int main(int, char**)
+{
+ {
+ M m;
+ printf ("=================================\n");
+ printf ("m.f<int>(-10): %d\n", m.f<int>(-10));
+ printf ("m.f<double>(-11.5): %d\n", m.f<double>(-11.5));
+ printf ("m.f<int>(10): %d\n", m.f<int>(10));
+ printf ("m.f<double>(11.5): %d\n", m.f<double>(11.5));
+
+ printf ("=================================\n");
+ printf ("m.g<int>(-10): %d\n", m.g<int>(-10));
+ printf ("m.g<double>(-11.5): %d\n", m.g<double>(-11.5));
+ printf ("m.g<int>(10): %d\n", m.g<int>(10));
+ printf ("m.g<double>(11.5): %d\n", m.g<double>(11.5));
+
+ printf ("=================================\n");
+ printf ("m.f_arg(-10): %d\n", m.f_arg(-10));
+ printf ("m.f_arg(-11.5): %d\n", m.f_arg(-11.5));
+ printf ("m.f_arg(10): %d\n", m.f_arg(10));
+ printf ("m.f_arg(11.5): %d\n", m.f_arg(11.5));
+
+ printf ("=================================\n");
+ printf ("m.g_arg(-10): %d\n", m.g_arg(-10));
+ printf ("m.g_arg(-11.5): %d\n", m.g_arg(-11.5));
+ printf ("m.g_arg(10): %d\n", m.g_arg(10));
+ printf ("m.g_arg(11.5): %d\n", m.g_arg(11.5));
+
+ printf ("=================================\n");
+ printf ("m.f_ret<int>(-10): %d\n", m.f_ret<int>(-10));
+ printf ("m.f_ret<double>(-11.5): %f\n", m.f_ret<double>(-11.5));
+ printf ("m.f_ret<int>(10): %d\n", m.f_ret<int>(10));
+ printf ("m.f_ret<double>(11.5): %f\n", m.f_ret<double>(11.5));
+
+ printf ("=================================\n");
+ printf ("m.g_ret<int>(-10): %d\n", m.g_ret<int>(-10));
+ printf ("m.g_ret<double>(-11.5): %f\n", m.g_ret<double>(-11.5));
+ printf ("m.g_ret<int>(10): %d\n", m.g_ret<int>(10));
+ printf ("m.g_ret<double>(11.5): %f\n", m.g_ret<double>(11.5));
+ }
+
+ {
+ S<int> s;
+ printf ("=================================\n");
+ s.f<int>(-10);
+
+ s.f<double>(-10);
+
+ printf ("=================================\n");
+ s.g<int>(-10);
+
+ s.g<double>(-10);
+ }
+
+ {
+ S<double> s;
+ printf ("=================================\n");
+ s.f<int>(-10);
+
+ s.f<double>(-10);
+
+ printf ("=================================\n");
+ s.g<int>(-10);
+
+ s.g<double>(-10);
+ }
+
+ return 0;
+}
+
+// { dg-output "=================================(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 7 M::f<int> .*(\n|\r\n|\r)*" }
+// { dg-output "m.f<int>.-10.: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 7 M::f<double> .*(\n|\r\n|\r)*" }
+// { dg-output "m.f<double>.-11.5.: 11(\n|\r\n|\r)*" }
+// { dg-output "m.f<int>.10.: -10(\n|\r\n|\r)*" }
+// { dg-output "m.f<double>.11.5.: -11(\n|\r\n|\r)*" }
+// { dg-output "=================================(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 10 M::g<int> .*(\n|\r\n|\r)*" }
+// { dg-output "m.g<int>.-10.: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 10 M::g<double> .*(\n|\r\n|\r)*" }
+// { dg-output "m.g<double>.-11.5.: 11(\n|\r\n|\r)*" }
+// { dg-output "m.g<int>.10.: -10(\n|\r\n|\r)*" }
+// { dg-output "m.g<double>.11.5.: -11(\n|\r\n|\r)*" }
+// { dg-output "=================================(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 16 M::f_arg<int> .*(\n|\r\n|\r)*" }
+// { dg-output "m.f_arg.-10.: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 16 M::f_arg<double> .*(\n|\r\n|\r)*" }
+// { dg-output "m.f_arg.-11.5.: 11(\n|\r\n|\r)*" }
+// { dg-output "m.f_arg.10.: -10(\n|\r\n|\r)*" }
+// { dg-output "m.f_arg.11.5.: -11(\n|\r\n|\r)*" }
+// { dg-output "=================================(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 19 M::g_arg<int> .*(\n|\r\n|\r)*" }
+// { dg-output "m.g_arg.-10.: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 19 M::g_arg<double> .*(\n|\r\n|\r)*" }
+// { dg-output "m.g_arg.-11.5.: 11(\n|\r\n|\r)*" }
+// { dg-output "m.g_arg.10.: -10(\n|\r\n|\r)*" }
+// { dg-output "m.g_arg.11.5.: -11(\n|\r\n|\r)*" }
+// { dg-output "=================================(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 25 M::f_ret<int> .*(\n|\r\n|\r)*" }
+// { dg-output "m.f_ret<int>.-10.: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 25 M::f_ret<double> .*(\n|\r\n|\r)*" }
+// { dg-output "m.f_ret<double>.-11.5.: 16.500000(\n|\r\n|\r)*" }
+// { dg-output "m.f_ret<int>.10.: -10(\n|\r\n|\r)*" }
+// { dg-output "m.f_ret<double>.11.5.: -16.500000(\n|\r\n|\r)*" }
+// { dg-output "=================================(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 28 M::g_ret<int> .*(\n|\r\n|\r)*" }
+// { dg-output "m.g_ret<int>.-10.: 15(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 28 M::g_ret<double> .*(\n|\r\n|\r)*" }
+// { dg-output "m.g_ret<double>.-11.5.: 16.500000(\n|\r\n|\r)*" }
+// { dg-output "m.g_ret<int>.10.: -15(\n|\r\n|\r)*" }
+// { dg-output "m.g_ret<double>.11.5.: -16.500000(\n|\r\n|\r)*" }
+// { dg-output "=================================(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 59 S<int>::g<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 59 S<int>::g<double> .*(\n|\r\n|\r)*" }
+// { dg-output "=================================(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 59 S<double>::g<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 59 S<double>::g<double> .*(\n|\r\n|\r)*" }
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-pre2.C b/gcc/testsuite/g++.dg/contracts/contracts-pre2.C
new file mode 100644
index 0000000..4fe2f9d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-pre2.C
@@ -0,0 +1,212 @@
+// basic test to ensure pre contracts work for free functions
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+#include <cstdio>
+
+namespace nullary
+{
+ int x = 10;
+ int y = 10;
+
+ void fun()
+ [[ pre: x < 0 ]]
+ {
+ printf("fun::x: %d\n", x);
+ }
+
+ void fun2()
+ [[ pre: x < 0 ]]
+ [[ pre: y < 0 ]]
+ {
+ printf("fun2::x: %d fun2::y: %d\n", x, y);
+ }
+
+ void funend()
+ [[ pre: x < 0 ]];
+}
+
+namespace nonvoid
+{
+ int x = 10;
+ double y = 10.5;
+
+ struct S
+ {
+ bool z;
+ };
+
+ void vfun()
+ [[ pre: x < 0 ]]
+ {
+ printf("vfun::x: %d\n", x);
+ }
+
+ int fun()
+ [[ pre: x < 0 ]]
+ {
+ printf("fun::x: %d\n", x);
+ return x;
+ }
+
+ double fun2()
+ [[ pre: x < 0 ]]
+ [[ pre: y < 0 ]]
+ {
+ printf("fun2::x: %d fun2::y: %f\n", x, y);
+ return y;
+ }
+
+ S funend()
+ [[ pre: x < 0 ]];
+}
+
+namespace nonnullary
+{
+ int x = 10;
+ double y = 10.5;
+
+ struct S
+ {
+ bool z;
+ };
+
+ void vfun(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: m < 0 ]]
+ {
+ printf("vfun::x: %d\n", x);
+ }
+
+ int fun(int m, double n)
+ [[ pre: x < 0 ]]
+ {
+ printf("fun::x: %d\n", x);
+ return x;
+ }
+
+ double fun2(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: y < 0 ]]
+ [[ pre: m < 0 ]]
+ [[ pre: n < 0 ]]
+ {
+ printf("fun2::x: %d fun2::y: %f\n", x, y);
+ return y;
+ }
+
+ S funend(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: m < 0 ]];
+}
+
+int main(int, char**) {
+ // nullary void
+ {
+ nullary::fun();
+ nullary::fun2();
+ nullary::funend();
+ }
+
+ // nullary non void
+ {
+ nonvoid::vfun();
+
+ int f = 13;
+ f = nonvoid::fun();
+ printf("main::f: %d\n", f);
+ double d = 13.37;
+ d = nonvoid::fun2();
+ printf("main::d: %f\n", d);
+ nonvoid::S s = nonvoid::funend();
+ printf("main::s.z: %d\n", s.z ? 1 : 0);
+ }
+
+ // non-nullary non-void
+ {
+ int x = 11;
+ double y = 11.5;
+
+ nonnullary::vfun(x, y);
+
+ int f = 13;
+ f = nonnullary::fun(x, y);
+ printf("main::f: %d\n", f);
+ double d = 13.37;
+ d = nonnullary::fun2(x, y);
+ printf("main::d: %f\n", d);
+ nonnullary::S s = nonnullary::funend(x, y);
+ printf("main::s.z: %d\n", s.z ? 1 : 0);
+ }
+ return 0;
+}
+
+namespace nullary
+{
+ void funend()
+ [[ pre: x < 0 ]]
+ {
+ printf("funend::x: %d\n", x);
+ }
+}
+
+namespace nonvoid
+{
+ S funend()
+ [[ pre: x < 0 ]]
+ {
+ printf("funend::x: %d\n", x);
+ S s;
+ s.z = true;
+ return s;
+ }
+}
+
+namespace nonnullary
+{
+ S funend(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: m < 0 ]]
+ {
+ printf("funend::x: %d\n", x);
+ S s;
+ s.z = true;
+ return s;
+ }
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 12 nullary::fun .*(\n|\r\n|\r)*" }
+// { dg-output "fun::x: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 18 nullary::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 19 nullary::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "fun2::x: 10 fun2::y: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 146 nullary::funend .*(\n|\r\n|\r)*" }
+// { dg-output "funend::x: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 39 nonvoid::vfun .*(\n|\r\n|\r)*" }
+// { dg-output "vfun::x: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 45 nonvoid::fun .*(\n|\r\n|\r)*" }
+// { dg-output "fun::x: 10(\n|\r\n|\r)*" }
+// { dg-output "main::f: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 52 nonvoid::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 53 nonvoid::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "fun2::x: 10 fun2::y: 10.500000(\n|\r\n|\r)*" }
+// { dg-output "main::d: 10.500000(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 155 nonvoid::funend .*(\n|\r\n|\r)*" }
+// { dg-output "funend::x: 10(\n|\r\n|\r)*" }
+// { dg-output "main::s.z: 1(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 74 nonnullary::vfun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 75 nonnullary::vfun .*(\n|\r\n|\r)*" }
+// { dg-output "vfun::x: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 81 nonnullary::fun .*(\n|\r\n|\r)*" }
+// { dg-output "fun::x: 10(\n|\r\n|\r)*" }
+// { dg-output "main::f: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 88 nonnullary::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 89 nonnullary::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 90 nonnullary::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 91 nonnullary::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "fun2::x: 10 fun2::y: 10.500000(\n|\r\n|\r)*" }
+// { dg-output "main::d: 10.500000(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 167 nonnullary::funend .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 168 nonnullary::funend .*(\n|\r\n|\r)*" }
+// { dg-output "funend::x: 10(\n|\r\n|\r)*" }
+// { dg-output "main::s.z: 1(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-pre2a1.C b/gcc/testsuite/g++.dg/contracts/contracts-pre2a1.C
new file mode 100644
index 0000000..2616749
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-pre2a1.C
@@ -0,0 +1,33 @@
+// ensure the feature test macros are defined pre c++20 while we still support
+// -fcontracts independent of std version
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-fcontracts" }
+
+static_assert (__cpp_contracts >= 201906, "__cpp_contracts");
+static_assert (__cpp_contracts_literal_semantics >= 201906, "__cpp_contracts_literal_semantics");
+static_assert (__cpp_contracts_roles >= 201906, "__cpp_contracts_roles");
+
+int main()
+{
+ int x;
+
+ [[assert: x >= 0]];
+ [[assert default: x < 0]];
+ [[assert audit: x == 0]];
+ [[assert axiom: x == 1]];
+
+ [[assert: x > 0 ? true : false]];
+ [[assert: x < 0 ? true : false]];
+
+ [[assert ignore: x >= 0]];
+ [[assert assume: x >= 0]];
+ [[assert check_never_continue: x >= 0]];
+ [[assert check_maybe_continue: x >= 0]];
+
+ [[assert %default: x >= 0]];
+ [[assert default %default: x < 0]];
+ [[assert audit %default: x == 0]];
+ [[assert axiom %default: x == 1]];
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-pre2a2.C b/gcc/testsuite/g++.dg/contracts/contracts-pre2a2.C
new file mode 100644
index 0000000..db9a0c37
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-pre2a2.C
@@ -0,0 +1,22 @@
+// basic test to ensure contracts work pre-c++2a
+// { dg-do run { target c++11 } }
+// { dg-additional-options "-fcontracts -fcontract-continuation-mode=on" }
+
+int f(int n)
+ [[ pre: n > 0 ]]
+ [[ post r: r < 0 ]]
+{
+ [[ assert: n > 0 ]];
+ return -n;
+}
+
+int main()
+{
+ f(-5);
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 6 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 9 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 7 .*(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-pre3.C b/gcc/testsuite/g++.dg/contracts/contracts-pre3.C
new file mode 100644
index 0000000..1c4e3a9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-pre3.C
@@ -0,0 +1,525 @@
+// tests to ensure pre contracts work on member functions
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+#include <cstdio>
+
+namespace member
+{
+ int x = 10;
+ double y = 10.5;
+
+ struct S
+ {
+ bool z;
+ };
+
+ struct T1
+ {
+ void vfun(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: m < 0 ]];
+
+ int fun(int m, double n)
+ [[ pre: x < 0 ]];
+
+ double fun2(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: y < 0 ]]
+ [[ pre: m < 0 ]]
+ [[ pre: n < 0 ]];
+
+ S funend(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: m < 0 ]];
+ };
+
+ void T1::vfun(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: m < 0 ]]
+ {
+ printf("vfun::x: %d\n", x);
+ }
+
+
+ int T1::fun(int m, double n)
+ [[ pre: x < 0 ]]
+ {
+ printf("fun::x: %d\n", x);
+ return x;
+ }
+
+ double T1::fun2(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: y < 0 ]]
+ [[ pre: m < 0 ]]
+ [[ pre: n < 0 ]]
+ {
+ printf("fun2::x: %d fun2::y: %f\n", x, y);
+ return y;
+ }
+}
+
+namespace special
+{
+ struct T1
+ {
+ T1(int m, int n)
+ [[ pre: m < 0 ]]
+ [[ pre: n < 0 ]];
+
+ int operator+(int m)
+ [[ pre: m > 0 ]]
+ [[ pre: v > 0 ]];
+
+ int operator-(int m)
+ [[ pre: m > 0 ]]
+ [[ pre: v > 0 ]];
+
+ ~T1()
+ [[ pre: v > 0 ]];
+
+ int v{-10};
+ };
+
+ T1::T1(int m, int n)
+ [[ pre: m < 0 ]]
+ [[ pre: n < 0 ]]
+ : v{-m * n}
+ {
+ }
+
+ int T1::operator+(int m)
+ [[ pre: m > 0 ]]
+ [[ pre: v > 0 ]]
+ {
+ return v + m;
+ }
+
+ int T1::operator-(int m)
+ [[ pre: m > 0 ]]
+ [[ pre: v > 0 ]]
+ {
+ return v - m;
+ }
+
+ T1::~T1()
+ [[ pre: v > 0 ]]
+ {
+ }
+
+ struct T2
+ {
+ T2(int m, int n)
+ [[ pre: m < 0 ]]
+ [[ pre: n < 0 ]]
+ : v{-m * n}
+ {
+ }
+
+ int operator+(int m)
+ [[ pre: m > 0 ]]
+ [[ pre: v > 0 ]]
+ {
+ return v + m;
+ }
+
+ int operator-(int m)
+ [[ pre: m > 0 ]]
+ [[ pre: v > 0 ]]
+ {
+ return v - m;
+ }
+
+ ~T2()
+ [[ pre: v > 0 ]]
+ {
+ }
+
+ int v{-10};
+ };
+
+ struct TC : T1
+ {
+ TC(int m, int n)
+ [[ pre: m < -1 ]]
+ [[ pre: n < -1 ]]
+ : T1{m, n}
+ {
+ }
+
+ ~TC()
+ [[ pre: vc < 0 ]]
+ {
+ }
+
+ TC(int a)
+ [[ pre: a < 0 ]]
+ : TC{a, a}
+ {
+ }
+
+ int vc{10};
+ };
+
+ void test()
+ {
+ T1 t1{10, 20};
+ int a = t1 - -5;
+ int b = t1 + -5;
+ printf("==========\n");
+
+ T2 t2{10, 20};
+ int k = t2 - -5;
+ int j = t2 + -5;
+ printf("==========\n");
+
+ TC tc{10, 20};
+ printf("==========\n");
+
+ TC tc2{10};
+ printf("==========\n");
+ }
+}
+
+namespace virt
+{
+ struct T1
+ {
+ virtual int fun(int m, int n)
+ [[ pre: m > 0 ]]
+ [[ pre: n > 0 ]]
+ [[ pre: v > 0 ]];
+ int v{-10};
+ };
+
+ int T1::fun(int m, int n)
+ [[ pre: m > 0 ]]
+ [[ pre: n > 0 ]]
+ [[ pre: v > 0 ]]
+ {
+ printf("T1::fun::m: %d, T1::fun::n: %d, T1::v: %d\n", m, n, v);
+ return m * n * v;
+ }
+
+ struct T2 : T1
+ {
+ };
+
+ struct T3 : T2
+ {
+ virtual int fun(int m, int n)
+ [[ pre: m > 0 ]]
+ [[ pre: n > 0 ]]
+ [[ pre: v > 0 ]]
+ override
+ {
+ printf("T3::fun::m: %d, T3::fun::n: %d, T3::v: %d\n", m, n, v);
+ return m * n * v;
+ }
+ };
+
+ struct T3b : T2
+ {
+ virtual int fun(int m, int n)
+ [[ pre: m > 0 ]]
+ [[ pre: n > 0 ]]
+ [[ pre: v > 0 ]]
+ override;
+
+ int p(int a)
+ [[ pre: a > 0 ]]
+ [[ pre: v > 0 ]];
+
+ int u(int a)
+ [[ pre: a > 0 ]]
+ [[ pre: z > 0 ]];
+
+ int n(int a)
+ [[ pre: a > 0 ]];
+
+ static int Sn(int a)
+ [[ pre: a > 0 ]];
+
+ int z{-10};
+ };
+
+ int T3b::fun(int m, int n)
+ [[ pre: m > 0 ]]
+ [[ pre: n > 0 ]]
+ [[ pre: v > 0 ]]
+ {
+ printf("T3b::fun::m: %d, T3b::fun::n: %d, T3b::v: %d\n", m, n, v);
+ return m * n * v;
+ }
+
+ int T3b::p(int a)
+ [[ pre: a > 0 ]]
+ [[ pre: v > 0 ]]
+ {
+ printf("T3b::p: a: %d, v: %d\n", a, v);
+ return a * v;
+ }
+
+ int T3b::u(int a)
+ [[ pre: a > 0 ]]
+ [[ pre: z > 0 ]]
+ {
+ printf("T3b::u: a: %d, z: %d\n", a, z);
+ return a * z;
+ }
+
+ int T3b::n(int a)
+ [[ pre: a > 0 ]]
+ {
+ printf("T3b::n: a: %d\n", a);
+ return a;
+ }
+
+ int T3b::Sn(int a)
+ [[ pre: a > 0 ]]
+ {
+ printf("T3b::Sn: a: %d\n", a);
+ return a;
+ }
+
+ struct T3c : T2
+ {
+ int fun(int m, int n)
+ [[ pre: m > 0 ]]
+ [[ pre: n > 0 ]]
+ [[ pre: v > 0 ]]
+ {
+ printf("T3c::fun::m: %d, T3c::fun::n: %d, T3c::v: %d\n", m, n, v);
+ return m * n * v;
+ }
+
+ int p(int a)
+ [[ pre: a > 0 ]]
+ [[ pre: v > 0 ]]
+ {
+ printf("T3c::p: a: %d, v: %d\n", a, v);
+ return a * v;
+ }
+
+ int u(int a)
+ [[ pre: a > 0 ]]
+ [[ pre: z > 0 ]]
+ {
+ printf("T3c::u: a: %d, z: %d\n", a, z);
+ return a * z;
+ }
+
+ int n(int a)
+ [[ pre: a > 0 ]]
+ {
+ printf("T3c::n: a: %d\n", a);
+ return a;
+ }
+
+ static int Sn(int a)
+ [[ pre: a > 0 ]]
+ {
+ printf("T3c::Sn: a: %d\n", a);
+ return a;
+ }
+
+ int z{-10};
+ };
+
+ void t(const char *kind, T1 *t)
+ {
+ printf("=================\n%s:\n", kind);
+ t->fun(-1, -2);
+ }
+
+ void test()
+ {
+ T1 t1;
+ t1.fun(-10, -20);
+
+ T2 t2;
+ t2.fun(-10, -20);
+
+ T3 t3;
+ t3.fun(-10, -20);
+
+ T3b t3b;
+ t3b.fun(-10, -20);
+
+ T3c t3c;
+ t3c.fun(-10, -20);
+
+ t("T1", &t1);
+ t("T2", &t2);
+ t("T3", &t3);
+ t("T3b", &t3b);
+ t("T3c", &t3c);
+
+ printf("=============\n");
+ t3b.p(-3);
+ t3b.u(-3);
+ t3b.n(-3);
+ T3b::Sn(-3);
+
+ printf("=============\n");
+ t3c.p(-3);
+ t3c.u(-3);
+ t3c.n(-3);
+ T3c::Sn(-3);
+ }
+}
+
+int main(int, char**)
+{
+ // ordinary member functions
+ {
+ int x = 11;
+ double y = 11.5;
+ member::T1 t1;
+ t1.vfun(x, y);
+
+ int f = 13;
+ f = t1.fun(x, y);
+ printf("main::f: %d\n", f);
+ double d = 13.37;
+ d = t1.fun2(x, y);
+ printf("main::d: %f\n", d);
+ member::S s = t1.funend(x, y);
+ printf("main::s.z: %d\n", s.z ? 1 : 0);
+ }
+
+ special::test();
+ virt::test();
+ return 0;
+}
+
+member::S member::T1::funend(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: m < 0 ]]
+{
+ printf("funend::x: %d\n", x);
+ S s;
+ s.z = true;
+ return s;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 37 member::T1::vfun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 38 member::T1::vfun .*(\n|\r\n|\r)*" }
+// { dg-output "vfun::x: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 45 member::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "fun::x: 10(\n|\r\n|\r)*" }
+// { dg-output "main::f: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 52 member::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 53 member::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 54 member::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 55 member::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "fun2::x: 10 fun2::y: 10.500000(\n|\r\n|\r)*" }
+// { dg-output "main::d: 10.500000(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 397 member::T1::funend .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 398 member::T1::funend .*(\n|\r\n|\r)*" }
+// { dg-output "funend::x: 10(\n|\r\n|\r)*" }
+// { dg-output "main::s.z: 1(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 85 special::T1::T1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 86 special::T1::T1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 99 special::T1::operator- .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 100 special::T1::operator- .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 92 special::T1::operator. .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 93 special::T1::operator. .*(\n|\r\n|\r)*" }
+// { dg-output "==========(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 113 special::T2::T2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 114 special::T2::T2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 127 special::T2::operator- .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 128 special::T2::operator- .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 120 special::T2::operator. .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 121 special::T2::operator. .*(\n|\r\n|\r)*" }
+// { dg-output "==========(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 144 special::TC::TC .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 145 special::TC::TC .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 85 special::T1::T1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 86 special::T1::T1 .*(\n|\r\n|\r)*" }
+// { dg-output "==========(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 156 special::TC::TC .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 144 special::TC::TC .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 145 special::TC::TC .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 85 special::T1::T1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 86 special::T1::T1 .*(\n|\r\n|\r)*" }
+// { dg-output "==========(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 151 special::TC::~TC .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 106 special::T1::~T1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 151 special::TC::~TC .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 106 special::T1::~T1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 134 special::T2::~T2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 106 special::T1::~T1 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 196 virt::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 197 virt::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 198 virt::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "T1::fun::m: -10, T1::fun::n: -20, T1::v: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 196 virt::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 197 virt::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 198 virt::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "T1::fun::m: -10, T1::fun::n: -20, T1::v: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 211 virt::T3::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 212 virt::T3::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 213 virt::T3::fun .*(\n|\r\n|\r)*" }
+// { dg-output "T3::fun::m: -10, T3::fun::n: -20, T3::v: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 247 virt::T3b::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 248 virt::T3b::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 249 virt::T3b::fun .*(\n|\r\n|\r)*" }
+// { dg-output "T3b::fun::m: -10, T3b::fun::n: -20, T3b::v: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 288 virt::T3c::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 289 virt::T3c::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 290 virt::T3c::fun .*(\n|\r\n|\r)*" }
+// { dg-output "T3c::fun::m: -10, T3c::fun::n: -20, T3c::v: -10(\n|\r\n|\r)*" }
+// { dg-output "=================(\n|\r\n|\r)*" }
+// { dg-output "T1:(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 196 virt::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 197 virt::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 198 virt::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "T1::fun::m: -1, T1::fun::n: -2, T1::v: -10(\n|\r\n|\r)*" }
+// { dg-output "=================(\n|\r\n|\r)*" }
+// { dg-output "T2:(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 196 virt::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 197 virt::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 198 virt::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "T1::fun::m: -1, T1::fun::n: -2, T1::v: -10(\n|\r\n|\r)*" }
+// { dg-output "=================(\n|\r\n|\r)*" }
+// { dg-output "T3:(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 211 virt::T3::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 212 virt::T3::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 213 virt::T3::fun .*(\n|\r\n|\r)*" }
+// { dg-output "T3::fun::m: -1, T3::fun::n: -2, T3::v: -10(\n|\r\n|\r)*" }
+// { dg-output "=================(\n|\r\n|\r)*" }
+// { dg-output "T3b:(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 247 virt::T3b::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 248 virt::T3b::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 249 virt::T3b::fun .*(\n|\r\n|\r)*" }
+// { dg-output "T3b::fun::m: -1, T3b::fun::n: -2, T3b::v: -10(\n|\r\n|\r)*" }
+// { dg-output "=================(\n|\r\n|\r)*" }
+// { dg-output "T3c:(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 288 virt::T3c::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 289 virt::T3c::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 290 virt::T3c::fun .*(\n|\r\n|\r)*" }
+// { dg-output "T3c::fun::m: -1, T3c::fun::n: -2, T3c::v: -10(\n|\r\n|\r)*" }
+// { dg-output "=============(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 256 virt::T3b::p .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 257 virt::T3b::p .*(\n|\r\n|\r)*" }
+// { dg-output "T3b::p: a: -3, v: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 264 virt::T3b::u .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 265 virt::T3b::u .*(\n|\r\n|\r)*" }
+// { dg-output "T3b::u: a: -3, z: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 272 virt::T3b::n .*(\n|\r\n|\r)*" }
+// { dg-output "T3b::n: a: -3(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 279 virt::T3b::Sn .*(\n|\r\n|\r)*" }
+// { dg-output "T3b::Sn: a: -3(\n|\r\n|\r)*" }
+// { dg-output "=============(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 297 virt::T3c::p .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 298 virt::T3c::p .*(\n|\r\n|\r)*" }
+// { dg-output "T3c::p: a: -3, v: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 305 virt::T3c::u .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 306 virt::T3c::u .*(\n|\r\n|\r)*" }
+// { dg-output "T3c::u: a: -3, z: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 313 virt::T3c::n .*(\n|\r\n|\r)*" }
+// { dg-output "T3c::n: a: -3(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 320 virt::T3c::Sn .*(\n|\r\n|\r)*" }
+// { dg-output "T3c::Sn: a: -3(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-pre4.C b/gcc/testsuite/g++.dg/contracts/contracts-pre4.C
new file mode 100644
index 0000000..16189cd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-pre4.C
@@ -0,0 +1,92 @@
+// test that contracts on overriding functions are found correctly
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+
+struct Base
+{
+ virtual int f(int a) [[ pre: a > 0 ]];
+};
+
+int Base::f(int a)
+{
+ return a + 10;
+}
+
+// inherits original
+struct Child0 : Base
+{
+};
+
+// defined out of line, explicit override
+struct Child1 : Base
+{
+ virtual int f(int a) override;
+};
+
+int Child1::f(int a)
+{
+ return a + 20;
+}
+
+// defined out of line
+struct Child2 : Base
+{
+ int f(int a);
+};
+
+int Child2::f(int a)
+{
+ return a + 30;
+}
+
+// defined inline, explicitly override
+struct Child3 : Base
+{
+ virtual int f(int a) override
+ {
+ return a + 40;
+ }
+};
+
+// defined inline
+struct Child4 : Base
+{
+ int f(int a)
+ {
+ return a + 50;
+ }
+};
+
+#include <cstdio>
+int main(int, char**)
+{
+ Base b;
+ Child0 c0;
+ Child1 c1;
+ Child2 c2;
+ Child3 c3;
+ Child4 c4;
+
+ printf("Base: %d\n", b.f(-10));
+ printf("Child0: %d\n", c0.f(-10));
+ printf("Child1: %d\n", c1.f(-10));
+ printf("Child2: %d\n", c2.f(-10));
+ printf("Child3: %d\n", c3.f(-10));
+ printf("Child4: %d\n", c4.f(-10));
+
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 7 Base::f .*(\n|\r\n|\r)*" }
+// { dg-output "Base: 0(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 7 Base::f .*(\n|\r\n|\r)*" }
+// { dg-output "Child0: 0(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 7 Child1::f .*(\n|\r\n|\r)*" }
+// { dg-output "Child1: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 7 Child2::f .*(\n|\r\n|\r)*" }
+// { dg-output "Child2: 20(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 7 Child3::f .*(\n|\r\n|\r)*" }
+// { dg-output "Child3: 30(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 7 Child4::f .*(\n|\r\n|\r)*" }
+// { dg-output "Child4: 40(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-pre5.C b/gcc/testsuite/g++.dg/contracts/contracts-pre5.C
new file mode 100644
index 0000000..278a545
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-pre5.C
@@ -0,0 +1,81 @@
+// basic test to ensure pre contracts work for free templates
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+#include <cstdio>
+
+template<typename T>
+int body(int a)
+ [[ pre: a > 0 ]]
+{
+ T t = a * 2.5;
+ return t;
+}
+
+template<typename T>
+int none(int a)
+ [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+template<typename T>
+int arg0(T t)
+ [[ pre: t > 0 ]]
+{
+ return -t - 10;
+}
+
+template<typename T>
+int arg1(int a, T t)
+ [[ pre: a > 0 ]]
+ [[ pre: t > 0 ]]
+{
+ return -t * a;
+}
+
+template<typename T>
+T ret(int a)
+ [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+int main(int, char**)
+{
+ printf("%d\n", body<int>(-1));
+ printf("%d\n", body<double>(-2));
+ printf("%d\n", none<int>(-1));
+ printf("%d\n", none<double>(-2));
+ printf("%d\n", arg0(-1));
+ printf("%d\n", arg0(-2.9));
+ printf("%d\n", arg1(-3, -1));
+ printf("%d\n", arg1(-4, -2.9));
+ printf("%d\n", (int)ret<int>(-3));
+ printf("%d\n", (int)ret<double>(-4.9));
+
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 8 body<int> .*(\n|\r\n|\r)*" }
+// { dg-output "-2(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 8 body<double> .*(\n|\r\n|\r)*" }
+// { dg-output "-5(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 16 none<int> .*(\n|\r\n|\r)*" }
+// { dg-output "1(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 16 none<double> .*(\n|\r\n|\r)*" }
+// { dg-output "2(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 23 arg0<int> .*(\n|\r\n|\r)*" }
+// { dg-output "-9(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 23 arg0<double> .*(\n|\r\n|\r)*" }
+// { dg-output "-7(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 30 arg1<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 31 arg1<int> .*(\n|\r\n|\r)*" }
+// { dg-output "-3(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 30 arg1<double> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 31 arg1<double> .*(\n|\r\n|\r)*" }
+// { dg-output "-11(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 38 ret<int> .*(\n|\r\n|\r)*" }
+// { dg-output "3(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 38 ret<double> .*(\n|\r\n|\r)*" }
+// { dg-output "4(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-pre6.C b/gcc/testsuite/g++.dg/contracts/contracts-pre6.C
new file mode 100644
index 0000000..44e8e26
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-pre6.C
@@ -0,0 +1,74 @@
+// ensure no errors are thrown when we have to insert a decl for the internal
+// unchecked function after leaving a (possibly nested) namespace
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+namespace ns0
+{
+ int f(int a) [[ pre: a > 0 ]];
+}
+
+int ns0::f(int a) [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+namespace ns0
+{
+ namespace ns1
+ {
+ int f(int a) [[ pre: a > 0 ]];
+ }
+}
+
+int ns0::ns1::f(int a) [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+namespace ns0
+{
+ namespace ns1
+ {
+ int f2(int a) [[ pre: a > 0 ]];
+ namespace ns2
+ {
+ int f(int a) [[ pre: a > 0 ]];
+ }
+ }
+ int ns1::f2(int a) [[ pre: a > 0 ]]
+ {
+ return -a;
+ }
+}
+
+int ns0::ns1::ns2::f(int a) [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+namespace ns0
+{
+ struct S
+ {
+ int f(int a) [[ pre: a > 0 ]];
+ };
+ namespace ns1
+ {
+ struct S2
+ {
+ int f(int a) [[ pre: a > 0 ]];
+ };
+ }
+}
+
+int ns0::S::f(int a) [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+int ns0::ns1::S2::f(int a) [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-pre7.C b/gcc/testsuite/g++.dg/contracts/contracts-pre7.C
new file mode 100644
index 0000000..aeb8fc0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-pre7.C
@@ -0,0 +1,134 @@
+// ensure no errors are thrown when we have to insert a decl for the internal
+// unchecked function after leaving a (possibly nested) namespace
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+
+namespace ns0
+{
+ template<typename T>
+ int f(T a) [[ pre: a > 0 ]];
+}
+
+template<typename T>
+int ns0::f(T a) [[ pre: a > 0 ]]
+{
+ return (int)-a;
+}
+
+namespace ns0
+{
+ namespace ns1
+ {
+ template<typename T>
+ int f(T a) [[ pre: a > 0 ]];
+ }
+}
+
+template<typename T>
+int ns0::ns1::f(T a) [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+namespace ns0
+{
+ namespace ns1
+ {
+ template<typename T>
+ int f2(T a) [[ pre: a > 0 ]];
+ namespace ns2
+ {
+ template<typename T>
+ int f(T a) [[ pre: a > 0 ]];
+ }
+ }
+ template<typename T>
+ int ns1::f2(T a) [[ pre: a > 0 ]]
+ {
+ return -a;
+ }
+}
+
+template<typename T>
+int ns0::ns1::ns2::f(T a) [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+namespace ns0
+{
+ template<typename T>
+ struct S
+ {
+ int f(T a) [[ pre: a > 0 ]];
+ };
+ namespace ns1
+ {
+ template<typename T>
+ struct S2
+ {
+ int f(T a) [[ pre: a > 0 ]];
+ };
+ }
+}
+
+template<typename T>
+int ns0::S<T>::f(T a) [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+template<typename T>
+int ns0::ns1::S2<T>::f(T a) [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+#include <cstdio>
+int main(int, char**)
+{
+ printf ("%d\n", ns0::f(-1));
+ printf ("%d\n", ns0::ns1::f(-2));
+ printf ("%d\n", ns0::ns1::f2(-3));
+ printf ("%d\n", ns0::ns1::ns2::f(-4));
+ ns0::S<int> ns0_s;
+ printf ("%d\n", ns0_s.f(-5));
+ ns0::ns1::S2<int> ns0_ns1_s2;
+ printf ("%d\n", ns0_ns1_s2.f(-6));
+
+ printf ("%d\n", ns0::f(-7.5));
+ printf ("%d\n", ns0::ns1::f(-8.5));
+ printf ("%d\n", ns0::ns1::f2(-9.5));
+ printf ("%d\n", ns0::ns1::ns2::f(-10.5));
+ ns0::S<double> ns0_sd;
+ printf ("%d\n", ns0_sd.f(-11.5));
+ ns0::ns1::S2<double> ns0_ns1_s2d;
+ printf ("%d\n", ns0_ns1_s2d.f(-12.5));
+
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 13 ns0::f<int> .*(\n|\r\n|\r)*" }
+// { dg-output "1(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 28 ns0::ns1::f<int> .*(\n|\r\n|\r)*" }
+// { dg-output "2(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 46 ns0::ns1::f2<int> .*(\n|\r\n|\r)*" }
+// { dg-output "3(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 53 ns0::ns1::ns2::f<int> .*(\n|\r\n|\r)*" }
+// { dg-output "4(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 76 ns0::S<int>::f .*(\n|\r\n|\r)*" }
+// { dg-output "5(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 82 ns0::ns1::S2<int>::f .*(\n|\r\n|\r)*" }
+// { dg-output "6(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 13 ns0::f<double> .*(\n|\r\n|\r)*" }
+// { dg-output "7(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 28 ns0::ns1::f<double> .*(\n|\r\n|\r)*" }
+// { dg-output "8(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 46 ns0::ns1::f2<double> .*(\n|\r\n|\r)*" }
+// { dg-output "9(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 53 ns0::ns1::ns2::f<double> .*(\n|\r\n|\r)*" }
+// { dg-output "10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 76 ns0::S<double>::f .*(\n|\r\n|\r)*" }
+// { dg-output "11(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 82 ns0::ns1::S2<double>::f .*(\n|\r\n|\r)*" }
+// { dg-output "12(\n|\r\n|\r)*" }
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-pre9.C b/gcc/testsuite/g++.dg/contracts/contracts-pre9.C
new file mode 100644
index 0000000..64c0cfa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-pre9.C
@@ -0,0 +1,146 @@
+// ensure no errors are thrown for various combinations of class templates
+// with guarded members
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+
+template<typename T>
+struct S
+{
+ int f(int a) [[ pre: a > 0 ]];
+ int g(int a) [[ pre: a > 0 ]];
+};
+
+template<typename T>
+int S<T>::f(int a) [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+template<typename T>
+int S<T>::g(int a) // Contract is inherited (error from line 10).
+{
+ return -a;
+}
+
+template<typename T>
+struct S_arg
+{
+ int f(T a) [[ pre: a > 0 ]];
+ int g(T a) [[ pre: a > 0 ]];
+};
+
+template<typename T>
+int S_arg<T>::f(T a) [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+template<typename T>
+int S_arg<T>::g(T a) // Contract is inherited (error from line 29).
+{
+ return -a;
+}
+
+template<typename T>
+struct S_ret
+{
+ T f(int a) [[ pre: a > 0 ]];
+ T g(int a) [[ pre: a > 0 ]];
+};
+
+template<typename T>
+T S_ret<T>::f(int a) [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+template<typename T>
+T S_ret<T>::g(int a) // Contract is inherited (error from line 48).
+{
+ return -a;
+}
+
+#include <cstdio>
+int main(int, char**)
+{
+ {
+ S<int> s_int;
+ printf ("s_int.f(-10): %d\n", s_int.f(-10));
+ printf ("s_int.g(-10): %d\n", s_int.g(-10));
+ printf ("s_int.f(10): %d\n", s_int.f(10));
+ printf ("s_int.g(10): %d\n", s_int.g(10));
+
+ S<double> s_double;
+ printf ("s_double.f(-10.5): %d\n", s_double.f(-10.5));
+ printf ("s_double.g(-10.5): %d\n", s_double.g(-10.5));
+ printf ("s_double.f(10.5): %d\n", s_double.f(10.5));
+ printf ("s_double.g(10.5): %d\n", s_double.g(10.5));
+ }
+
+ {
+ S_arg<int> s_arg_int;
+ printf ("s_arg_int.f(-10): %d\n", s_arg_int.f(-10));
+ printf ("s_arg_int.g(-10): %d\n", s_arg_int.g(-10));
+ printf ("s_arg_int.f(10): %d\n", s_arg_int.f(10));
+ printf ("s_arg_int.g(10): %d\n", s_arg_int.g(10));
+
+ S_arg<double> s_arg_double;
+ printf ("s_arg_double.f(-10): %d\n", s_arg_double.f(-10));
+ printf ("s_arg_double.g(-10): %d\n", s_arg_double.g(-10));
+ printf ("s_arg_double.f(10): %d\n", s_arg_double.f(10));
+ printf ("s_arg_double.g(10): %d\n", s_arg_double.g(10));
+ }
+
+ {
+ S_ret<int> s_ret_int;
+ printf ("s_ret_int.f(-10): %d\n", s_ret_int.f(-10));
+ printf ("s_ret_int.g(-10): %d\n", s_ret_int.g(-10));
+ printf ("s_ret_int.f(10): %d\n", s_ret_int.f(10));
+ printf ("s_ret_int.g(10): %d\n", s_ret_int.g(10));
+
+ S_ret<double> s_ret_double;
+ printf ("s_ret_double.f(-10): %f\n", s_ret_double.f(-10));
+ printf ("s_ret_double.g(-10): %f\n", s_ret_double.g(-10));
+ printf ("s_ret_double.f(10): %f\n", s_ret_double.f(10));
+ printf ("s_ret_double.g(10): %f\n", s_ret_double.g(10));
+ }
+
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 14 S<int>::f .*(\n|\r\n|\r)*" }
+// { dg-output "s_int.f.-10.: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 10 S<int>::g .*(\n|\r\n|\r)*" }
+// { dg-output "s_int.g.-10.: 10(\n|\r\n|\r)*" }
+// { dg-output "s_int.f.10.: -10(\n|\r\n|\r)*" }
+// { dg-output "s_int.g.10.: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 14 S<double>::f .*(\n|\r\n|\r)*" }
+// { dg-output "s_double.f.-10.5.: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 10 S<double>::g .*(\n|\r\n|\r)*" }
+// { dg-output "s_double.g.-10.5.: 10(\n|\r\n|\r)*" }
+// { dg-output "s_double.f.10.5.: -10(\n|\r\n|\r)*" }
+// { dg-output "s_double.g.10.5.: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 33 S_arg<int>::f .*(\n|\r\n|\r)*" }
+// { dg-output "s_arg_int.f.-10.: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 29 S_arg<int>::g .*(\n|\r\n|\r)*" }
+// { dg-output "s_arg_int.g.-10.: 10(\n|\r\n|\r)*" }
+// { dg-output "s_arg_int.f.10.: -10(\n|\r\n|\r)*" }
+// { dg-output "s_arg_int.g.10.: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 33 S_arg<double>::f .*(\n|\r\n|\r)*" }
+// { dg-output "s_arg_double.f.-10.: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 29 S_arg<double>::g .*(\n|\r\n|\r)*" }
+// { dg-output "s_arg_double.g.-10.: 10(\n|\r\n|\r)*" }
+// { dg-output "s_arg_double.f.10.: -10(\n|\r\n|\r)*" }
+// { dg-output "s_arg_double.g.10.: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 52 S_ret<int>::f .*(\n|\r\n|\r)*" }
+// { dg-output "s_ret_int.f.-10.: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 48 S_ret<int>::g .*(\n|\r\n|\r)*" }
+// { dg-output "s_ret_int.g.-10.: 10(\n|\r\n|\r)*" }
+// { dg-output "s_ret_int.f.10.: -10(\n|\r\n|\r)*" }
+// { dg-output "s_ret_int.g.10.: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 52 S_ret<double>::f .*(\n|\r\n|\r)*" }
+// { dg-output "s_ret_double.f.-10.: 10.000000(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 48 S_ret<double>::g .*(\n|\r\n|\r)*" }
+// { dg-output "s_ret_double.g.-10.: 10.000000(\n|\r\n|\r)*" }
+// { dg-output "s_ret_double.f.10.: -10.000000(\n|\r\n|\r)*" }
+// { dg-output "s_ret_double.g.10.: -10.000000(\n|\r\n|\r)*" }
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-redecl1.C b/gcc/testsuite/g++.dg/contracts/contracts-redecl1.C
new file mode 100644
index 0000000..58d0aaf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-redecl1.C
@@ -0,0 +1,149 @@
+// generic error tests for contract redecls with generalized redecl
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+// OK if equivalent -- even through renames.
+int g0(int a) [[ pre: a > 0 ]];
+int g0(int a) [[ pre: a > 0 ]];
+
+int g0b(int a) [[ pre: a > 0 ]];
+int g0b(int b) [[ pre: b > 0 ]];
+int g0b(int c) [[ pre: c > 0 ]]
+{
+ return 0;
+}
+
+// OK if specified before.
+int g1(int a) [[ pre: a > 0 ]];
+int g1(int a);
+
+// OK if specified after.
+int g2(int a);
+int g2(int a) [[ pre: a > 0 ]];
+
+int g2b(int a);
+int g2b(int b) [[ pre: b > 0 ]];
+
+// can add to non-virtual methods
+struct G0
+{
+ int f(int a);
+};
+
+// OK to add contracts at the point of definition.
+int G0::f(int a) [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+struct G1
+{
+ int f1(int a);
+};
+
+// OK to redeclare functions and add constraints...
+int G1::f1(int a) [[ pre: a > 0 ]];
+
+// ...and leave them off later.
+int G1::f1(int a)
+{
+ return -a;
+}
+
+int f0(int a) [[ pre: a > 0 ]];
+int f0(int a) [[ pre: a > 0 ]] [[ pre: a > 10 ]]; // { dg-error "different number of contracts" }
+
+int f1(int a) [[ pre: a > 0 ]] [[ pre: a > 10 ]];
+int f1(int a) [[ pre: a > 0 ]]; // { dg-error "different number of contracts" }
+
+int f2(int a) [[ pre: a > 0 ]];
+int f2(int a) [[ pre: a < 0 ]]; // { dg-error "mismatched contract" }
+
+int f3(int a) { return a; }
+int f3(int a) [[ pre: a < 0 ]]; // { dg-error "cannot add contracts" }
+
+struct Base
+{
+ virtual int f(int a) [[ pre: a > 0 ]];
+};
+
+struct Child : Base
+{
+ int f(int a) [[ pre: a < 0 ]]; // { dg-error "mismatched contract" }
+};
+
+struct S1
+{
+ virtual int f(int a); // contracts are inherited at the point of declarations
+};
+
+int S1::f(int a) [[ pre: a > 0 ]] // { dg-error "cannot add" }
+{
+ return -a;
+}
+
+struct S2
+{
+ int f() { return 0; }
+};
+
+int S2::f(); // OK?
+
+
+struct S3
+{
+ int f() { return 0; }
+};
+
+int S3::f() [[pre: true]]; // { dg-error "cannot add contracts" }
+
+
+// The initial decl of a guarded member must appear inside the class.
+struct S4
+{
+ int f(int a);
+};
+
+int S4::g(int a) [[ pre: a > 0 ]]; // { dg-error "no declaration matches" }
+
+
+struct S5
+{
+ template<typename T>
+ S5(T a);
+};
+
+template<typename T>
+S5::S5(T a) [[ pre: a > 0 ]]
+{
+}
+
+struct S6
+{
+ template<typename T>
+ S6(T a);
+};
+
+template<typename T>
+S6::S6(T a) [[ pre: a > 0 ]];
+
+template<typename T>
+S6::S6(T a)
+{
+}
+
+int p0(int n)
+ [[ post r: r > 0 && r == n ]]
+ [[ post r: r > 1 && r == n ]]
+ [[ post r: r > 2 && r == n ]]
+ [[ post r: r > 3 && r == n ]];
+
+int p0(int z)
+ [[ post r: r > 0 && r == z ]]
+ [[ post r1: r1 > 1 && r1 == z ]]
+ [[ post r2: r2 > 2 && r2 == z ]]
+ [[ post r3: r3 > 3 && r3 == z ]]
+{
+ return z;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-redecl2.C b/gcc/testsuite/g++.dg/contracts/contracts-redecl2.C
new file mode 100644
index 0000000..70c9259
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-redecl2.C
@@ -0,0 +1,149 @@
+// generic error tests for generalized contract redecls
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+// allowed to repeat contracts or omit them
+int g0(int a) [[ pre: a > 0 ]];
+int g0(int a) [[ pre: a > 0 ]];
+
+int g1(int a) [[ pre: a > 0 ]];
+int g1(int a);
+
+// allowed to add from none if generalized redecl is on (by default)
+int g2(int a);
+int g2(int a) [[ pre: a > 0 ]];
+
+// can add to non-virtual methods
+struct G0
+{
+ int f(int a);
+};
+
+int G0::f(int a) [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+struct G1
+{
+ int f(int a);
+};
+
+int G1::f(int a) [[ pre: a > 0 ]];
+
+int G1::f(int a)
+{
+ return -a;
+}
+
+// allowed to redeclare even without contracts
+struct G2
+{
+ int f(int a);
+};
+
+int G2::f(int a);
+
+
+int f0(int a) [[ pre: a > 0 ]];
+int f0(int a) [[ pre: a > 0 ]] [[ pre: a > 10 ]]; // { dg-error "different number of contracts" }
+
+int f1(int a) [[ pre: a > 0 ]];
+int f1(int a) [[ pre: a < 0 ]]; // { dg-error "mismatched contract" }
+
+int f2(int a) { return a; }
+int f2(int a) [[ pre: a < 0 ]]; // { dg-error "cannot add contracts after definition" }
+
+struct Base
+{
+ virtual int f(int a) [[ pre: a > 0 ]];
+};
+
+struct Child : Base
+{
+ int f(int a) [[ pre: a < 0 ]]; // { dg-error "mismatched contract" }
+};
+
+// the initial decl of a guarded member must appear inside the class
+struct F2
+{
+ int f(int a);
+};
+
+int F2::g(int a) [[ pre: a > 0 ]]; // { dg-error "no declaration matches" }
+// FIXME if we move F2 down then a different error makes F2 undeclared
+
+struct F0
+{
+ virtual int f(int a);
+};
+
+int F0::f(int a); // { dg-error "declaration.*is not definition" }
+
+struct F1
+{
+ virtual int f(int a);
+};
+
+int F1::f(int a) [[ pre: a > 0 ]] // { dg-error "cannot add" }
+{
+ return -a;
+}
+
+// cannot "re"declare members of a forward declared class
+struct F2;
+int F2::test(); // { dg-error "no declaration matches" }
+int F2::test2() [[ pre: true ]]; // { dg-error "no declaration matches" }
+
+// can only redeclare member functions
+struct F3
+{
+ int x;
+ typedef int my_int;
+
+ struct Inner0;
+ struct Inner1;
+ enum my_enum0; // { dg-error "use of enum.*without previous decl" }
+ enum my_enum1 { E1, E2 };
+
+ int test0();
+ int test1();
+ int test2();
+};
+
+int F3::x{-1}; // { dg-error "is not a static data member" }
+typedef double F3::my_int; // { dg-error "typedef name may not be a nested-name-specifier" }
+struct F3::Inner0; // { dg-warning "declaration.*does not declare anything" }
+
+struct F3::Inner1 { };
+
+enum F3::my_enum1 { E0, E1, END }; // { dg-error "multiple definition" }
+
+struct F4
+{
+ int test0();
+
+ int F3::test0() [[ pre: true ]]; // { dg-error "cannot declare member function" }
+ friend int F3::test1();
+ friend int F3::test2();
+};
+int F3::test2() [[ pre: true ]] { return -1; }
+
+void dummy0()
+{
+ int F4::test0() [[ pre: true ]]; // { dg-error "qualified-id in declaration" }
+}
+
+namespace ns0
+{
+ typedef int value;
+ struct X
+ {
+ int test1(value);
+ typedef double value;
+ int test2(value);
+ };
+ int X::test1(value); // { dg-error "no declaration matches" }
+ int X::test2(value);
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-redecl3.C b/gcc/testsuite/g++.dg/contracts/contracts-redecl3.C
new file mode 100644
index 0000000..fdfca3a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-redecl3.C
@@ -0,0 +1,195 @@
+// basic test to ensure contracts generalized redecl works
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+#include <cstdio>
+
+namespace defining
+{
+ int x = 10;
+ double y = 10.5;
+
+ struct S
+ {
+ bool z;
+ };
+
+ struct T1
+ {
+ void vfun(int m, double n);
+ int fun(int m, double n);
+ double fun2(int m, double n);
+ S funend(int m, double n);
+ };
+
+ void T1::vfun(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: m < 0 ]]
+ {
+ printf("vfun::x: %d\n", x);
+ }
+
+ int T1::fun(int m, double n)
+ [[ pre: x < 0 ]]
+ {
+ printf("fun::x: %d\n", x);
+ return x;
+ }
+
+ double T1::fun2(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: y < 0 ]]
+ [[ pre: m < 0 ]]
+ [[ pre: n < 0 ]]
+ {
+ printf("fun2::x: %d fun2::y: %f\n", x, y);
+ return y;
+ }
+}
+
+namespace nondefining
+{
+ int x = 10;
+ double y = 10.5;
+
+ struct S
+ {
+ bool z;
+ };
+
+ struct T1
+ {
+ void vfun(int m, double n);
+ int fun(int m, double n);
+ double fun2(int m, double n);
+ S funend(int m, double n);
+ };
+
+ void T1::vfun(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: m < 0 ]];
+ int T1::fun(int m, double n)
+ [[ pre: x < 0 ]];
+ double T1::fun2(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: y < 0 ]]
+ [[ pre: m < 0 ]]
+ [[ pre: n < 0 ]];
+
+ void T1::vfun(int m, double n)
+ {
+ printf("vfun::x: %d\n", x);
+ }
+
+ int T1::fun(int m, double n)
+ {
+ printf("fun::x: %d\n", x);
+ return x;
+ }
+
+ double T1::fun2(int m, double n)
+ {
+ printf("fun2::x: %d fun2::y: %f\n", x, y);
+ return y;
+ }
+}
+
+int main(int, char**) {
+ // defining redecl
+ {
+ int x = 11;
+ double y = 11.5;
+
+ defining::T1 t1;
+ t1.vfun(x, y);
+
+ int f = 13;
+ f = t1.fun(x, y);
+ printf("main::f: %d\n", f);
+ double d = 13.37;
+ d = t1.fun2(x, y);
+ printf("main::d: %f\n", d);
+ defining::S s = t1.funend(x, y);
+ printf("main::s.z: %d\n", s.z ? 1 : 0);
+ }
+
+ // nondefining redecl
+ {
+ int x = 12;
+ double y = 12.5;
+
+ nondefining::T1 t1;
+ t1.vfun(x, y);
+
+ int f = 13;
+ f = t1.fun(x, y);
+ printf("main::f: %d\n", f);
+ double d = 13.37;
+ d = t1.fun2(x, y);
+ printf("main::d: %f\n", d);
+ nondefining::S s = t1.funend(x, y);
+ printf("main::s.z: %d\n", s.z ? 1 : 0);
+ }
+ return 0;
+}
+
+namespace defining
+{
+ S T1::funend(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: m < 0 ]]
+ {
+ printf("funend::x: %d\n", x);
+ S s;
+ s.z = true;
+ return s;
+ }
+}
+
+namespace nondefining
+{
+ S T1::funend(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: m < 0 ]];
+
+ S T1::funend(int m, double n)
+ {
+ printf("funend::x: %d\n", x);
+ S s;
+ s.z = true;
+ return s;
+ }
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 25 defining::T1::vfun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 26 defining::T1::vfun .*(\n|\r\n|\r)*" }
+// { dg-output "vfun::x: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 32 defining::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "fun::x: 10(\n|\r\n|\r)*" }
+// { dg-output "main::f: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 39 defining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 40 defining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 41 defining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 42 defining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "fun2::x: 10 fun2::y: 10.500000(\n|\r\n|\r)*" }
+// { dg-output "main::d: 10.500000(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 138 defining::T1::funend .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 139 defining::T1::funend .*(\n|\r\n|\r)*" }
+// { dg-output "funend::x: 10(\n|\r\n|\r)*" }
+// { dg-output "main::s.z: 1(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 68 nondefining::T1::vfun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 69 nondefining::T1::vfun .*(\n|\r\n|\r)*" }
+// { dg-output "vfun::x: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 71 nondefining::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "fun::x: 10(\n|\r\n|\r)*" }
+// { dg-output "main::f: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 73 nondefining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 74 nondefining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 75 nondefining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 76 nondefining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "fun2::x: 10 fun2::y: 10.500000(\n|\r\n|\r)*" }
+// { dg-output "main::d: 10.500000(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 151 nondefining::T1::funend .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 152 nondefining::T1::funend .*(\n|\r\n|\r)*" }
+// { dg-output "funend::x: 10(\n|\r\n|\r)*" }
+// { dg-output "main::s.z: 1(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-redecl4.C b/gcc/testsuite/g++.dg/contracts/contracts-redecl4.C
new file mode 100644
index 0000000..c1e2342
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-redecl4.C
@@ -0,0 +1,56 @@
+// test that free functions can be redeclared with contracts without affecting
+// normal default parm handling
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+#include <cstdio>
+
+int f(int a, int, int c = 10);
+int f(int a, int b = 11, int);
+int f(int a, int b, int c)
+ [[ pre: a < 0 ]]
+ [[ pre: b < 0 ]]
+ [[ pre: c < 0 ]];
+
+int f(int, int, int);
+
+int f(int a, int b, int c)
+{
+ printf("f: a: %d, b: %d, c: %d\n", a, b, c);
+ return a * b - c;
+}
+
+int f(int a = 12, int, int);
+
+int main(int, char **)
+{
+ f(1,1,1);
+ printf("=====\n");
+ f(1,1);
+ printf("=====\n");
+ f(1);
+ printf("=====\n");
+ f();
+ printf("=====\n");
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 10 f .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 11 f .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 12 f .*(\n|\r\n|\r)*" }
+// { dg-output "f: a: 1, b: 1, c: 1(\n|\r\n|\r)*" }
+// { dg-output "=====(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 10 f .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 11 f .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 12 f .*(\n|\r\n|\r)*" }
+// { dg-output "f: a: 1, b: 1, c: 10(\n|\r\n|\r)*" }
+// { dg-output "=====(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 10 f .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 11 f .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 12 f .*(\n|\r\n|\r)*" }
+// { dg-output "f: a: 1, b: 11, c: 10(\n|\r\n|\r)*" }
+// { dg-output "=====(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 10 f .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 11 f .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 12 f .*(\n|\r\n|\r)*" }
+// { dg-output "f: a: 12, b: 11, c: 10(\n|\r\n|\r)*" }
+// { dg-output "=====(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-redecl5.C b/gcc/testsuite/g++.dg/contracts/contracts-redecl5.C
new file mode 100644
index 0000000..ea4835f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-redecl5.C
@@ -0,0 +1,101 @@
+// generic error tests for generalized contract redecls
+// we also test for the warning diagnostic for strict redecl
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts -fcontract-strict-declarations=on" }
+
+// allowed to repeat contracts or omit them
+int g0(int a) [[ pre: a > 0 ]];
+int g0(int a) [[ pre: a > 0 ]];
+
+int g1(int a) [[ pre: a > 0 ]];
+int g1(int a);
+
+// allowed to add from none if generalized redecl is on (by default)
+int g2(int a);
+int g2(int a) [[ pre: a > 0 ]]; // { dg-warning "adds contracts" }
+int g2(int a) [[ pre: a > 0 ]]; // { dg-bogus "adds contracts" }
+
+// can add to non-virtual methods
+struct G0
+{
+ int f(int a);
+};
+
+int G0::f(int a) [[ pre: a > 0 ]] // { dg-warning "adds contracts" }
+{
+ return -a;
+}
+
+struct G1
+{
+ int f(int a);
+};
+
+int G1::f(int a) [[ pre: a > 0 ]]; // { dg-warning "adds contracts" }
+// { dg-warning "outside of class is not definition" "" { target *-*-* } .-1 }
+
+int G1::f(int a);
+// { dg-warning "outside of class is not definition" "" { target *-*-* } .-1 }
+
+int G1::f(int a) [[ pre: a > 0 ]];
+// { dg-warning "outside of class is not definition" "" { target *-*-* } .-1 }
+
+int G1::f(int a)
+{
+ return -a;
+}
+
+// allowed to redeclare even without contracts
+struct G2
+{
+ int f(int a);
+};
+
+int G2::f(int a); // { dg-warning "outside of class is not definition" }
+
+
+int f0(int a) [[ pre: a > 0 ]];
+int f0(int a) [[ pre: a > 0 ]] [[ pre: a > 10 ]]; // { dg-error "different number of contracts" }
+
+int f1(int a) [[ pre: a > 0 ]];
+int f1(int a) [[ pre: a < 0 ]]; // { dg-error "mismatched contract" }
+
+int f2(int a) { return a; }
+int f2(int a) [[ pre: a < 0 ]]; // { dg-error "cannot add contracts after definition" }
+
+struct Base
+{
+ virtual int f(int a) [[ pre: a > 0 ]];
+};
+
+struct Child : Base
+{
+ int f(int a) [[ pre: a < 0 ]]; // { dg-error "mismatched contract" }
+};
+
+// the initial decl of a guarded member must appear inside the class
+struct F2
+{
+ int f(int a);
+};
+
+int F2::g(int a) [[ pre: a > 0 ]]; // { dg-error "no declaration matches" }
+// FIXME if we move F2 down then a different error makes F2 undeclared
+
+struct F0
+{
+ virtual int f(int a);
+};
+
+int F0::f(int a); // { dg-error "declaration.*is not definition" }
+
+struct F1
+{
+ virtual int f(int a);
+};
+
+int F1::f(int a) [[ pre: a > 0 ]] // { dg-error "cannot add" }
+{
+ return -a;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-redecl6.C b/gcc/testsuite/g++.dg/contracts/contracts-redecl6.C
new file mode 100644
index 0000000..e79a5aa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-redecl6.C
@@ -0,0 +1,195 @@
+// basic test to ensure contracts generalized redecl works
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+#include <cstdio>
+
+namespace defining
+{
+ int x = 10;
+ double y = 10.5;
+
+ struct S
+ {
+ bool z;
+ };
+
+ struct T1
+ {
+ void vfun(int m, double n) const;
+ int fun(int m, double n) volatile;
+ double fun2(int m, double n) const volatile;
+ static S funend(int m, double n);
+ };
+
+ void T1::vfun(int m, double n) const
+ [[ pre: x < 0 ]]
+ [[ pre: m < 0 ]]
+ {
+ printf("vfun::x: %d\n", x);
+ }
+
+ int T1::fun(int m, double n) volatile
+ [[ pre: x < 0 ]]
+ {
+ printf("fun::x: %d\n", x);
+ return x;
+ }
+
+ double T1::fun2(int m, double n) const volatile
+ [[ pre: x < 0 ]]
+ [[ pre: y < 0 ]]
+ [[ pre: m < 0 ]]
+ [[ pre: n < 0 ]]
+ {
+ printf("fun2::x: %d fun2::y: %f\n", x, y);
+ return y;
+ }
+}
+
+namespace nondefining
+{
+ int x = 10;
+ double y = 10.5;
+
+ struct S
+ {
+ bool z;
+ };
+
+ struct T1
+ {
+ void vfun(int m, double n) const;
+ int fun(int m, double n) volatile;
+ double fun2(int m, double n) const volatile;
+ static S funend(int m, double n);
+ };
+
+ void T1::vfun(int m, double n) const
+ [[ pre: x < 0 ]]
+ [[ pre: m < 0 ]];
+ int T1::fun(int m, double n) volatile
+ [[ pre: x < 0 ]];
+ double T1::fun2(int m, double n) const volatile
+ [[ pre: x < 0 ]]
+ [[ pre: y < 0 ]]
+ [[ pre: m < 0 ]]
+ [[ pre: n < 0 ]];
+
+ void T1::vfun(int m, double n) const
+ {
+ printf("vfun::x: %d\n", x);
+ }
+
+ int T1::fun(int m, double n) volatile
+ {
+ printf("fun::x: %d\n", x);
+ return x;
+ }
+
+ double T1::fun2(int m, double n) const volatile
+ {
+ printf("fun2::x: %d fun2::y: %f\n", x, y);
+ return y;
+ }
+}
+
+int main(int, char**) {
+ // defining redecl
+ {
+ int x = 11;
+ double y = 11.5;
+
+ defining::T1 t1;
+ t1.vfun(x, y);
+
+ int f = 13;
+ f = t1.fun(x, y);
+ printf("main::f: %d\n", f);
+ double d = 13.37;
+ d = t1.fun2(x, y);
+ printf("main::d: %f\n", d);
+ defining::S s = defining::T1::funend(x, y);
+ printf("main::s.z: %d\n", s.z ? 1 : 0);
+ }
+
+ // nondefining redecl
+ {
+ int x = 12;
+ double y = 12.5;
+
+ nondefining::T1 t1;
+ t1.vfun(x, y);
+
+ int f = 13;
+ f = t1.fun(x, y);
+ printf("main::f: %d\n", f);
+ double d = 13.37;
+ d = t1.fun2(x, y);
+ printf("main::d: %f\n", d);
+ nondefining::S s = nondefining::T1::funend(x, y);
+ printf("main::s.z: %d\n", s.z ? 1 : 0);
+ }
+ return 0;
+}
+
+namespace defining
+{
+ S T1::funend(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: m < 0 ]]
+ {
+ printf("funend::x: %d\n", x);
+ S s;
+ s.z = true;
+ return s;
+ }
+}
+
+namespace nondefining
+{
+ S T1::funend(int m, double n)
+ [[ pre: x < 0 ]]
+ [[ pre: m < 0 ]];
+
+ S T1::funend(int m, double n)
+ {
+ printf("funend::x: %d\n", x);
+ S s;
+ s.z = true;
+ return s;
+ }
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 25 defining::T1::vfun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 26 defining::T1::vfun .*(\n|\r\n|\r)*" }
+// { dg-output "vfun::x: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 32 defining::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "fun::x: 10(\n|\r\n|\r)*" }
+// { dg-output "main::f: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 39 defining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 40 defining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 41 defining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 42 defining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "fun2::x: 10 fun2::y: 10.500000(\n|\r\n|\r)*" }
+// { dg-output "main::d: 10.500000(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 138 defining::T1::funend .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 139 defining::T1::funend .*(\n|\r\n|\r)*" }
+// { dg-output "funend::x: 10(\n|\r\n|\r)*" }
+// { dg-output "main::s.z: 1(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 68 nondefining::T1::vfun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 69 nondefining::T1::vfun .*(\n|\r\n|\r)*" }
+// { dg-output "vfun::x: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 71 nondefining::T1::fun .*(\n|\r\n|\r)*" }
+// { dg-output "fun::x: 10(\n|\r\n|\r)*" }
+// { dg-output "main::f: 10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 73 nondefining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 74 nondefining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 75 nondefining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 76 nondefining::T1::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "fun2::x: 10 fun2::y: 10.500000(\n|\r\n|\r)*" }
+// { dg-output "main::d: 10.500000(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 151 nondefining::T1::funend .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 152 nondefining::T1::funend .*(\n|\r\n|\r)*" }
+// { dg-output "funend::x: 10(\n|\r\n|\r)*" }
+// { dg-output "main::s.z: 1(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-redecl7.C b/gcc/testsuite/g++.dg/contracts/contracts-redecl7.C
new file mode 100644
index 0000000..e3a57ee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-redecl7.C
@@ -0,0 +1,95 @@
+// test that contracts can be added during (defining) friend declarations
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+#include <cstdio>
+struct T;
+
+struct S
+{
+ int now(int a, T *t) [[ pre: a > 0 ]] [[ pre: x < 0 ]];
+
+
+ int x{-1};
+};
+
+int now(int a, T *t) [[ pre: a > 0 ]];
+int later(int a, T *t);
+int both(int a, T *t) [[ pre: a > 0 ]];
+
+struct T
+{
+ friend int now(int a, T *t);
+ friend int later(int a, T *t) [[ pre: a > 0 ]] [[ pre: t->pri > 0 ]]
+ {
+ printf("later: a: %d, t->pri: %d\n", a, t->pri);
+ return -a * t->pri;
+ }
+ friend int both(int a, T *t) [[ pre: a > 0 ]]
+ {
+ printf("both: a: %d, t->pri: %d\n", a, t->pri);
+ return -a * t->pri;
+ }
+
+
+ friend int S::now(int a, T *t);
+
+ friend int hidden(int a, T *t) [[ pre: a > 0 ]] [[ pre: t->pri > 0 ]]
+ {
+ printf("hidden: a: %d, t->pri: %d\n", a, t->pri);
+ return -a * t->pri;
+ }
+ friend int hidden2(int a, T *t) [[ pre: a > 0 ]] [[ pre: t->pri > 0 ]]
+ {
+ printf("hidden2: a: %d, t->pri: %d\n", a, t->pri);
+ return -a * t->pri;
+ }
+
+ int x{1};
+ private:
+ int pri{-10};
+};
+
+int hidden2(int a, T *t) [[ pre: a > 0 ]] [[ pre: t->pri > 0 ]];
+
+int S::now(int a, T *t)
+{
+ printf("S::now: a: %d, t->pri: %d\n", a, t->pri);
+ return -a * t->pri;
+}
+
+int now(int a, T *t)
+{
+ printf("now: a: %d, t->pri: %d\n", a, t->pri);
+ return -a * t->pri;
+}
+
+int main(int, char**)
+{
+ T t;
+ S s;
+ s.now(-10, &t);
+
+ now(-20, &t);
+ later(-21, &t);
+ both(-22, &t);
+ hidden(-23, &t);
+ hidden2(-24, &t);
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 9 S::now .*(\n|\r\n|\r)*" }
+// { dg-output "S::now: a: -10, t->pri: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 15 now .*(\n|\r\n|\r)*" }
+// { dg-output "now: a: -20, t->pri: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 22 later .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 22 later .*(\n|\r\n|\r)*" }
+// { dg-output "later: a: -21, t->pri: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 27 both .*(\n|\r\n|\r)*" }
+// { dg-output "both: a: -22, t->pri: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 36 hidden .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 36 hidden .*(\n|\r\n|\r)*" }
+// { dg-output "hidden: a: -23, t->pri: -10(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 41 hidden2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 41 hidden2 .*(\n|\r\n|\r)*" }
+// { dg-output "hidden2: a: -24, t->pri: -10(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-redecl8.C b/gcc/testsuite/g++.dg/contracts/contracts-redecl8.C
new file mode 100644
index 0000000..933adce
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-redecl8.C
@@ -0,0 +1,64 @@
+// test that contracts are matched on friend decls when the type is complete
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+struct T;
+
+int both(int x, T *t) [[ pre: x > 0 ]] { return 0; }
+int both2(int x, T *t) [[ pre: x > 0 ]];
+
+template<typename Z>
+int fn(int x, Z *z) [[ pre: x > 0 ]];
+
+template<typename Z>
+int fn2(int x, Z *z);
+
+template<typename Z>
+int fn3(int x, Z *z) [[ pre: x > 0 ]];
+
+template<>
+int fn3<T>(int x, T *z) [[ pre: x > 1 ]];
+
+struct T
+{
+ friend int both2(int x, T *t) [[ pre: x > 1 ]] // { dg-error "mismatched" }
+ {
+ return 0;
+ }
+
+ friend int hidden(int x, T *t)
+ [[ pre: x > 1 ]] [[ pre: t->pri > 0 ]]
+ {
+ return x;
+ }
+
+ /* cannot define friend spec, so we never get to matching contracts
+ friend int fn<T>(int x, T *t)
+ [[ pre: t->pri > 0 ]] { return 0; } // error defining explicit spec friend
+ */
+
+ // bad, general contracts must match general
+ template<typename Z>
+ friend int fn(int x, Z *z)
+ [[ pre: z->pri > 1 ]] { return 0; } // { dg-error "mismatched" }
+
+ // fine, can add contracts
+ template<typename Z>
+ friend int fn2(int x, Z *z)
+ [[ pre: z->pri > 1 ]] { return 0; } // { dg-bogus "mismatched" }
+
+ /* cannot declare without definition, so dup friend can't occur:
+ friend int dup(int x, T *t)
+ [[ pre: t->pri > 0 ]]; // error non-defining friend with contracts
+ friend int dup(int x, T *t)
+ [[ pre: t->pri > 1 ]]; // error non-defining friend with contracts
+ */
+
+ int x{1};
+ private:
+ int pri{-10};
+};
+
+int hidden(int x, T *t)
+ [[ pre: x > 0 ]] [[ pre: t->pri > 1 ]]; // { dg-error "mismatched" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-tmpl-attr1.C b/gcc/testsuite/g++.dg/contracts/contracts-tmpl-attr1.C
new file mode 100644
index 0000000..c9e7b9c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-tmpl-attr1.C
@@ -0,0 +1,19 @@
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+template<typename T>
+[[z]]
+[[nodiscard]]
+T fun(T n)
+ [[ pre: n > 0 ]]
+ [[ post r: r > 0 ]] // { dg-warning ".z. attribute.*ignored" }
+{
+ return n;
+}
+
+int main(int, char**) {
+ fun(-5); // { dg-warning "ignoring return value" }
+ fun(-5.3); // { dg-warning "ignoring return value" }
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec1.C b/gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec1.C
new file mode 100644
index 0000000..57ba765
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec1.C
@@ -0,0 +1,121 @@
+// basic test to ensure pre contracts work for free template specializations
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+#include <cstdio>
+
+template<typename T>
+int body(int a)
+ [[ pre: a > 0 ]]
+{
+ T t = a * 2.5;
+ return t;
+}
+
+template<>
+int body<double>(int a)
+ [[ pre: a > 0 ]]
+{
+ double t = a * 3.3;
+ return t;
+}
+
+template<typename T>
+int none(int a)
+ [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+template<>
+int none<double>(int a)
+ [[ pre: a > 0 ]]
+{
+ return a - 100;
+}
+
+template<typename T>
+int arg0(T t)
+ [[ pre: t > 0 ]]
+{
+ return -t - 10;
+}
+
+template<>
+int arg0<double>(double t)
+ [[ pre: t > 0 ]]
+{
+ return -t + 10;
+}
+
+template<typename T>
+int arg1(int a, T t)
+ [[ pre: a > 0 ]]
+ [[ pre: t > 0 ]]
+{
+ return -t * a;
+}
+
+template<>
+int arg1<double>(int a, double t)
+ [[ pre: a > 0 ]]
+ [[ pre: t > 0 ]]
+{
+ return -t * a + 17;
+}
+
+template<typename T>
+T ret(int a)
+ [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+template<>
+double ret<double>(int a)
+ [[ pre: a > 0 ]]
+{
+ return -a * 3.3;
+}
+
+
+int main(int, char**)
+{
+ printf("%d\n", body<int>(-1));
+ printf("%d\n", body<double>(-1));
+ printf("%d\n", none<int>(-1));
+ printf("%d\n", none<double>(-1));
+ printf("%d\n", arg0(-1));
+ printf("%d\n", arg0(-1.0));
+ printf("%d\n", arg1(-3, -1));
+ printf("%d\n", arg1(-3, -1.0));
+ printf("%d\n", (int)ret<int>(-1));
+ printf("%d\n", (int)ret<double>(-1));
+ printf("%f\n", ret<double>(-1));
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 8 body<int> .*(\n|\r\n|\r)*" }
+// { dg-output "-2(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 16 body<double> .*(\n|\r\n|\r)*" }
+// { dg-output "-3(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 24 none<int> .*(\n|\r\n|\r)*" }
+// { dg-output "1(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 31 none<double> .*(\n|\r\n|\r)*" }
+// { dg-output "-101(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 38 arg0<int> .*(\n|\r\n|\r)*" }
+// { dg-output "-9(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 45 arg0<double> .*(\n|\r\n|\r)*" }
+// { dg-output "11(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 52 arg1<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 53 arg1<int> .*(\n|\r\n|\r)*" }
+// { dg-output "-3(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 60 arg1<double> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 61 arg1<double> .*(\n|\r\n|\r)*" }
+// { dg-output "14(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 68 ret<int> .*(\n|\r\n|\r)*" }
+// { dg-output "1(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 75 ret<double> .*(\n|\r\n|\r)*" }
+// { dg-output "3(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 75 ret<double> .*(\n|\r\n|\r)*" }
+// { dg-output "3.300000(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec2.C b/gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec2.C
new file mode 100644
index 0000000..25982df
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec2.C
@@ -0,0 +1,395 @@
+// basic test to ensure contracts work for class and member specializations
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+#include <cstdio>
+
+// template specializations can have differing contracts
+template<typename T>
+int body(int a)
+ [[ pre: a > 0 ]]
+{
+ T t = a * 2.5;
+ return t;
+}
+
+template<>
+int body<double>(int a)
+ [[ pre: a > 1 ]]
+{
+ double t = a * 3.3;
+ return t;
+}
+
+template<typename T>
+int none(int a)
+ [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+template<>
+int none<double>(int a)
+ [[ pre: a > 1 ]]
+{
+ return a - 100;
+}
+
+template<typename T>
+int arg0(T t)
+ [[ pre: t > 0 ]]
+{
+ return -t - 10;
+}
+
+template<>
+int arg0<double>(double t)
+ [[ pre: t > 1 ]]
+{
+ return -t + 10;
+}
+
+template<typename T>
+int arg1(int a, T t)
+ [[ pre: a > 0 ]]
+ [[ pre: t > 0 ]]
+{
+ return -t * a;
+}
+
+template<>
+int arg1<double>(int a, double t)
+ [[ pre: a > 1 ]]
+ [[ pre: t > 1 ]]
+{
+ return -t * a + 17;
+}
+
+template<typename T>
+T ret(int a)
+ [[ pre: a > 0 ]]
+{
+ return -a;
+}
+
+template<>
+double ret<double>(int a)
+ [[ pre: a > 1 ]]
+{
+ return -a * 3.3;
+}
+
+// template specializations can have no contracts
+template<typename T>
+int g1(T t) [[ pre: t > 0 ]]
+{
+ return (int)t;
+}
+
+template<>
+int g1<double>(double t)
+{
+ return (int)t;
+}
+
+// template specializations can have no contracts in the first decl but add
+// them later
+template<typename T>
+int g2(T t) [[ pre: t > 0 ]]
+{
+ return (int)t;
+}
+
+template<>
+int g2<double>(double t);
+
+template<>
+int g2<double>(double t)
+ [[ pre: t < 0 ]]
+{
+ return (int)t;
+}
+
+template<>
+int g2<char>(char t)
+ [[ pre: t < 'c' ]]
+{
+ return (int)t;
+}
+
+// contracts can be different on the general template, partial and full specs
+template<typename T, typename S>
+struct G3
+{
+ void f(T t, S s)
+ [[ pre: t > 0 ]]
+ [[ pre: s > 0 ]]
+ {
+ printf ("G3 general T S\n");
+ }
+};
+
+template<typename S>
+struct G3<int, S>
+{
+ void f(int t, S s);
+};
+
+template<typename S>
+void G3<int, S>::f(int t, S s)
+ [[ pre: t > 1 ]]
+ [[ pre: s > 1 ]]
+{
+ printf ("G3 partial int S\n");
+}
+
+template<>
+void G3<int, double>::f(int t, double s)
+ [[ pre: t > 2 ]]
+ [[ pre: s > 2 ]]
+{
+ printf ("G3 full int double\n");
+}
+
+struct C
+{
+ bool operator>(int rhs) { return false; }
+};
+
+// deletes contracts
+template<>
+void G3<int, C>::f(int t, C s);
+
+template<>
+void G3<int, C>::f(int t, C s)
+{
+ printf ("G3 full int C\n");
+};
+
+// specialized ctors
+template<typename T, typename S>
+struct G4
+{
+ G4(T t, S s)
+ [[ pre: t > 0 ]]
+ [[ pre: s > 0 ]]
+ [[ post: x > 0 ]]
+ {
+ printf ("G4 general T S\n");
+ return;
+ }
+ int x{-1};
+};
+
+template<typename S>
+struct G4<char, S>
+{
+ G4(char t, S s)
+ [[ pre: t > 'c' ]]
+ [[ pre: s > 3 ]]
+ [[ post: x2 > 3 ]]
+ {
+ printf ("G4 partial char S\n");
+ return;
+ }
+ int x2{-1};
+};
+
+template<>
+G4<double, double>::G4(double, double)
+{
+ printf ("G4 full double double\n");
+ return;
+}
+
+template<>
+G4<double, char>::G4(double a, char b)
+ [[ pre: a > 0 ]]
+ [[ pre: b > 'b' ]]
+ [[ post: x > 1 ]]
+{
+ printf ("G4 full double char\n");
+ return;
+}
+
+// crossover of template classes and template members ok
+template<typename T, typename S>
+struct G5
+{
+ template<typename P>
+ void f(T t, S s, P r)
+ [[ pre: t > 0 ]]
+ [[ pre: s > 0 ]]
+ [[ pre: r > 0 ]]
+ {
+ printf ("G5 gen T S, f gen R\n");
+ }
+};
+
+template<typename S>
+struct G5<char, S>
+{
+ template<typename R>
+ void f(char x, S y, R z)
+ [[ pre: x > 'z' ]]
+ [[ pre: y > 1 ]]
+ [[ pre: z > 1 ]]
+ {
+ printf ("G5 partial char S, f gen R\n");
+ }
+};
+
+template<>
+template<typename Q>
+void G5<double, double>::f(double a, double b, Q c)
+ [[ pre: a > 2 ]]
+ [[ pre: b > 2 ]]
+ [[ pre: c > 2 ]]
+{
+ printf ("G5 full double double, f gen R\n");
+}
+
+int main(int, char**)
+{
+ printf("%d\n", body<int>(-1));
+ printf("%d\n", body<double>(-1));
+ printf("%d\n", none<int>(-1));
+ printf("%d\n", none<double>(-1));
+ printf("%d\n", arg0(-1));
+ printf("%d\n", arg0(-1.0));
+ printf("%d\n", arg1(-3, -1));
+ printf("%d\n", arg1(-3, -1.0));
+ printf("%d\n", (int)ret<int>(-1));
+ printf("%d\n", (int)ret<double>(-1));
+ printf("%f\n", ret<double>(-1));
+
+ printf("%d\n", g1(-1));
+ printf("%d\n", g1(-1.0));
+
+ printf("%d\n", g2(-1));
+ printf("%d\n", g2(1.0));
+ printf("%d\n", g2('d'));
+
+ G3<double, double> g3_gen;
+ G3<int, int> g3_partial;
+ G3<int, double> g3_full;
+ g3_gen.f(-1.0, -1.0); // general
+ g3_partial.f(-2, -2); // partial spec
+ g3_full.f(-3, -3.0); // full spec
+
+ G3<char, char> g3_gen2;
+ G3<int, char> g3_partial2;
+ g3_gen2.f((char)-1, (char)-1);
+ g3_partial2.f(-1, (char)-1);
+
+ G3<int, C> g3_full2;
+ g3_full2.f(5, C{});
+ g3_full2.f(-5, C{});
+
+ G4 g4_gen{-1, -1};
+ G4 g4_full1{-1.0, -1.0};
+ G4 g4_full2{-1.0, (char)'b'};
+ G4 g4_partial{(char)'c', -5};
+
+ G5<int, int> g5_gen;
+ g5_gen.f(-1, -1, -2);
+ g5_gen.f(-1, -1, -2.0);
+
+ G5<char, int> g5_part;
+ g5_part.f('a', -1, -2);
+ g5_part.f('a', -1, -2.1);
+
+ G5<double, double> g5_full;
+ g5_full.f(-1.0, -1.0, -2);
+ g5_full.f(-1.0, -1.0, -2.1);
+ return 0;
+}
+
+
+// { dg-output "default std::handle_contract_violation called: .*.C 9 body<int> .*(\n|\r\n|\r)*" }
+// { dg-output "-2(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 17 body<double> .*(\n|\r\n|\r)*" }
+// { dg-output "-3(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 25 none<int> .*(\n|\r\n|\r)*" }
+// { dg-output "1(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 32 none<double> .*(\n|\r\n|\r)*" }
+// { dg-output "-101(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 39 arg0<int> .*(\n|\r\n|\r)*" }
+// { dg-output "-9(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 46 arg0<double> .*(\n|\r\n|\r)*" }
+// { dg-output "11(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 53 arg1<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 54 arg1<int> .*(\n|\r\n|\r)*" }
+// { dg-output "-3(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 61 arg1<double> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 62 arg1<double> .*(\n|\r\n|\r)*" }
+// { dg-output "14(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 69 ret<int> .*(\n|\r\n|\r)*" }
+// { dg-output "1(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 76 ret<double> .*(\n|\r\n|\r)*" }
+// { dg-output "3(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 76 ret<double> .*(\n|\r\n|\r)*" }
+// { dg-output "3.300000(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 83 g1<int> .*(\n|\r\n|\r)*" }
+// { dg-output "-1(\n|\r\n|\r)*" }
+// { dg-output "-1(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 97 g2<int> .*(\n|\r\n|\r)*" }
+// { dg-output "-1(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 107 g2<double> .*(\n|\r\n|\r)*" }
+// { dg-output "1(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 114 g2<char> .*(\n|\r\n|\r)*" }
+// { dg-output "100(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 124 G3<double, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 125 G3<double, .*(\n|\r\n|\r)*" }
+// { dg-output "G3 general T S(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 139 G3<int, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 140 G3<int, .*(\n|\r\n|\r)*" }
+// { dg-output "G3 partial int S(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 147 G3<int, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 148 G3<int, .*(\n|\r\n|\r)*" }
+// { dg-output "G3 full int double(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 124 G3<char, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 125 G3<char, .*(\n|\r\n|\r)*" }
+// { dg-output "G3 general T S(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 139 G3<int, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 140 G3<int, .*(\n|\r\n|\r)*" }
+// { dg-output "G3 partial int S(\n|\r\n|\r)*" }
+// { dg-output "G3 full int C(\n|\r\n|\r)*" }
+// { dg-output "G3 full int C(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 173 G4<int, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 174 G4<int, .*(\n|\r\n|\r)*" }
+// { dg-output "G4 general T S(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 175 G4<int, .*(\n|\r\n|\r)*" }
+// { dg-output "G4 full double double(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 206 G4<double, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 207 G4<double, .*(\n|\r\n|\r)*" }
+// { dg-output "G4 full double char(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 208 G4<double, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 187 G4<char, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 188 G4<char, .*(\n|\r\n|\r)*" }
+// { dg-output "G4 partial char S(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 189 G4<char, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 220 G5<int, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 221 G5<int, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 222 G5<int, .*(\n|\r\n|\r)*" }
+// { dg-output "G5 gen T S, f gen R(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 220 G5<int, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 221 G5<int, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 222 G5<int, .*(\n|\r\n|\r)*" }
+// { dg-output "G5 gen T S, f gen R(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 233 G5<char, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 234 G5<char, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 235 G5<char, .*(\n|\r\n|\r)*" }
+// { dg-output "G5 partial char S, f gen R(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 233 G5<char, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 234 G5<char, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 235 G5<char, .*(\n|\r\n|\r)*" }
+// { dg-output "G5 partial char S, f gen R(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 244 G5<double, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 245 G5<double, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 246 G5<double, .*(\n|\r\n|\r)*" }
+// { dg-output "G5 full double double, f gen R(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 244 G5<double, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 245 G5<double, .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 246 G5<double, .*(\n|\r\n|\r)*" }
+// { dg-output "G5 full double double, f gen R(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec3.C b/gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec3.C
new file mode 100644
index 0000000..4472589
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-tmpl-spec3.C
@@ -0,0 +1,45 @@
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+#include <cstdio>
+
+template<typename T, typename S>
+struct G5
+{
+ template<typename R>
+ void f(T t, S s, R r)
+ [[ pre: t > 0 ]] [[ pre: s > 0 ]] [[ pre: r > 0 ]]
+ {
+ printf ("G5 gen T S, f gen R\n");
+ }
+};
+
+// specializations can remove contracts
+template<>
+template<typename R>
+void G5<double, double>::f(double a, double b, R c)
+{
+ printf ("G5 full double double, f gen R\n");
+}
+
+int main(int, char**) {
+ G5<double, double> g5_full;
+ g5_full.f(-1.0, -1.0, -2);
+ g5_full.f(-1.0, -1.0, -2.1);
+
+ G5<int, double> g5_gen;
+ g5_gen.f(-1, -1.0, -2);
+ g5_gen.f(-1, -1.0, -2.1);
+ return 0;
+}
+
+// { dg-output "G5 full double double, f gen R(\n|\r\n|\r)*" }
+// { dg-output "G5 full double double, f gen R(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 10 G5<int, .* t > 0 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 10 G5<int, .* s > 0 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 10 G5<int, .* r > 0 .*(\n|\r\n|\r)*" }
+// { dg-output "G5 gen T S, f gen R(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 10 G5<int, .* t > 0 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 10 G5<int, .* s > 0 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 10 G5<int, .* r > 0 .*(\n|\r\n|\r)*" }
+// { dg-output "G5 gen T S, f gen R(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts1.C b/gcc/testsuite/g++.dg/contracts/contracts1.C
new file mode 100644
index 0000000..6655e01
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts1.C
@@ -0,0 +1,49 @@
+// generic assert contract parsing checks
+// check omitted, 'default', 'audit', and 'axiom' contract levels parse
+// check that all concrete semantics parse
+// check omitted, '%default' contract roles parse
+// ensure that an invalid contract level 'invalid' errors
+// ensure that a predicate referencing an undefined variable errors
+// ensure that a missing colon after contract level errors
+// ensure that an invalid contract role 'invalid' errors
+// ensure that a missing colon after contract role errors
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+static_assert (__cpp_contracts >= 201906);
+static_assert (__cpp_contracts_literal_semantics >= 201906);
+static_assert (__cpp_contracts_roles >= 201906);
+
+int main()
+{
+ int x;
+
+ [[assert: x >= 0]];
+ [[assert default: x < 0]];
+ [[assert audit: x == 0]];
+ [[assert axiom: x == 1]];
+
+ [[assert: x > 0 ? true : false]];
+ [[assert: x < 0 ? true : false]];
+
+ [[assert: x = 0]]; // { dg-error "expected .]. before .=. token" }
+
+ [[assert ignore: x >= 0]];
+ [[assert assume: x >= 0]];
+ [[assert check_never_continue: x >= 0]];
+ [[assert check_maybe_continue: x >= 0]];
+
+ [[assert %default: x >= 0]];
+ [[assert default %default: x < 0]];
+ [[assert audit %default: x == 0]];
+ [[assert axiom %default: x == 1]];
+
+ [[assert check_always_continue: x >= 0]]; // { dg-error "expected contract level" }
+ [[assert invalid: x == 0]]; // { dg-error "expected contract level" }
+ [[assert: y == 0]]; // { dg-error ".y. was not declared in this scope" }
+ [[assert default x == 0]]; // { dg-error "expected .:. before .x." }
+ [[assert %default x >= 0]]; // { dg-error "expected .:. before .x." }
+
+ [[assert %invalid: x >= 0]]; // TODO: optional warning?
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts10.C b/gcc/testsuite/g++.dg/contracts/contracts10.C
new file mode 100644
index 0000000..ce0723c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts10.C
@@ -0,0 +1,73 @@
+// general checks to ensure that contract violations are generated during
+// runtime when appropriate
+// each check also validates the expected file name, line number, function,
+// predicate, and contract level are included in the violation_info object
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-build-level=audit -fcontract-continuation-mode=on" }
+
+namespace tns
+{
+ int fun()
+ {
+ int x = 1;
+ [[ assert: x < 0 ]];
+ return 0;
+ }
+ int fun2();
+
+ struct TestType
+ {
+ static int fun();
+ static int fun2()
+ {
+ int x = 1;
+ [[ assert: x < 0 ]];
+ return 0;
+ }
+ };
+}
+
+int tns::fun2()
+{
+ int x = 1;
+ [[ assert: x < 0 ]];
+ return 0;
+}
+
+int tns::TestType::fun()
+{
+ int x = 1;
+ [[ assert: x < 0 ]];
+ return 0;
+}
+
+int main()
+{
+ int x = 100;
+ [[assert: x < 0]];
+ [[assert default: x < 1]];
+ [[assert audit: x < 2]];
+// contract_violation.line_number() may eventually come from
+// std::source_location which *is* affected by the #line macro; our current
+// implementation conforms to this so we've included it as a check
+#line 100
+ [[assert: x < 3]];
+ [[assert axiom: x < 4]];
+
+ tns::fun();
+ tns::fun2();
+
+ tns::TestType::fun();
+ tns::TestType::fun2();
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 47 main .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 48 main .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 49 main .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 100 main .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 13 tns::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 33 tns::fun2 .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 40 tns::TestType::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 24 tns::TestType::fun2 .*(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts11.C b/gcc/testsuite/g++.dg/contracts/contracts11.C
new file mode 100644
index 0000000..b41bc53
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts11.C
@@ -0,0 +1,103 @@
+// ensure that assert contract predicates that are not convertible to bool
+// generate an error
+// ensure the same for instatiated template functions
+// ensure the same for non-instatiated template functions when the predicate
+// is not dependent on the template parameters
+// ensure template parameter dependent, potentially non-boolean, contract
+// predicates do not generate an error if never instatiated
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+void fun()
+{
+ return;
+}
+
+template<typename T>
+void fun2(T a)
+{
+ [[assert: fun()]]; // { dg-error "could not convert|in argument" }
+}
+
+template<typename T>
+void fun3(T a)
+{
+ [[assert: fun()]]; // { dg-error "could not convert|in argument" }
+}
+
+template<typename T>
+void fun4(T a)
+{
+ [[assert: a.fun()]];
+}
+
+struct test
+{
+ void fun() { }
+ void fun2() { }
+};
+
+template<typename T>
+void fun5(T a)
+{
+ [[assert: a.fun2()]]; // { dg-error "could not convert" }
+}
+
+struct VoidFun
+{
+ void fun() { }
+};
+struct BoolFun
+{
+ bool fun() { return true; }
+};
+
+template<typename T>
+void fun6(T a)
+{
+ [[ assert: a.fun() ]]; // { dg-error "could not convert" }
+}
+
+template void fun6(VoidFun);
+
+template<typename T>
+void fun7(T a)
+{
+ [[ assert: a.fun() ]];
+}
+
+template void fun7(BoolFun);
+
+struct ImplicitBool
+{
+ operator bool() { return true; }
+};
+struct ExplicitBool
+{
+ explicit operator bool() { return true; }
+};
+
+template<typename T>
+void fun8(T a)
+{
+ [[ assert: T() ]];
+}
+
+template void fun8(ImplicitBool);
+template void fun8(ExplicitBool);
+
+void fun9()
+{
+ [[ assert: ImplicitBool() ]];
+ [[ assert: ExplicitBool() ]];
+}
+
+int main()
+{
+ [[assert: fun()]]; // { dg-error "could not convert" }
+ fun2(1);
+
+ test t;
+ fun5(t);
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts12.C b/gcc/testsuite/g++.dg/contracts/contracts12.C
new file mode 100644
index 0000000..f888d51
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts12.C
@@ -0,0 +1,15 @@
+// ensure that constants for contract levels are inserted into the binary when
+// used and omitted when the runtime check is not generated
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts -fcontract-build-level=default" }
+// { dg-final { scan-assembler-not "audit" } }
+// { dg-final { scan-assembler "default" } }
+
+int main()
+{
+ int x = 1;
+ [[assert: x < 0]];
+ [[assert default: x < 0]];
+ [[assert audit: x < 0]];
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts13.C b/gcc/testsuite/g++.dg/contracts/contracts13.C
new file mode 100644
index 0000000..14ba0e9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts13.C
@@ -0,0 +1,51 @@
+// ensure that passing asserts do not affect constexpr functions
+// ensure that failing asserts generate an error in a constexpr function
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+constexpr int wfun(int a) {
+ [[assert: a > 0]];
+ return a;
+}
+
+constexpr int ffun(int a) {
+ [[assert: a > 0]];
+ return a;
+}
+
+template<typename T>
+constexpr int tfun(T a) {
+ [[assert: a > 0]];
+ return a;
+}
+
+template<typename T>
+constexpr int wtfun(T a) {
+ [[assert: a > 0]];
+ return a;
+}
+
+template<typename T>
+constexpr int ftfun(T a) {
+ [[assert: a > 0]];
+ return a;
+}
+
+constexpr int explicitfn(int a) {
+ [[assert ignore: a > 0]];
+ [[assert check_never_continue: a > 0]];
+ return a;
+}
+
+int main(int, char **) {
+ constexpr int a = wfun(10);
+ constexpr int b = ffun(-10); // { dg-message "in .constexpr. expansion" }
+ // { dg-error "contract predicate" "" { target *-*-* } 12 }
+ constexpr int c = wtfun(10);
+ constexpr int d = ftfun(-10); // { dg-message "in .constexpr. expansion" }
+ // { dg-error "contract predicate" "" { target *-*-* } 30 }
+ constexpr int e = explicitfn(-10); // { dg-message "in .constexpr. expansion" }
+ // { dg-error "contract predicate" "" { target *-*-* } 36 }
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts14.C b/gcc/testsuite/g++.dg/contracts/contracts14.C
new file mode 100644
index 0000000..55208db
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts14.C
@@ -0,0 +1,58 @@
+// ensure that exceptions thrown inside a custom contract violation handler
+// are catchable up the call stack
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+#include <iostream>
+#include <experimental/contract>
+
+void handle_contract_violation(const std::experimental::contract_violation &violation) {
+ std::cerr << "custom std::handle_contract_violation called:"
+ << " " << violation.line_number()
+ << " " << violation.file_name()
+ << std::endl;
+ throw -(int)violation.line_number();
+}
+
+int fun() {
+ int x = 0;
+ [[ assert: x < 0 ]];
+ return 0;
+}
+
+int fun3() {
+ fun();
+ return 2;
+}
+
+int main(int, char**) {
+ try {
+ int x = 0;
+ [[ assert: x < 0 ]];
+ } catch(int &ex) {
+ std::cerr << "synth caught direct: " << ex << std::endl;
+ }
+
+ try {
+ fun();
+ } catch(int &ex) {
+ std::cerr << "synth caught indirect: " << ex << std::endl;
+ }
+
+ try {
+ fun3();
+ } catch(int &ex) {
+ std::cerr << "synth caught double indirect: " << ex << std::endl;
+ }
+
+ std::cerr << "end main" << std::endl;
+ return 0;
+}
+
+// { dg-output "custom std::handle_contract_violation called: 30 .*/contracts14.C(\n|\r\n|\r)*" }
+// { dg-output "synth caught direct: -30(\n|\r\n|\r)*" }
+// { dg-output "custom std::handle_contract_violation called: 18 .*/contracts14.C(\n|\r\n|\r)*" }
+// { dg-output "synth caught indirect: -18(\n|\r\n|\r)*" }
+// { dg-output "custom std::handle_contract_violation called: 18 .*/contracts14.C(\n|\r\n|\r)*" }
+// { dg-output "synth caught double indirect: -18(\n|\r\n|\r)*" }
+// { dg-output "end main" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts15.C b/gcc/testsuite/g++.dg/contracts/contracts15.C
new file mode 100644
index 0000000..d822f83
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts15.C
@@ -0,0 +1,56 @@
+// ensure that exceptions thrown inside a custom contract violation handler
+// are not catchable up the call stack when failing in a noexcept function
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+#include <iostream>
+#include <experimental/contract>
+
+void handle_contract_violation(const std::experimental::contract_violation &violation) {
+ std::cerr << "custom std::handle_contract_violation called:"
+ << " " << violation.line_number()
+ << " " << violation.file_name()
+ << std::endl;
+ throw -(int)violation.line_number();
+}
+
+int fun() noexcept {
+ int x = 0;
+ [[ assert: x < 0 ]];
+ return 0;
+}
+
+int fun3() {
+ fun();
+ return 2;
+}
+
+int main(int, char**) {
+ try {
+ int x = 0;
+ [[ assert: x < 0 ]];
+ } catch(int &ex) {
+ std::cerr << "synth caught direct: " << ex << std::endl;
+ }
+
+ try {
+ fun();
+ } catch(int &ex) {
+ std::cerr << "synth caught indirect: " << ex << std::endl;
+ }
+
+ try {
+ fun3();
+ } catch(int &ex) {
+ std::cerr << "synth caught double indirect: " << ex << std::endl;
+ }
+
+ std::cerr << "end main" << std::endl;
+ return 0;
+}
+
+// { dg-output "custom std::handle_contract_violation called: 30 .*/contracts15.C(\n|\r\n|\r)*" }
+// { dg-output "synth caught direct: -30(\n|\r\n|\r)*" }
+// { dg-output "custom std::handle_contract_violation called: 18 .*/contracts15.C(\n|\r\n|\r)*" }
+// { dg-output "terminate called after throwing an instance of .int.(\n|\r\n|\r)*" }
+// { dg-shouldfail "throwing in noexcept" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts16.C b/gcc/testsuite/g++.dg/contracts/contracts16.C
new file mode 100644
index 0000000..1c70545
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts16.C
@@ -0,0 +1,34 @@
+// ensure that exceptions thrown inside a custom contract violation handler
+// are not catchable up the call stack even when continue mode is off
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts" }
+#include <iostream>
+#include <experimental/contract>
+
+void handle_contract_violation(const std::experimental::contract_violation &violation) {
+ std::cerr << "custom std::handle_contract_violation called:"
+ << " " << violation.line_number()
+ << " " << violation.file_name()
+ << std::endl;
+ throw -(int)violation.line_number();
+}
+
+int fun() {
+ int x = 0;
+ [[ assert: x < 0 ]];
+ return 0;
+}
+
+int main(int, char**) {
+ try {
+ fun();
+ } catch(int &ex) {
+ std::cerr << "synth caught indirect: " << ex << std::endl;
+ }
+
+ return 0;
+}
+
+// { dg-output "custom std::handle_contract_violation called: 18 .*/contracts16.C(\n|\r\n|\r)*" }
+// { dg-output "synth caught indirect: -18(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts17.C b/gcc/testsuite/g++.dg/contracts/contracts17.C
new file mode 100644
index 0000000..d165bb0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts17.C
@@ -0,0 +1,35 @@
+// ensure that exceptions thrown inside a custom contract violation handler
+// are not catchable up the call stack when continue mode is off and the
+// assert fails in a noexcept function
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts" }
+#include <iostream>
+#include <experimental/contract>
+
+void handle_contract_violation(const std::experimental::contract_violation &violation) {
+ std::cerr << "custom std::handle_contract_violation called:"
+ << " " << violation.line_number()
+ << " " << violation.file_name()
+ << std::endl;
+ throw -violation.line_number();
+}
+
+int fun() noexcept {
+ int x = 0;
+ [[ assert: x < 0 ]];
+ return 0;
+}
+
+int main(int, char**) {
+ try {
+ fun();
+ } catch(int &ex) {
+ std::cerr << "synth caught indirect: " << ex << std::endl;
+ }
+
+ return 0;
+}
+
+// { dg-output "custom std::handle_contract_violation called: 19 .*/contracts17.C(\n|\r\n|\r)*" }
+// { dg-shouldfail "throwing in noexcept" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts18.C b/gcc/testsuite/g++.dg/contracts/contracts18.C
new file mode 100644
index 0000000..e8163ba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts18.C
@@ -0,0 +1,15 @@
+// check that a valid program using assertions compiles and runs
+// ensure an axiom with a failing predicate doesn't prevent a successful run
+// (axiom level contracts are never checked at runtime)
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-role=custom:never,ignore,ignore" }
+
+int main()
+{
+ int x = 1;
+ [[assert axiom: x < 0]];
+ [[assert %custom: x > 0]];
+ [[assert audit %custom: x < 0]];
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts19.C b/gcc/testsuite/g++.dg/contracts/contracts19.C
new file mode 100644
index 0000000..4a8b43a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts19.C
@@ -0,0 +1,19 @@
+// check that a valid program using assertions compiles and runs
+// ensure an axiom with a failing predicate doesn't prevent a successful run
+// (axiom level contracts are never checked at runtime)
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-role=custom:maybe,maybe,ignore" }
+
+int main()
+{
+ int x = 10;
+ [[assert axiom: x < 0]];
+ [[assert %custom: x < 0]];
+ [[assert audit %custom: x < 1]];
+ [[assert axiom %custom: x < 1]];
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 11 main .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 12 main .*(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts2.C b/gcc/testsuite/g++.dg/contracts/contracts2.C
new file mode 100644
index 0000000..9535e07
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts2.C
@@ -0,0 +1,13 @@
+// check that a valid program using assertions compiles and runs
+// ensure an axiom with a failing predicate doesn't prevent a successful run
+// (axiom level contracts are never checked at runtime)
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts" }
+
+int main()
+{
+ int x = 1;
+ [[assert axiom: x < 0]];
+ [[assert default: x > 0]];
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts20.C b/gcc/testsuite/g++.dg/contracts/contracts20.C
new file mode 100644
index 0000000..adce5d7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts20.C
@@ -0,0 +1,11 @@
+// test that contract attributes cause errors pre-c++2a
+// { dg-do compile { target c++17_only } }
+
+int fun(int a)
+ [[ pre: a > 0 ]] // { dg-error "contracts are only available with .-fcontracts." }
+ [[ post r: r < 0 ]] // { dg-error "contracts are only available with .-fcontracts." }
+{
+ [[ assert: a != 0 ]]; // { dg-error "contracts are only available with .-fcontracts." }
+ return -a;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts22.C b/gcc/testsuite/g++.dg/contracts/contracts22.C
new file mode 100644
index 0000000..91e32b9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts22.C
@@ -0,0 +1,32 @@
+// ensure a default level assert with a failing predicate does not generate an
+// error during runtime when the contracts mode is off
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-mode=off" }
+// { dg-output "returning from main" }
+#include <cstdio>
+
+int constexpr f()
+{
+ constexpr int x = 1;
+ [[assert default: x < 0]];
+ return x;
+}
+
+template<typename T> int k()
+{
+ int x = 1;
+ [[assert default: x < 0]];
+ return x;
+}
+
+
+int main()
+{
+ int x = 1;
+ [[assert default: x < 0]];
+ constexpr int x2 = f();
+ int x3 = k<int>();
+
+ printf ("returning from main\n");
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts24.C b/gcc/testsuite/g++.dg/contracts/contracts24.C
new file mode 100644
index 0000000..70a54f9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts24.C
@@ -0,0 +1,15 @@
+// check that a valid program using assertions compiles and runs
+// ensure an axiom with a failing predicate doesn't prevent a successful run
+// (axiom level contracts are never checked at runtime)
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-semantic=default:never -fcontract-semantic=audit:ignore -fcontract-semantic=axiom:ignore" }
+
+int main()
+{
+ int x = 1;
+ [[assert axiom: x < 0]];
+ [[assert: x > 0]];
+ [[assert audit: x < 0]];
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts25.C b/gcc/testsuite/g++.dg/contracts/contracts25.C
new file mode 100644
index 0000000..0121780
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts25.C
@@ -0,0 +1,57 @@
+// ensure that passing asserts do not affect constexpr functions
+// ensure that failing asserts generate an error at runtime in constexpr funcs
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+
+constexpr int wfun(int a) {
+ [[assert: a > 0]];
+ return a;
+}
+
+constexpr int ffun(int a) {
+ [[assert: a > 0]];
+ return a;
+}
+
+template<typename T>
+constexpr int tfun(T a) {
+ [[assert: a > 0]];
+ return a;
+}
+
+template<typename T>
+constexpr int wtfun(T a) {
+ [[assert: a > 0]];
+ return a;
+}
+
+template<typename T>
+constexpr int ftfun(T a) {
+ [[assert: a > 0]];
+ return a;
+}
+
+constexpr int explicitfn(int a) {
+ [[assert ignore: a > 0]];
+ [[assert check_maybe_continue: a > 0]];
+ return a;
+}
+
+int main(int, char **) {
+ int a = wfun(10);
+ int b = ffun(-10);
+ int c = wtfun(10);
+ int d = ftfun(-10);
+
+ int e = explicitfn(-10);
+
+ int z = ftfun(-10.0);
+
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 12 ffun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 30 ftfun<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 36 explicitfn .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 30 ftfun<double> .*(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts3.C b/gcc/testsuite/g++.dg/contracts/contracts3.C
new file mode 100644
index 0000000..ecb9fdb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts3.C
@@ -0,0 +1,13 @@
+// ensure a default level assert with a failing predicate generates an error
+// during runtime when the contract build level is default
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts" }
+// { dg-shouldfail "assert violation" }
+// { dg-output "default std::handle_contract_violation called" }
+
+int main()
+{
+ int x = 1;
+ [[assert default: x < 0]];
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts35.C b/gcc/testsuite/g++.dg/contracts/contracts35.C
new file mode 100644
index 0000000..ddd8002
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts35.C
@@ -0,0 +1,47 @@
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+#include <cstdio>
+
+struct S
+{
+ template<typename T>
+ S(T a) [[ pre: a > 0 ]] [[ pre: a > 10 ]];
+};
+
+template<typename T>
+S::S(T a)
+{
+ printf ("S::S(T): %d\n", (int)a);
+}
+
+struct S1
+{
+ template<typename T>
+ S1(T a) [[ pre: a > 0 ]] [[ pre: a > 10 ]]
+ {
+ printf ("S1::S1(T): %d\n", (int)a);
+ }
+};
+
+int main(int, char **) {
+ S s{-1};
+ S s2{-2.5};
+
+ S1 s1_1{-3};
+ S1 s1_2{-4.5};
+ return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 8 S::S<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 8 S::S<int> .*(\n|\r\n|\r)*" }
+// { dg-output "S::S.T.: -1(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 8 S::S<double> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 8 S::S<double> .*(\n|\r\n|\r)*" }
+// { dg-output "S::S.T.: -2(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 20 S1::S1<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 20 S1::S1<int> .*(\n|\r\n|\r)*" }
+// { dg-output "S1::S1.T.: -3(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 20 S1::S1<double> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 20 S1::S1<double> .*(\n|\r\n|\r)*" }
+// { dg-output "S1::S1.T.: -4(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/contracts/contracts4.C b/gcc/testsuite/g++.dg/contracts/contracts4.C
new file mode 100644
index 0000000..a43fb9f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts4.C
@@ -0,0 +1,11 @@
+// ensure an audit level assert with a failing predicate does not generate an
+// error during runtime when the contract build level is default
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts" }
+
+int main()
+{
+ int x = 1;
+ [[assert audit: x < 0]];
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts5.C b/gcc/testsuite/g++.dg/contracts/contracts5.C
new file mode 100644
index 0000000..0fa0ec8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts5.C
@@ -0,0 +1,13 @@
+// ensure an audit level assert with a failing predicate generates an error
+// during runtime when the contract build level is audit
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-build-level=audit" }
+// { dg-shouldfail "assert violation" }
+// { dg-output "default std::handle_contract_violation called" }
+
+int main()
+{
+ int x = 1;
+ [[assert audit: x < 0]];
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts6.C b/gcc/testsuite/g++.dg/contracts/contracts6.C
new file mode 100644
index 0000000..59c010e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts6.C
@@ -0,0 +1,11 @@
+// ensure a default level assert with a failing predicate does not generate an
+// error during runtime when the contract build level is off
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-build-level=off" }
+
+int main()
+{
+ int x = 1;
+ [[assert default: x < 0]];
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts7.C b/gcc/testsuite/g++.dg/contracts/contracts7.C
new file mode 100644
index 0000000..eaad8f0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts7.C
@@ -0,0 +1,14 @@
+// ensure a default level assert with a failing predicate does generates an
+// error during runtime but lets the program continue and complete
+// successfully when the contract build level is default but continuation on
+// contract failure is switched on
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+// { dg-output "default std::handle_contract_violation called" }
+
+int main()
+{
+ int x = 1;
+ [[assert default: x < 0]];
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts8.C b/gcc/testsuite/g++.dg/contracts/contracts8.C
new file mode 100644
index 0000000..9c8a6b5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts8.C
@@ -0,0 +1,43 @@
+// generic assert contract parsing checks
+// ensure that existing generalized attribute parsing is not intefered with
+// ensure that an assert contract cannot chain into an empty attribute list
+// ensure that an attribute list cannot chain into an assert contract
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts" }
+
+constexpr bool fun(int x) {
+ return x < 0;
+}
+
+namespace tns {
+ constexpr bool f(int x) {
+ return x < 0;
+ }
+}
+
+bool assert(int x) {
+ return x < 0;
+}
+
+int main()
+{
+ constexpr int x = 1;
+ [[fun(x)]]; // { dg-warning "attributes at the beginning of statement are ignored" }
+ [[fun(x), assert(x)]]; // { dg-warning "attributes at the beginning of statement are ignored" }
+
+ [[assert default: fun(x), ]]; // { dg-error "expected ']'" }
+ [[assert default: fun(x) ]];
+
+ [[fun(x), assert default: fun(x)]]; // { dg-error "expected .]. before .default." }
+ // { dg-warning "attributes at the beginning of statement are ignored" "" { target *-*-* } .-1 }
+ [[fun(x), assert: fun(x)]]; // { dg-error "expected .]. before .:. token" }
+ // { dg-warning "attributes at the beginning of statement are ignored" "" { target *-*-* } .-1 }
+ [[fun(x), assert fun(x)]]; // { dg-error "expected .]. before .fun." }
+ // { dg-warning "attributes at the beginning of statement are ignored" "" { target *-*-* } .-1 }
+ [[ using tns: f(x) ]]; // { dg-warning "attributes at the beginning of statement are ignored" }
+ [[ using tns: f(x), assert default: fun(x) ]]; // { dg-error "expected .]. before .default." }
+ // { dg-warning "attributes at the beginning of statement are ignored" "" { target *-*-* } .-1 }
+ [[ using tns: f(x), , default: fun(x) ]]; // { dg-error "expected .]. before .:." }
+ // { dg-warning "attributes at the beginning of statement are ignored" "" { target *-*-* } .-1 }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/contracts/contracts9.C b/gcc/testsuite/g++.dg/contracts/contracts9.C
new file mode 100644
index 0000000..f566628
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts9.C
@@ -0,0 +1,45 @@
+// ensure that dependent and non-dependent asserts inside templated
+// functions parse without error whether the function is instatiated or not
+// ensure that assert contract checks are generated inside called templates
+// ensure that template functions can be used as assert predicates
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fcontract-continuation-mode=on" }
+
+template<typename T>
+int fun1(int a, T b)
+{
+ [[ assert: a > 0 ]];
+ [[ assert: (long long)b > 0 ]];
+ return a > 0;
+}
+
+template<typename T>
+struct test
+{
+ static int fun(int a, T b) {
+ [[ assert: a > 0 ]];
+ [[ assert: b > 0 ]];
+ return a > 0;
+ }
+};
+
+int main()
+{
+ fun1(1, -1);
+ fun1(-1, 1.0);
+ fun1(-1, "test");
+
+ [[ assert: fun1(-1, -5) ]];
+ [[ assert: test<int>::fun(10, -6) ]];
+ [[ assert: test<double>::fun(10.0, -7) ]];
+ // return 0;
+}
+
+// { dg-output "default std::handle_contract_violation called: .*.C 12 fun1<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 11 fun1<double> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 11 fun1<const char.> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 11 fun1<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 12 fun1<int> .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 32 main .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 21 test<int>::fun .*(\n|\r\n|\r)*" }
+// { dg-output "default std::handle_contract_violation called: .*.C 21 test<double>::fun .*(\n|\r\n|\r)*" }
diff --git a/gcc/testsuite/g++.dg/contracts/except_preload_handler/Makefile b/gcc/testsuite/g++.dg/contracts/except_preload_handler/Makefile
new file mode 100644
index 0000000..8fcc5b2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/except_preload_handler/Makefile
@@ -0,0 +1,13 @@
+CXXFLAGS=--std=c++17 -fcontract-continuation-mode=on
+
+default: assert_fail libhandle_contract_violation.so
+
+run: default
+ LD_PRELOAD=./libhandle_contract_violation.so ./assert_fail
+
+./libhandle_contract_violation.so: ./handle_contract_violation.cpp
+ ${CXX} ${CXXFLAGS} -shared -fPIC -o $@ $<
+
+clean:
+ rm -fr ./*.o ./libhandle_contract_violation.so ./assert_fail
+
diff --git a/gcc/testsuite/g++.dg/contracts/except_preload_handler/README b/gcc/testsuite/g++.dg/contracts/except_preload_handler/README
new file mode 100644
index 0000000..cbfe48b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/except_preload_handler/README
@@ -0,0 +1,13 @@
+build and install gcc to $prefix, then run:
+LD_LIBRARY_PATH=$prefix/lib64 CXX=$prefix/bin/g++ make run
+
+this test has a custom handle_contract_violation that throws an exception
+this test is built with -fcontract-continuation-mode=on
+
+since 1) our fun() is not marked noexcept and 2) the continue mode is set to
+on, we expect the exception thrown within the contract violation handler to
+propagate back up into the catch block located in main()
+
+expected output therefore ends in:
+ synth caught indirect: -1
+
diff --git a/gcc/testsuite/g++.dg/contracts/except_preload_handler/assert_fail.cpp b/gcc/testsuite/g++.dg/contracts/except_preload_handler/assert_fail.cpp
new file mode 100644
index 0000000..3dda7ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/except_preload_handler/assert_fail.cpp
@@ -0,0 +1,20 @@
+#include <iostream>
+#include <contract>
+
+int fun() {
+ int x = 0;
+ [[ assert: x < 0 ]];
+
+ return 0;
+}
+
+int main(int argc, char**) {
+ try {
+ fun();
+ } catch(int &ex) {
+ std::cerr << "synth caught indirect: " << ex << std::endl;
+ }
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/except_preload_handler/handle_contract_violation.cpp b/gcc/testsuite/g++.dg/contracts/except_preload_handler/handle_contract_violation.cpp
new file mode 100644
index 0000000..ec051b3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/except_preload_handler/handle_contract_violation.cpp
@@ -0,0 +1,14 @@
+#include <iostream>
+#include <contract>
+
+void handle_contract_violation(const std::contract_violation &violation) {
+ std::cerr << "custom handle_contract_violation: " << std::endl
+ << " line_number: " << violation.line_number() << std::endl
+ << " file_name: " << violation.file_name() << std::endl
+ << " function_name: " << violation.function_name() << std::endl
+ << " comment: " << violation.comment() << std::endl
+ << " assertion_level: " << violation.assertion_level() << std::endl
+ << std::endl;
+ throw -1;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/Makefile b/gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/Makefile
new file mode 100644
index 0000000..8fcc5b2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/Makefile
@@ -0,0 +1,13 @@
+CXXFLAGS=--std=c++17 -fcontract-continuation-mode=on
+
+default: assert_fail libhandle_contract_violation.so
+
+run: default
+ LD_PRELOAD=./libhandle_contract_violation.so ./assert_fail
+
+./libhandle_contract_violation.so: ./handle_contract_violation.cpp
+ ${CXX} ${CXXFLAGS} -shared -fPIC -o $@ $<
+
+clean:
+ rm -fr ./*.o ./libhandle_contract_violation.so ./assert_fail
+
diff --git a/gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/README b/gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/README
new file mode 100644
index 0000000..aa7c6dd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/README
@@ -0,0 +1,15 @@
+build and install gcc to $prefix, then run:
+LD_LIBRARY_PATH=$prefix/lib64 CXX=$prefix/bin/g++ make run
+
+this test has a custom handle_contract_violation that throws an exception
+this test is built with -fcontract-continuation-mode=on
+
+since 1) our fun() *IS* marked noexcept even though 2) the continue mode is
+set to on, we expect the exception thrown within the contract violation
+handler to quashed and have std::terminate run.
+
+expected output therefore ends in:
+ terminate called after throwing an instance of 'int'
+
+despite there being a catch(int &) handler in main
+
diff --git a/gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/assert_fail.cpp b/gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/assert_fail.cpp
new file mode 100644
index 0000000..8ae98fb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/assert_fail.cpp
@@ -0,0 +1,20 @@
+#include <iostream>
+#include <contract>
+
+int fun() noexcept {
+ int x = 0;
+ [[ assert: x < 0 ]];
+
+ return 0;
+}
+
+int main(int argc, char**) {
+ try {
+ fun();
+ } catch(int &ex) {
+ std::cerr << "synth caught indirect: " << ex << std::endl;
+ }
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/handle_contract_violation.cpp b/gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/handle_contract_violation.cpp
new file mode 100644
index 0000000..ec051b3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/noexcept_preload_handler/handle_contract_violation.cpp
@@ -0,0 +1,14 @@
+#include <iostream>
+#include <contract>
+
+void handle_contract_violation(const std::contract_violation &violation) {
+ std::cerr << "custom handle_contract_violation: " << std::endl
+ << " line_number: " << violation.line_number() << std::endl
+ << " file_name: " << violation.file_name() << std::endl
+ << " function_name: " << violation.function_name() << std::endl
+ << " comment: " << violation.comment() << std::endl
+ << " assertion_level: " << violation.assertion_level() << std::endl
+ << std::endl;
+ throw -1;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/preload_handler/Makefile b/gcc/testsuite/g++.dg/contracts/preload_handler/Makefile
new file mode 100644
index 0000000..6ff083f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/preload_handler/Makefile
@@ -0,0 +1,13 @@
+CXXFLAGS=--std=c++17
+
+default: assert_fail libhandle_contract_violation.so
+
+run: default
+ LD_PRELOAD=./libhandle_contract_violation.so ./assert_fail
+
+./libhandle_contract_violation.so: ./handle_contract_violation.cpp
+ ${CXX} ${CXXFLAGS} -shared -fPIC -o $@ $<
+
+clean:
+ rm -fr ./libhandle_contract_violation.so ./assert_fail
+
diff --git a/gcc/testsuite/g++.dg/contracts/preload_handler/README b/gcc/testsuite/g++.dg/contracts/preload_handler/README
new file mode 100644
index 0000000..cc913fe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/preload_handler/README
@@ -0,0 +1,2 @@
+build and install gcc to $prefix, then run:
+LD_LIBRARY_PATH=$prefix/lib64 CXX=$prefix/bin/g++ make run
diff --git a/gcc/testsuite/g++.dg/contracts/preload_handler/assert_fail.cpp b/gcc/testsuite/g++.dg/contracts/preload_handler/assert_fail.cpp
new file mode 100644
index 0000000..0f807db
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/preload_handler/assert_fail.cpp
@@ -0,0 +1,7 @@
+int main(int, char**) {
+ int x = 0;
+ [[ assert: x < 0 ]];
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/preload_handler/handle_contract_violation.cpp b/gcc/testsuite/g++.dg/contracts/preload_handler/handle_contract_violation.cpp
new file mode 100644
index 0000000..6029875
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/preload_handler/handle_contract_violation.cpp
@@ -0,0 +1,15 @@
+#include <iostream>
+#include <contract>
+
+void handle_contract_violation(const std::contract_violation &violation) {
+ std::cerr << "custom handle_contract_violation: " << std::endl
+ << " line_number: " << violation.line_number() << std::endl
+ << " file_name: " << violation.file_name() << std::endl
+ << " function_name: " << violation.function_name() << std::endl
+ << " comment: " << violation.comment() << std::endl
+ << " assertion_level: " << violation.assertion_level() << std::endl
+ << " assertion_role: " << violation.assertion_role() << std::endl
+ << " continuation_mode: " << (int)violation.continuation_mode() << std::endl
+ << std::endl;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/Makefile b/gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/Makefile
new file mode 100644
index 0000000..c826328
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/Makefile
@@ -0,0 +1,23 @@
+CXXFLAGS=--std=c++17 -fcontract-continuation-mode=on
+LDFLAGS=-ldl
+
+default: assert_fail libhandle_contract_violation.so libnocontinue.so
+
+run: default
+ ./assert_fail
+
+runno: default
+ LD_PRELOAD="./libnocontinue.so ./libhandle_contract_violation.so" ./assert_fail
+
+runnostd: default
+ LD_PRELOAD=./libnocontinue.so ./assert_fail
+
+./libhandle_contract_violation.so: ./handle_contract_violation.cpp
+ ${CXX} ${CXXFLAGS} -shared -fPIC -o $@ $<
+
+./libnocontinue.so: ./nocontinue.cpp
+ ${CXX} ${CXXFLAGS} -shared -fPIC -o $@ $<
+
+clean:
+ rm -fr ./libhandle_contract_violation.so ./libnocontinue.so ./assert_fail
+
diff --git a/gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/README b/gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/README
new file mode 100644
index 0000000..5c93191
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/README
@@ -0,0 +1,23 @@
+build and install gcc to $prefix, then run:
+
+LD_LIBRARY_PATH=$prefix/lib64 CXX=$prefix/bin/g++ make run
+ Build and run with continuation mode on; will print violation info from the
+ standard handler and then continue to print "returning from main"
+
+LD_LIBRARY_PATH=$prefix/lib64 CXX=$prefix/bin/g++ make runnostd
+ Build and run with continuation mode on, using the default violation handler
+ while preloading the 'nocontinue' hook. This uses LD_PRELOAD to turn all
+ continuing contract violations into non-continuing versions.
+
+ Will print violation info from the standard handler and then terminate -- it
+ will not print "returning from main"
+
+LD_LIBRARY_PATH=$prefix/lib64 CXX=$prefix/bin/g++ make runno
+ Build and run with continuation mode on, using a custom violation handler
+ while preloading the 'nocontinue' hook. This uses LD_PRELOAD to turn all
+ continuing contract violations into non-continuing versions and to install a
+ custom violation handler.
+
+ Will print violation info from the custom handler and then terminate -- it
+ will not print "returning from main"
+
diff --git a/gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/assert_fail.cpp b/gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/assert_fail.cpp
new file mode 100644
index 0000000..a17a623
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/assert_fail.cpp
@@ -0,0 +1,10 @@
+#include <iostream>
+
+int main(int, char**) {
+ int x = 0;
+ [[ assert: x < 0 ]];
+
+ std::cout << "returning from main" << std::endl;
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/handle_contract_violation.cpp b/gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/handle_contract_violation.cpp
new file mode 100644
index 0000000..8499483
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/handle_contract_violation.cpp
@@ -0,0 +1,13 @@
+#include <iostream>
+#include <contract>
+
+void handle_contract_violation(const std::contract_violation &violation) {
+ std::cerr << "custom handle_contract_violation: " << std::endl
+ << " line_number: " << violation.line_number() << std::endl
+ << " file_name: " << violation.file_name() << std::endl
+ << " function_name: " << violation.function_name() << std::endl
+ << " comment: " << violation.comment() << std::endl
+ << " assertion_level: " << violation.assertion_level() << std::endl
+ << std::endl;
+}
+
diff --git a/gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/nocontinue.cpp b/gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/nocontinue.cpp
new file mode 100644
index 0000000..2a7d53e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/preload_nocontinue_handler/nocontinue.cpp
@@ -0,0 +1,19 @@
+#include <exception>
+#include <contract>
+#include <dlfcn.h>
+
+using handler = void (*)(const std::contract_violation &);
+constexpr const char *mangledHandlerName = "_Z25handle_contract_violationRKSt18contract_violation";
+void handle_contract_violation(const std::contract_violation &violation) {
+ try {
+ handler original_handle_contract_violation;
+ original_handle_contract_violation =
+ (handler)dlsym(RTLD_NEXT, mangledHandlerName);
+ (*original_handle_contract_violation)(violation);
+ }
+ catch(...) {
+ ; // squash
+ }
+ std::terminate();
+}
+
diff --git a/gcc/testsuite/g++.dg/coroutines/pr100611.C b/gcc/testsuite/g++.dg/coroutines/pr100611.C
new file mode 100644
index 0000000..14edf48
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr100611.C
@@ -0,0 +1,94 @@
+// { dg-do run }
+/*
+ Test that instances created in capture clauses within co_await statements do not
+ get 'promoted'. This would lead to the members destructor getting called more
+ than once.
+
+ Correct output should look like:
+ Foo(23) 0xf042d8
+ Foo(const& 23) 0xf042ec
+ ~Foo(23) 0xf042ec
+ After co_await
+ ~Foo(23) 0xf042d8
+*/
+#include <coroutine>
+#include <iostream>
+
+static unsigned int struct_Foo_destructor_counter = 0;
+static bool lambda_was_executed = false;
+
+class Task {
+public:
+ struct promise_type {
+ Task get_return_object() {
+ return {std::coroutine_handle<promise_type>::from_promise(*this)};
+ }
+
+ std::suspend_never initial_suspend() { return {}; }
+ std::suspend_always final_suspend() noexcept { return {}; }
+ void unhandled_exception() {}
+ void return_void() {}
+ };
+
+ ~Task() {
+ if (handle_) {
+ handle_.destroy();
+ }
+ }
+
+ bool await_ready() { return false; }
+ bool await_suspend(std::coroutine_handle<>) { return false; }
+ bool await_resume() { return false; }
+
+private:
+ Task(std::coroutine_handle<promise_type> handle) : handle_(handle) {}
+
+ std::coroutine_handle<promise_type> handle_;
+};
+
+class Foo {
+public:
+ Foo(int id) : id_(id) {
+ std::cout << "Foo(" << id_ << ") " << (void*)this << std::endl;
+ }
+
+ Foo(Foo const& other) : id_(other.id_) {
+ std::cout << "Foo(const& " << id_ << ") " << (void*)this << std::endl;
+ }
+
+ Foo(Foo&& other) : id_(other.id_) {
+ std::cout << "Foo(&& " << id_ << ") " << (void*)this << std::endl;
+ }
+
+ ~Foo() {
+ std::cout << "~Foo(" << id_ << ") " << (void*)this << std::endl;
+ struct_Foo_destructor_counter++;
+
+ if (struct_Foo_destructor_counter > 2){
+ std::cout << "Foo was destroyed more than two times!\n";
+ __builtin_abort();
+ }
+ }
+
+private:
+ int id_;
+};
+
+Task test() {
+ Foo foo(23);
+
+ co_await [foo]() -> Task { // A copy of foo is captured. This copy must not get 'promoted'.
+ co_return;
+ }();
+
+ std::cout << "After co_await\n";
+ if (struct_Foo_destructor_counter == 0){
+ std::cout << "The captured copy of foo was not destroyed after the co_await statement!\n";
+ __builtin_abort();
+ }
+}
+
+int main() {
+ test();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/coroutines/pr101367.C b/gcc/testsuite/g++.dg/coroutines/pr101367.C
new file mode 100644
index 0000000..0a9e5be
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr101367.C
@@ -0,0 +1,72 @@
+// { dg-do run }
+
+#include <coroutine>
+using namespace std;
+#include <cstdio>
+#include <utility>
+#include <string>
+
+struct resource {
+ template<typename Func>
+ resource(Func fn) { fn(); /*std::printf("resource()\n"); */}
+ ~resource() { /*std::printf("~resource()\n"); */}
+ resource(resource&&) = delete;
+};
+
+template<typename T>
+struct generator {
+ struct promise_type {
+ generator get_return_object() {
+ return generator{coroutine_handle<promise_type>::from_promise(*this)};
+ }
+
+ void return_void() {}
+ void unhandled_exception() {}
+ suspend_always initial_suspend() { return {}; }
+ suspend_always final_suspend() noexcept { return {}; }
+
+ struct awaitable {
+ resource& r;
+
+ awaitable(resource&& r) : r(r) {}
+
+ bool await_ready() noexcept { return false; }
+
+ void await_suspend(coroutine_handle<> h) noexcept {
+ //std::printf("awaitable::await_suspend()\n");
+ }
+
+ void await_resume() noexcept {
+ //std::printf("awaitable::await_resume()\n");
+ }
+ };
+
+ awaitable yield_value(resource&& r) {
+ return awaitable{std::move(r)};
+ }
+ };
+
+ generator(coroutine_handle<promise_type> coro) : coro(coro)
+ {}
+
+ generator(generator&& g) noexcept : coro(std::exchange(g.coro, {}))
+ {}
+
+ ~generator() {
+ if (coro) { coro.destroy(); }
+ }
+
+ coroutine_handle<promise_type> coro;
+};
+
+generator<int> f() {
+ std::string s;
+ // if `s` isn't captured things work ok
+ co_yield resource{[s]{}};
+}
+
+int main() {
+ generator x = f();
+ x.coro.resume();
+ x.coro.resume();
+}
diff --git a/gcc/testsuite/g++.dg/coroutines/pr101976.C b/gcc/testsuite/g++.dg/coroutines/pr101976.C
new file mode 100644
index 0000000..1854ba0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr101976.C
@@ -0,0 +1,78 @@
+// { dg-do run }
+
+/*
+ Test that members of temporary instances in co_await statements do not get
+ 'promoted'. This would lead to the members destructor getting called more
+ than once.
+
+ Correct output should look like:
+ Before co_await
+ nontrivial_move() 0x6ec2e1
+ nontrivial_move(nontrivial_move&&) 0x6ed320
+ In subtask
+ ~nontrivial_move() 0x6ed320
+ ~nontrivial_move() 0x6ec2e1
+ After co_await
+*/
+#include <coroutine>
+#include <iostream>
+
+static unsigned int struct_nontrivial_move_destructor_counter = 0;
+
+struct task {
+ struct promise_type {
+ task get_return_object() {
+ return {std::coroutine_handle<promise_type>::from_promise(*this)};
+ }
+ std::suspend_never initial_suspend() { return {}; }
+ std::suspend_never final_suspend() noexcept { return {}; }
+ void unhandled_exception() {}
+ void return_void() {}
+ };
+
+ bool await_ready() { return true; }
+ void await_suspend(std::coroutine_handle<>) {}
+ void await_resume() {}
+
+ std::coroutine_handle<promise_type> m_handle;
+};
+
+struct nontrivial_move {
+ nontrivial_move() {
+ std::cout << "nontrivial_move() " << (void *)this << std::endl;
+ }
+ nontrivial_move(nontrivial_move&&) {
+ std::cout << "nontrivial_move(nontrivial_move&&) " << (void *)this
+ << std::endl;
+ }
+ ~nontrivial_move() {
+ std::cout << "~nontrivial_move() " << (void *)this << std::endl;
+ struct_nontrivial_move_destructor_counter++;
+ if (struct_nontrivial_move_destructor_counter > 2){
+ std::cerr << "The destructor of nontrivial_move was called more than two times!\n";
+ __builtin_abort();
+ }
+ }
+
+ char buf[128]{}; // Example why the move could be non trivial
+};
+
+struct wrapper {
+ nontrivial_move member;
+};
+
+task subtask(wrapper /* unused */) {
+ std::cout << "In subtask\n";
+ co_return;
+}
+
+task main_task() {
+ std::cout << "Before co_await\n";
+ co_await subtask({}); // wrapper must get 'promoted', but not its member
+ std::cout << "After co_await\n";
+}
+
+int main() {
+ main_task();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/coroutines/pr99576_1.C b/gcc/testsuite/g++.dg/coroutines/pr99576_1.C
new file mode 100644
index 0000000..612f0cd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr99576_1.C
@@ -0,0 +1,124 @@
+// { dg-do run }
+/*
+ Test that instances created in capture clauses within co_await statements do not get
+ 'promoted'. This would lead to their members destructors getting called more
+ than once.
+
+ Correct output should look like:
+ START TASK
+ Foo() 0x4f9320
+ IN LAMBDA
+ ~Foo() 0x4f9320
+ TASK RETURN
+*/
+#include <coroutine>
+#include <exception>
+#include <iostream>
+#include <utility>
+
+static unsigned int struct_Foo_destructor_counter = 0;
+static bool lambda_was_executed = false;
+
+class Task {
+public:
+ struct promise_type {
+ struct final_awaitable {
+ bool await_ready() noexcept { return false; }
+ auto await_suspend(std::coroutine_handle<promise_type> coro) noexcept {
+ return coro.promise().continuation;
+ }
+ void await_resume() noexcept {}
+ };
+ Task get_return_object() {
+ return Task(std::coroutine_handle<promise_type>::from_promise(*this));
+ }
+ std::suspend_always initial_suspend() { return {}; }
+ final_awaitable final_suspend() noexcept { return {}; }
+ void unhandled_exception() { std::terminate(); }
+ void return_void() {}
+
+ std::coroutine_handle<void> continuation = std::noop_coroutine();
+ };
+
+ Task(Task const&) = delete;
+ Task(Task&& other) noexcept
+ : handle_(std::exchange(other.handle_, nullptr)) {}
+ Task& operator=(Task const&) = delete;
+ Task& operator=(Task&& other) noexcept {
+ handle_ = std::exchange(other.handle_, nullptr);
+ return *this;
+ }
+ ~Task() {
+ if (handle_) {
+ handle_.destroy();
+ }
+ }
+
+ bool await_ready() const { return false; }
+ auto await_suspend(std::coroutine_handle<void> continuation) {
+ handle_.promise().continuation = continuation;
+ return handle_;
+ }
+ void await_resume() {}
+
+private:
+ explicit Task(std::coroutine_handle<promise_type> handle) : handle_(handle) {}
+
+ std::coroutine_handle<promise_type> handle_;
+};
+
+struct RunTask {
+ struct promise_type {
+ RunTask get_return_object() { return {}; }
+ std::suspend_never initial_suspend() { return {}; }
+ std::suspend_never final_suspend() noexcept { return {}; }
+ void return_void() {}
+ void unhandled_exception() { std::terminate(); }
+ };
+};
+
+struct Foo {
+ Foo() {
+ std::cout << "Foo() " << (void *)this << std::endl;
+ }
+
+ ~Foo() {
+ std::cout << "~Foo() " << (void *)this << std::endl;
+ struct_Foo_destructor_counter++;
+
+ if (struct_Foo_destructor_counter > 1 || !lambda_was_executed) {
+ std::cout << "The destructor of Foo was called more than once or too early!\n";
+ __builtin_abort();
+ }
+ }
+
+ Foo(Foo&&) = delete;
+ Foo(Foo const&) = delete;
+ Foo& operator=(Foo&&) = delete;
+ Foo& operator=(Foo const&) = delete;
+};
+
+Task DoAsync() {
+ std::cout << "START TASK\n";
+ co_await [foo = Foo{}]() -> Task { // foo is constructed inplace, no copy/move is performed.
+ // foo itself must not get 'promoted'.
+ std::cout << "IN LAMBDA\n";
+ lambda_was_executed = true;
+ co_return;
+ }();
+ // After the co_await statement the temporary lambda and foo
+ // must now have been destroyed
+ if (struct_Foo_destructor_counter == 0){
+ std::cout << "foo was not destroyed after the co_await statement!\n";
+ __builtin_abort();
+ }
+ std::cout << "TASK RETURN\n";
+ co_return;
+}
+
+RunTask Main() { co_await DoAsync(); }
+
+int main() {
+ Main();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/coroutines/pr99576_2.C b/gcc/testsuite/g++.dg/coroutines/pr99576_2.C
new file mode 100644
index 0000000..b7371d6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr99576_2.C
@@ -0,0 +1,72 @@
+// { dg-do run }
+/*
+ Test that members of temporary awaitables in co_await statements do not get
+ 'promoted'. This would lead to the members destructor getting called more
+ than once.
+
+ Correct output should look like:
+ A 0x4f82d6
+ ~A 0x4f82d6
+*/
+#include <coroutine>
+#include <iostream>
+
+
+static unsigned int struct_A_destructor_counter = 0;
+
+struct task : std::coroutine_handle<> {
+ struct promise_type;
+};
+
+struct task::promise_type {
+ task get_return_object() {
+ return {std::coroutine_handle<promise_type>::from_promise(*this)};
+ }
+ std::suspend_always initial_suspend() { return {}; }
+ std::suspend_always final_suspend() noexcept { return {}; }
+ void unhandled_exception() { std::terminate(); }
+ void return_void() {}
+};
+
+struct A {
+ void log(const char *str) { std::cout << str << " " << (void *)this << std::endl; }
+
+ A() { log(__func__); }
+
+ ~A() {
+ log(__func__);
+ struct_A_destructor_counter++;
+
+ if (struct_A_destructor_counter > 1) {
+ std::cout << "The destructor of A was called more than once!\n";
+ __builtin_abort();
+ }
+ }
+
+ A(A&&) = delete;
+ A(A const&) = delete;
+ A& operator=(A&&) = delete;
+ A& operator=(A const&) = delete;
+};
+
+struct Awaitable {
+ A a{}; // <- This member must NOT get 'promoted'
+ bool await_ready() { return false; }
+ void await_suspend(std::coroutine_handle<> handle) {}
+ void await_resume() {}
+};
+
+task coroutine() {
+ co_await Awaitable{}; // <- This temporary must get 'promoted'
+}
+
+int main() {
+
+ auto task = coroutine();
+ while (!task.done()) {
+ task();
+ }
+ task.destroy();
+
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/Wredundant-move13.C b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move13.C
new file mode 100644
index 0000000..80e7d80
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/Wredundant-move13.C
@@ -0,0 +1,61 @@
+// PR c++/107363
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wredundant-move" }
+
+// Define std::move.
+namespace std {
+ template<typename _Tp>
+ struct remove_reference
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ struct remove_reference<_Tp&>
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ struct remove_reference<_Tp&&>
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ constexpr typename std::remove_reference<_Tp>::type&&
+ move(_Tp&& __t) noexcept
+ { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
+}
+
+template <typename T, typename U>
+struct Optional {
+ U &value();
+ T release_value() {
+ T t = std::move (value ());
+ return t;
+ }
+};
+
+struct Foo {};
+void test(Optional<const Foo, const Foo> o) { o.release_value(); }
+
+struct F {
+ F(const F&);
+ F(F&&) = delete;
+};
+
+struct Z {
+ Z(const Z&) = delete;
+ Z(Z&&) = delete;
+ Z(const Z&&);
+};
+
+const F& constfref();
+const Z& constzref();
+
+void
+g ()
+{
+ // Will call F::F(const F&) w/ and w/o std::move. So it's redundant.
+ F f = std::move (constfref()); // { dg-warning "redundant move in initialization" }
+ (void) f;
+ // Will call Z::Z(const Z&&) w/ std::move, and Z::Z(const Z&) w/o.
+ // So it's not redundant.
+ Z z = std::move (constzref());
+ (void) z;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/attr-carries_dependency1.C b/gcc/testsuite/g++.dg/cpp0x/attr-carries_dependency1.C
new file mode 100644
index 0000000..bf0f9cb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/attr-carries_dependency1.C
@@ -0,0 +1,17 @@
+// { dg-do compile { target c++11 } }
+
+[[carries_dependency]] int *f1 (); // { dg-warning "attribute ignored" }
+int f2 (int *x [[carries_dependency]]); // { dg-warning "attribute ignored" }
+[[carries_dependency]] int f3 (); // { dg-warning "attribute ignored" }
+int f4 (int x [[carries_dependency]]); // { dg-warning "attribute ignored" }
+[[carries_dependency(1)]] int f5 (); // { dg-error "'carries_dependency' attribute does not take any arguments" }
+[[carries_dependency]] int v; // { dg-warning "'carries_dependency' attribute can only be applied to functions or parameters" }
+[[carries_dependency]]; // { dg-warning "attribute ignored" }
+void
+f6 ()
+{
+ [[carries_dependency]]; // { dg-warning "attributes at the beginning of statement are ignored" }
+}
+#if __has_cpp_attribute(carries_dependency)
+#error carries_dependency attribute is not actually implemented
+#endif
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor2.C
index 30b0109..eabc586 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor2.C
@@ -7,5 +7,5 @@ struct A
struct B : A
{
- constexpr B(): A() { } // { dg-error "A::A" }
+ constexpr B(): A() { } // { dg-error "A::A" "" { target c++20_down } }
};
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-default-ctor.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-default-ctor.C
index 8d352d0..2f9fbfb 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-default-ctor.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-default-ctor.C
@@ -7,6 +7,6 @@ struct A {
struct B: A { };
constexpr int f(B b) { return b.i; }
-struct C { C(); }; // { dg-message "" }
-struct D: C { }; // { dg-message "" }
-constexpr int g(D d) { return 42; } // { dg-error "invalid type" }
+struct C { C(); }; // { dg-message "" "" { target c++20_down } }
+struct D: C { }; // { dg-message "" "" { target c++20_down } }
+constexpr int g(D d) { return 42; } // { dg-error "invalid type" "" { target c++20_down } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C
index c167bb1..5eedf42 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C
@@ -37,7 +37,7 @@ struct base // { dg-message "no .constexpr. constructor" "" { target { !
struct derived : public base // { dg-message "base class" "" { target { ! implicit_constexpr } } }
{
- constexpr derived(): base() { } // { dg-error "non-.constexpr. function" "" { target { ! implicit_constexpr } } }
+ constexpr derived(): base() { } // { dg-error "non-.constexpr. function" "" { target { { ! implicit_constexpr } && c++20_down } } }
};
constexpr derived obj; // { dg-error "not literal" "" { target { ! implicit_constexpr } } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C
index 1d5c58b..383d38a 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C
@@ -87,7 +87,8 @@ struct resource {
}
};
constexpr resource f(resource d)
-{ return d; } // { dg-error "non-.constexpr." "" { target { ! implicit_constexpr } } }
-constexpr resource d = f(9); // { dg-message ".constexpr." "" { target { ! implicit_constexpr } } }
+{ return d; } // { dg-error "non-.constexpr." "" { target { { { ! implicit_constexpr } && c++20_down } || c++11_only } } }
+// { dg-error "non-.constexpr." "" { target { c++23 && { ! implicit_constexpr } } } .-2 }
+constexpr resource d = f(9); // { dg-message ".constexpr." "" { target { { ! implicit_constexpr } || c++11_only } } }
// 4.4 floating-point constant expressions
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-friend.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-friend.C
index 85dfca4..3d17182 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-friend.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-friend.C
@@ -5,7 +5,7 @@ struct A { A(); };
struct B {
friend constexpr int f(B) { return 0; } // OK
- friend constexpr int f(A) { return 0; } // { dg-error "constexpr" }
+ friend constexpr int f(A) { return 0; } // { dg-error "constexpr" "" { target c++20_down } }
};
template <class T>
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-generated1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-generated1.C
index 4b0d68b..9823571 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-generated1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-generated1.C
@@ -9,7 +9,7 @@ int g();
// We should complain about this.
template<> constexpr int A<int>::f()
-{ return g(); } // { dg-error "non-.constexpr." }
+{ return g(); } // { dg-error "non-.constexpr." "" { target c++20_down } }
// But not about this.
struct B
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice5.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice5.C
index e934421..70327fc 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice5.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice5.C
@@ -9,5 +9,5 @@ struct A
struct B
{
A a[1];
- constexpr B() : a() {} // { dg-error "non-constant|non-.constexpr." "" { target { ! implicit_constexpr } } }
+ constexpr B() : a() {} // { dg-error "non-constant|non-.constexpr." "" { target { { ! implicit_constexpr } && c++20_down } } }
};
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice6.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice6.C
index bf95b24..7eabd33 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice6.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice6.C
@@ -6,6 +6,6 @@ struct A
A(int);
};
-struct B : A {}; // { dg-message "" }
+struct B : A {}; // { dg-message "" "" { target c++20_down } }
-constexpr int foo(B) { return 0; } // { dg-error "invalid type" }
+constexpr int foo(B) { return 0; } // { dg-error "invalid type" "" { target c++20_down } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C
index 3725528..0c95961 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C
@@ -13,6 +13,6 @@ constexpr X X::g(X x) { return x; }
struct Y
{
Y() { }
- constexpr Y f(Y y) { return y; } // { dg-error "constexpr" "" { target { ! implicit_constexpr } } }
- static constexpr Y g(Y y) { return y; } // { dg-error "constexpr" "" { target { ! implicit_constexpr } } }
+ constexpr Y f(Y y) { return y; } // { dg-error "constexpr" "" { target { { ! implicit_constexpr } && c++20_down } } }
+ static constexpr Y g(Y y) { return y; } // { dg-error "constexpr" "" { target { { ! implicit_constexpr } && c++20_down } } }
};
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-neg2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-neg2.C
index 793b4c3..47f7fb05 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-neg2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-neg2.C
@@ -18,10 +18,10 @@ constexpr int three = one() ? 3 : nonconst_func(0);
constexpr int bogus() { return zero () ? 3 : nonconst_func(0); } // { dg-error "nonconst_func" }
// Correctly rejected (not sure why).
-constexpr int correct_error() { return nonconst_func(0); } // { dg-error "nonconst_func" }
+constexpr int correct_error() { return nonconst_func(0); } // { dg-error "nonconst_func" "" { target c++20_down } }
// Correctly rejected.
constexpr int z = bogus(); // { dg-error "" }
// This is also correctly rejected.
-constexpr int correct_failure() { return 0 ? 3 : nonconst_func(0); } // { dg-error "nonconst_func" }
+constexpr int correct_failure() { return 0 ? 3 : nonconst_func(0); } // { dg-error "nonconst_func" "" { target c++20_down } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-non-const-arg.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-non-const-arg.C
index 0f68643..abbc703 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-non-const-arg.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-non-const-arg.C
@@ -10,7 +10,7 @@ struct B {
int global; // { dg-message "not const" }
struct D : B {
- constexpr D() : B(global) { } // { dg-error "global|argument" }
+ constexpr D() : B(global) { } // { dg-error "global|argument" "" { target c++20_down } }
};
struct A2 {
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C
index d7d244f..4e19cd3 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C
@@ -17,7 +17,7 @@ public:
constexpr static Inner & getInner()
/* I am surprised this is considered a constexpr */
{
- return *((Inner *)4); // { dg-error "reinterpret_cast" }
+ return *((Inner *)4); // { dg-error "reinterpret_cast" "" { target c++20_down } }
}
};
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted3.C b/gcc/testsuite/g++.dg/cpp0x/defaulted3.C
index 75e89c8..33de973 100644
--- a/gcc/testsuite/g++.dg/cpp0x/defaulted3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted3.C
@@ -4,7 +4,7 @@
template<class T>
struct A {
template<class U>
- bool operator==(const A<U>&) = delete; // { dg-message "declared" }
+ bool operator==(const A<U>&) const = delete; // { dg-message "declared" }
operator bool () { return true; }
};
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr65327.C b/gcc/testsuite/g++.dg/cpp0x/pr65327.C
index e814995..b3ef57e 100644
--- a/gcc/testsuite/g++.dg/cpp0x/pr65327.C
+++ b/gcc/testsuite/g++.dg/cpp0x/pr65327.C
@@ -14,5 +14,5 @@ foo ()
constexpr volatile int // { dg-warning "deprecated" "" { target c++2a } }
bar ()
{
- return i; // { dg-error "lvalue-to-rvalue conversion of a volatile lvalue" }
+ return i; // { dg-error "lvalue-to-rvalue conversion of a volatile lvalue" "" { target c++20_down } }
}
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-105050.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-105050.C
index e0688fb..e5d53c9 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-105050.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-105050.C
@@ -5,7 +5,7 @@ void g();
void h();
constexpr void f(int* p, int* q) {
- if (p != q && *p < 0) // { dg-error "neither branch of 'if' is a constant expression" }
+ if (p != q && *p < 0) // { dg-error "neither branch of 'if' is a constant expression" "" { target c++20_down } }
g();
else
h();
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285-2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285-2.C
index ea44daa..7b129fc 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285-2.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285-2.C
@@ -10,7 +10,7 @@ struct B {
int *c = &x->a;
while (*c)
c = reinterpret_cast<int *>((reinterpret_cast<char *>(c) + *c));
- *c = reinterpret_cast<char *>(this) - reinterpret_cast<char *>(c); // { dg-error "reinterpret_cast" }
+ *c = reinterpret_cast<char *>(this) - reinterpret_cast<char *>(c); // { dg-error "reinterpret_cast" "" { target c++20_down } }
}
};
struct C : A {
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C
index 26aab9b..fe0b857 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C
@@ -10,7 +10,7 @@ struct B {
int *c = &x->a;
while (*c)
c = reinterpret_cast<int *>((reinterpret_cast<char *>(c) + *c));
- *c = reinterpret_cast<char *>(this) - reinterpret_cast<char *>(c); // { dg-error "reinterpret_cast" }
+ *c = reinterpret_cast<char *>(this) - reinterpret_cast<char *>(c); // { dg-error "reinterpret_cast" "" { target c++20_down } }
}
};
struct C : A {
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-89785-2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-89785-2.C
index 5cd46c7..7afd9d2 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-89785-2.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-89785-2.C
@@ -11,7 +11,7 @@ foo (int x)
case 2:
break;
}
- throw 42; // { dg-error "is not a constant expression" }
+ throw 42; // { dg-error "is not a constant expression" "" { target c++20_down } }
return 0;
}
@@ -29,7 +29,7 @@ bar (int x)
continue;
break;
}
- throw -42; // { dg-error "is not a constant expression" }
+ throw -42; // { dg-error "is not a constant expression" "" { target c++20_down } }
}
while (0);
return x;
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-neg1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-neg1.C
index 8e9d1ea..53b5dd5 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-neg1.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-neg1.C
@@ -3,7 +3,7 @@
struct A { A(); };
constexpr int f(int i) {
- static int j = i; // { dg-error "static" }
+ static int j = i; // { dg-error "static" "" { target c++20_down } }
thread_local int l = i; // { dg-error "thread_local" "" { target c++20_down } }
goto foo; // { dg-error "goto" "" { target c++20_down } }
foo:
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-nsdmi7b.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-nsdmi7b.C
index ec10ddd..a410e48 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-nsdmi7b.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-nsdmi7b.C
@@ -21,7 +21,7 @@ bar()
A a = foo();
a.p->n = 5;
return a;
-} // { dg-error "non-.constexpr." }
+} // { dg-error "non-.constexpr." "" { target c++20_down } }
constexpr int
baz()
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C
index 3bbc8ac..3592874 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C
@@ -7,18 +7,18 @@ constexpr void f1() {
constexpr void f2() {
if (true)
- throw; // { dg-error "not a constant expression" }
+ throw; // { dg-error "not a constant expression" "" { target c++20_down } }
}
constexpr void f3() {
if (false)
;
else
- throw; // { dg-error "not a constant expression" }
+ throw; // { dg-error "not a constant expression" "" { target c++20_down } }
}
constexpr void f4() {
- throw; // { dg-error "not a constant expression" }
+ throw; // { dg-error "not a constant expression" "" { target c++20_down } }
}
constexpr int fun(int n) {
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1-18.C b/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1-18.C
new file mode 100644
index 0000000..22ad15e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1-18.C
@@ -0,0 +1,26 @@
+// { dg-do compile { target c++14 } }
+// { dg-additional-options -fabi-version=18 }
+
+// PRs 78621
+
+#include "lambda-mangle-1.h"
+
+// We erroneously mangled lambda auto parms as-if template parameters (T<n>_),
+// rather than auto (Da). Fixed in abi version 11
+
+// ABI 18 uses per-scope per-signature lambda discriminator
+
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRT_E_EOS0_S1_:" } }
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRiRT_E_EOS1_S2_:" } }
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRT_R1XIiEE_EOS0_S1_:" } }
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlPA5_T_E_EOS0_RS0_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlRT_E_EvS1_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlRiRT_E_EvS2_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlRT_R1XIiEE_EvS1_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlPA5_T_E_EvRS0_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3FoovEUlPfS1_E_EvRT_RT0_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3FoovEUlPT_PT0_E_EvRS1_RS3_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlPT_PT0_E_Z3FoovEUlS1_S3_E0_EvRS0_RS2_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPfS3_E_EvRT_RT0_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPT_PT0_E_EvRS3_RS5_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsDpPT_E_EvRT_RT0_:" } }
diff --git a/gcc/testsuite/g++.dg/cpp1y/new1.C b/gcc/testsuite/g++.dg/cpp1y/new1.C
index fec0088..21f225c 100644
--- a/gcc/testsuite/g++.dg/cpp1y/new1.C
+++ b/gcc/testsuite/g++.dg/cpp1y/new1.C
@@ -65,7 +65,7 @@ void
test_unused() {
volatile double d = 0.0;
double *p = new double ();
- d += 1.0; // { dg-warning "deprecated" "" { target c++2a } }
+ d += 1.0;
delete p;
}
diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp56.C b/gcc/testsuite/g++.dg/cpp1z/decomp56.C
new file mode 100644
index 0000000..25a4c3d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/decomp56.C
@@ -0,0 +1,29 @@
+// PR c++/84469
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct A {
+ template <typename T>
+ void bar () const {}
+ template <typename T>
+ void baz () const {}
+};
+struct B { A a; };
+
+template <typename>
+void
+foo ()
+{
+ A a[1][1];
+ for (auto const& [b]: a) // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ b.bar<int> ();
+ B c;
+ auto const& [d] = c; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ d.baz<double> ();
+}
+
+int
+main ()
+{
+ foo<int> ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/charset1.C b/gcc/testsuite/g++.dg/cpp23/charset1.C
new file mode 100644
index 0000000..d6f0d1c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/charset1.C
@@ -0,0 +1,10 @@
+// P2314R4
+// { dg-do compile { target c++23 } }
+// { dg-options "-finput-charset=UTF-8 -fexec-charset=UTF-8" }
+
+#define S(x) # x
+const char s1[] = S(Köppe); // "Köppe"
+const char s2[] = S(K\u00f6ppe); // "Köppe"
+
+static_assert (sizeof (s1) == 7);
+static_assert (sizeof (s2) == 7);
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit10.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit10.C
new file mode 100644
index 0000000..31d4b87
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit10.C
@@ -0,0 +1,96 @@
+// PR c++/106649
+// P2448 - Relaxing some constexpr restrictions
+// { dg-do compile { target c++23 } }
+// { dg-options "-Winvalid-constexpr -pedantic-errors" }
+
+// No constexpr constructors = not a literal type.
+struct NonLiteral {
+ NonLiteral() {}
+};
+
+// C++23: It is possible to write a constexpr function for which no
+// invocation satisfies the requirements of a core constant expression.
+constexpr NonLiteral
+fn0 (int) // { dg-warning "invalid return type" "" { target { ! implicit_constexpr } } }
+{
+ return NonLiteral{};
+}
+
+constexpr int
+fn1 (NonLiteral) // { dg-warning "invalid type" "" { target { ! implicit_constexpr } } }
+{
+ return 42;
+}
+
+// From P2448.
+void f(int& i) {
+ i = 0;
+}
+
+constexpr void g(int& i) {
+ f(i); // { dg-warning "call to" }
+}
+
+// [dcl.constexpr] used to have this.
+constexpr int f(bool b)
+ { return b ? throw 0 : 0; } // OK
+constexpr int f() { return f(true); } // ill-formed, no diagnostic required
+
+struct B {
+ constexpr B(int) : i(0) { }
+ int i;
+};
+
+int global;
+
+struct D : B {
+ constexpr D() : B(global) { } // { dg-warning "not usable" }
+ // ill-formed, no diagnostic required
+ // lvalue-to-rvalue conversion on non-constant global
+};
+
+// If no specialization of the template would satisfy the requirements
+// for a constexpr function when considered as a non-template function,
+// the template is ill-formed, no diagnostic required.
+template<typename>
+constexpr void
+fn2 ()
+{
+ int i = 42;
+ f (i);
+}
+
+void
+fn3 ()
+{
+ fn2<int>();
+}
+
+constexpr volatile int cvi = 10;
+
+constexpr int
+fn4 ()
+{
+ return cvi; // { dg-warning "lvalue-to-rvalue conversion" }
+}
+
+constexpr unsigned int
+fn5 (int *p)
+{
+ unsigned int *q = reinterpret_cast<unsigned int *>(p); // { dg-warning "reinterpret_cast" }
+ return *q;
+}
+
+constexpr int
+fn6 (int i)
+{
+ void *p = (void *) 1LL; // { dg-warning ".reinterpret_cast. from integer to pointer" }
+ return 42;
+}
+
+constexpr int
+fn7 (int i)
+{
+ static int s = i; // { dg-warning "static" }
+ return s;
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit11.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit11.C
new file mode 100644
index 0000000..e08809f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit11.C
@@ -0,0 +1,53 @@
+// PR c++/106649
+// P2448 - Relaxing some constexpr restrictions
+// { dg-do compile { target c++23 } }
+// { dg-options "-Winvalid-constexpr -pedantic-errors" }
+
+// [dcl.constexpr]/4 used to say:
+// The definition of a constexpr constructor whose function-body
+// is not = delete shall additionally satisfy the following requirements:
+// (4.1) for a non-delegating constructor, every constructor selected to initialize non-static data members and base class subobjects shall be a constexpr constructor;
+// (4.2) for a delegating constructor, the target constructor shall be a constexpr constructor.
+
+// This continues to be OK.
+struct Length {
+ constexpr explicit Length(int i = 0) : val(i) { }
+private:
+ int val;
+};
+
+struct X {
+ X() {}
+ X(int i_) : i(i_) {}
+ int i;
+};
+
+struct S {
+ X x;
+ // Calls a non-constexpr constructor X::X(int).
+ constexpr S(int i) : x(i) { } // { dg-warning "call to" "" { target { ! implicit_constexpr } } }
+ S(int, int) { }
+ // Target constructor isn't constexpr.
+ constexpr S() : S(42, 42) { } // { dg-warning "call to" "" { target { ! implicit_constexpr } } }
+};
+
+namespace N1 {
+struct X {
+ void x();
+};
+struct Y {
+ X x;
+ constexpr void y() { x.x(); } // { dg-warning "call to" }
+};
+}
+
+void g();
+
+struct A {
+ constexpr A() { g(); } // { dg-warning "call to" }
+};
+
+struct B {
+ constexpr B& operator=(const B&) { g(); return *this; } // { dg-warning "call to" }
+ constexpr B& operator=(B&&) { g(); return *this; } // { dg-warning "call to" }
+};
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit12.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit12.C
new file mode 100644
index 0000000..8f003b8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit12.C
@@ -0,0 +1,24 @@
+// PR c++/106649
+// P2448 - Relaxing some constexpr restrictions
+// { dg-do compile { target c++23 } }
+// Test that we get a diagnostic even in C++23 if you do call the function.
+
+constexpr unsigned int
+fn0 (const int *p)
+{
+ return *reinterpret_cast<unsigned const int *>(p); // { dg-error ".reinterpret_cast. is not a constant expression" }
+}
+
+constexpr void *
+fn1 (int i)
+{
+ return (void *) 1LL; // { dg-error ".reinterpret_cast." }
+}
+
+void
+g ()
+{
+ constexpr int i = 42;
+ constexpr auto a1 = fn0 (&i);
+ constexpr auto a2 = fn1 (i); // { dg-error "called in a constant expression" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit13.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit13.C
new file mode 100644
index 0000000..7997e8e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit13.C
@@ -0,0 +1,14 @@
+// PR c++/106649
+// P2448 - Relaxing some constexpr restrictions
+// { dg-do compile { target c++23 } }
+// { dg-options "-Winvalid-constexpr" }
+
+constexpr volatile int i = 10;
+
+constexpr int
+bar ()
+{
+ return i; // { dg-warning "lvalue-to-rvalue conversion of a volatile lvalue" }
+}
+
+constexpr int x = bar (); // { dg-error "called in a constant expression" }
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit14.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit14.C
new file mode 100644
index 0000000..f79ff15
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit14.C
@@ -0,0 +1,26 @@
+// PR c++/106649
+// P2448 - Relaxing some constexpr restrictions
+// { dg-do compile { target c++20 } }
+// { dg-options "" }
+// The definition of a constexpr destructor whose function-body is not
+// =delete shall additionally satisfy the following requirement:
+// (5.1) for every subobject of class type or (possibly multi-dimensional)
+// array thereof, that class type shall have a constexpr destructor.
+
+struct B {
+ B() { }
+ ~B() { }
+};
+
+struct T : B {
+ constexpr ~T() { } // { dg-warning "call to" "" { target c++20_down } }
+};
+
+struct S {
+ constexpr S() = default; // was error: implicit S() is not constexpr, now OK
+ ~S() noexcept(false) = default; // OK, despite mismatched exception specification
+private:
+ int i;
+ S(S&); // OK: private copy constructor
+};
+S::S(S&) = default; // OK: defines copy constructor
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit15.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit15.C
new file mode 100644
index 0000000..aa35fa8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit15.C
@@ -0,0 +1,35 @@
+// PR c++/106649
+// P2448 - Relaxing some constexpr restrictions
+// { dg-do compile { target c++23 } }
+// { dg-options "-Winvalid-constexpr" }
+// A copy/move assignment operator for a class X that is defaulted and
+// not defined as deleted is implicitly defined when it is odr-used,
+// when it is needed for constant evaluation, or when it is explicitly
+// defaulted after its first declaration.
+// The implicitly-defined copy/move assignment operator is constexpr.
+
+struct S {
+ constexpr S() {}
+ S& operator=(const S&) = default;
+ S& operator=(S&&) = default;
+};
+
+struct U {
+ constexpr U& operator=(const U&) = default;
+ constexpr U& operator=(U&&) = default;
+};
+
+constexpr void
+g ()
+{
+ S a;
+ S b;
+ b = a;
+ b = S{};
+
+ U u, v;
+ u = v;
+ u = U{};
+}
+
+static_assert ((g(), true), "");
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit16.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit16.C
new file mode 100644
index 0000000..a6c4d19
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit16.C
@@ -0,0 +1,23 @@
+// PR c++/106649
+// P2448 - Relaxing some constexpr restrictions
+// { dg-do compile { target c++20 } }
+// { dg-options "" }
+
+template <typename T>
+struct Wrapper {
+ constexpr Wrapper() = default;
+ constexpr Wrapper(Wrapper const&) = default;
+ constexpr Wrapper(T const& t) : t(t) { }
+
+ constexpr T get() const { return t; }
+ constexpr bool operator==(Wrapper const&) const = default; // { dg-warning "call to" "" { target c++20_down } }
+private:
+ T t;
+};
+
+struct X {
+ X();
+ bool operator==(X const&) const;
+};
+
+Wrapper<X> x;
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit17.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit17.C
new file mode 100644
index 0000000..a4c78bb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit17.C
@@ -0,0 +1,12 @@
+// P2647R1 - Permitting static constexpr variables in constexpr functions
+// { dg-do compile { target c++23 } }
+
+constexpr char
+test ()
+{
+ static const int x = 5;
+ static constexpr char c[] = "Hello World";
+ return *(c + x);
+}
+
+static_assert (test () == ' ');
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit18.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit18.C
new file mode 100644
index 0000000..8e230ef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit18.C
@@ -0,0 +1,49 @@
+// P2647R1 - Permitting static constexpr variables in constexpr functions
+// { dg-do compile { target c++14 } }
+
+constexpr int
+f1 (int x)
+{
+ if (x)
+ throw 1;
+ return 0;
+}
+
+constexpr int
+f2 ()
+{
+ static const int a = f1 (1); // { dg-error "'a' defined 'static' in 'constexpr' function only available with" "" { target c++20_down } }
+ return 0;
+}
+
+constexpr int
+f3 ()
+{
+ static const int a = 5; // { dg-error "'a' defined 'static' in 'constexpr' function only available with" "" { target c++20_down } }
+ return 0;
+}
+
+constexpr int
+f4 () // { dg-message "declared here" "" { target c++20_down } }
+{ // { dg-message "is not usable as a 'constexpr' function because:" "" { target c++23 } .-1 }
+ static const int a = f1 (1); // { dg-error "'a' defined 'static' in 'constexpr' function only available with" "" { target c++20_down } }
+ return 0; // { dg-error "'a' defined 'static' in 'constexpr' context" "" { target c++23 } .-1 }
+}
+
+constexpr int a4 = f4 (); // { dg-error "called in a constant expression" }
+
+constexpr int
+f5 ()
+{
+ static const int a = f1 (0); // { dg-error "'a' defined 'static' in 'constexpr' function only available with" "" { target c++20_down } }
+ return 0;
+}
+
+constexpr int
+f6 ()
+{
+ static const int a = f1 (0); // { dg-error "'a' defined 'static' in 'constexpr' function only available with" "" { target c++20_down } }
+ return 0;
+}
+
+constexpr int a6 = f6 (); // { dg-error "called in a constant expression" "" { target c++20_down } }
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit3.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit3.C
index 3b5585d..2238db9 100644
--- a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit3.C
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit3.C
@@ -5,6 +5,6 @@ constexpr int
foo ()
{
goto lab; // { dg-error "'goto' in 'constexpr' function only available with" "" { target c++20_down } }
-lab: // { dg-error "'goto' is not a constant expression" "" { target { c++23 } } .-1 }
+lab:
return 1;
}
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit6.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit6.C
index fbeb830..a143693 100644
--- a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit6.C
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit6.C
@@ -18,8 +18,19 @@ bar ()
}
constexpr int
-baz (int x)
+baz ()
{
thread_local int a; // { dg-error "'a' defined 'thread_local' in 'constexpr' context" }
return ++a;
}
+
+// In C++23, we get errors about the non-constant expressions only if we
+// actually call the functions in a constexpr context.
+
+void
+test ()
+{
+ constexpr int a = foo (); // { dg-error "constant expression" }
+ constexpr int b = bar (); // { dg-error "constant expression" }
+ constexpr int c = baz (); // { dg-error "constant expression" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit8.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit8.C
new file mode 100644
index 0000000..3fb1b93
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit8.C
@@ -0,0 +1,96 @@
+// PR c++/106649
+// P2448 - Relaxing some constexpr restrictions
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+// No constexpr constructors = not a literal type.
+struct NonLiteral {
+ NonLiteral() {}
+};
+
+// C++23: It is possible to write a constexpr function for which no
+// invocation satisfies the requirements of a core constant expression.
+constexpr NonLiteral
+fn0 (int) // { dg-warning "invalid return type" "" { target c++20_down } }
+{
+ return NonLiteral{};
+}
+
+constexpr int
+fn1 (NonLiteral) // { dg-warning "invalid type" "" { target c++20_down } }
+{
+ return 42;
+}
+
+// From P2448.
+void f(int& i) {
+ i = 0;
+}
+
+constexpr void g(int& i) {
+ f(i); // { dg-warning "call to" "" { target c++20_down } }
+}
+
+// [dcl.constexpr] used to have this.
+constexpr int f(bool b)
+ { return b ? throw 0 : 0; } // OK
+constexpr int f() { return f(true); } // ill-formed, no diagnostic required
+
+struct B {
+ constexpr B(int) : i(0) { }
+ int i;
+};
+
+int global;
+
+struct D : B {
+ constexpr D() : B(global) { } // { dg-warning "not usable" "" { target c++20_down } }
+ // ill-formed, no diagnostic required
+ // lvalue-to-rvalue conversion on non-constant global
+};
+
+// If no specialization of the template would satisfy the requirements
+// for a constexpr function when considered as a non-template function,
+// the template is ill-formed, no diagnostic required.
+template<typename>
+constexpr void
+fn2 ()
+{
+ int i = 42;
+ f (i);
+}
+
+void
+fn3 ()
+{
+ fn2<int>();
+}
+
+constexpr volatile int cvi = 10;
+
+constexpr int
+fn4 ()
+{
+ return cvi; // { dg-warning "lvalue-to-rvalue conversion" "" { target c++20_down } }
+}
+
+constexpr unsigned int
+fn5 (int *p)
+{
+ unsigned int *q = reinterpret_cast<unsigned int *>(p); // { dg-warning "reinterpret_cast" "" { target c++20_down } }
+ return *q;
+}
+
+constexpr int
+fn6 (int i)
+{
+ void *p = (void *) 1LL; // { dg-warning ".reinterpret_cast. from integer to pointer" "" { target c++20_down } }
+ return 42;
+}
+
+constexpr int
+fn7 (int i)
+{
+ static int s = i; // { dg-error "static" "" { target c++20_down } }
+ return s;
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit9.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit9.C
new file mode 100644
index 0000000..228e90f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit9.C
@@ -0,0 +1,53 @@
+// PR c++/106649
+// P2448 - Relaxing some constexpr restrictions
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+// [dcl.constexpr]/4 used to say:
+// The definition of a constexpr constructor whose function-body
+// is not = delete shall additionally satisfy the following requirements:
+// (4.1) for a non-delegating constructor, every constructor selected to initialize non-static data members and base class subobjects shall be a constexpr constructor;
+// (4.2) for a delegating constructor, the target constructor shall be a constexpr constructor.
+
+// This continues to be OK.
+struct Length {
+ constexpr explicit Length(int i = 0) : val(i) { }
+private:
+ int val;
+};
+
+struct X {
+ X() {}
+ X(int i_) : i(i_) {}
+ int i;
+};
+
+struct S {
+ X x;
+ // Calls a non-constexpr constructor X::X(int).
+ constexpr S(int i) : x(i) { } // { dg-warning "call to" "" { target c++20_down } }
+ S(int, int) { }
+ // Target constructor isn't constexpr.
+ constexpr S() : S(42, 42) { } // { dg-warning "call to" "" { target c++20_down } }
+};
+
+namespace N1 {
+struct X {
+ void x();
+};
+struct Y {
+ X x;
+ constexpr void y() { x.x(); } // { dg-warning "call to" "" { target c++20_down } }
+};
+}
+
+void g();
+
+struct A {
+ constexpr A() { g(); } // { dg-warning "call to" "" { target c++20_down } }
+};
+
+struct B {
+ constexpr B& operator=(const B&) { g(); return *this; } // { dg-warning "call to" "" { target c++20_down } }
+ constexpr B& operator=(B&&) { g(); return *this; } // { dg-warning "call to" "" { target c++20_down } }
+};
diff --git a/gcc/testsuite/g++.dg/cpp23/elision4.C b/gcc/testsuite/g++.dg/cpp23/elision4.C
index d39053a..77dcffc 100644
--- a/gcc/testsuite/g++.dg/cpp23/elision4.C
+++ b/gcc/testsuite/g++.dg/cpp23/elision4.C
@@ -34,6 +34,6 @@ T& temporary2(T&& x) { return static_cast<T&>(x); }
void
test ()
{
- int& r1 = temporary1 (42); // { dg-warning "dangling reference" }
- int& r2 = temporary2 (42); // { dg-warning "dangling reference" }
+ int& r1 = temporary1 (42);
+ int& r2 = temporary2 (42);
}
diff --git a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
index efe9770..6f4f6bc 100644
--- a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
+++ b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
@@ -134,8 +134,8 @@
#ifndef __cpp_constexpr
# error "__cpp_constexpr"
-#elif __cpp_constexpr != 202110
-# error "__cpp_constexpr != 202110"
+#elif __cpp_constexpr != 202211
+# error "__cpp_constexpr != 202211"
#endif
#ifndef __cpp_decltype_auto
@@ -556,8 +556,8 @@
#ifndef __cpp_multidimensional_subscript
# error "__cpp_multidimensional_subscript"
-#elif __cpp_multidimensional_subscript != 202110
-# error "__cpp_multidimensional_subscript != 202110"
+#elif __cpp_multidimensional_subscript != 202211
+# error "__cpp_multidimensional_subscript != 202211"
#endif
#ifndef __cpp_named_character_escapes
diff --git a/gcc/testsuite/g++.dg/cpp23/static-operator-call4.C b/gcc/testsuite/g++.dg/cpp23/static-operator-call4.C
new file mode 100644
index 0000000..83ccde3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/static-operator-call4.C
@@ -0,0 +1,37 @@
+// PR c++/107624
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+int n[3];
+struct S {
+ static void operator() (int x) { n[0] |= (1 << x); } // { dg-warning "may be a static member function only with" "" { target c++20_down } }
+ static void baz (int x) { n[1] |= (1 << x); }
+ int s;
+};
+volatile S s[2];
+
+S &
+foo (int x)
+{
+ static S t;
+ n[2] |= (1 << x);
+ return t;
+}
+
+int
+main ()
+{
+ int i = 0;
+ foo (0) (0);
+ if (n[0] != 1 || n[1] || n[2] != 1)
+ __builtin_abort ();
+ foo (1).baz (1);
+ if (n[0] != 1 || n[1] != 2 || n[2] != 3)
+ __builtin_abort ();
+ s[i++] (2);
+ if (i != 1 || n[0] != 5 || n[1] != 2 || n[2] != 3)
+ __builtin_abort ();
+ s[--i].baz (3);
+ if (i != 0 || n[0] != 5 || n[1] != 10 || n[2] != 3)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/subscript10.C b/gcc/testsuite/g++.dg/cpp23/subscript10.C
new file mode 100644
index 0000000..96e5e1f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/subscript10.C
@@ -0,0 +1,46 @@
+// PR c++/107624
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+int n[3];
+struct S {
+ static int &operator[] (int x) { n[0] |= (1 << x); return n[2]; } // { dg-warning "may be a static member function only with" "" { target c++20_down } }
+#if __cpp_multidimensional_subscript >= 202211L
+ static int &operator[] () { n[0] |= (1 << 8); return n[2]; }
+ static int &operator[] (int y, int z, int w) { n[0] |= (1 << y) | (1 << z) | (1 << w); return n[2]; }
+#endif
+ int s;
+};
+volatile S s[2];
+
+S &
+foo (int x)
+{
+ static S t;
+ n[1] |= (1 << x);
+ return t;
+}
+
+int
+main ()
+{
+ int i = 0;
+ foo (0) [0]++;
+ if (n[0] != 1 || n[1] != 1 || n[2] != 1)
+ __builtin_abort ();
+ s[i++][2]++;
+ if (i != 1 || n[0] != 5 || n[1] != 1 || n[2] != 2)
+ __builtin_abort ();
+#if __cpp_multidimensional_subscript >= 202211L
+ foo (3) []++;
+ if (n[0] != 261 || n[1] != 9 || n[2] != 3)
+ __builtin_abort ();
+ int y = 10;
+ int z = 10;
+ int w = 13;
+ foo (4) [y++, ++z, w++]++;
+ if (n[0] != 11525 || n[1] != 25 || n[2] != 4
+ || y != 11 || z != 11 || w != 14)
+ __builtin_abort ();
+#endif
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/subscript11.C b/gcc/testsuite/g++.dg/cpp23/subscript11.C
new file mode 100644
index 0000000..990a703
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/subscript11.C
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct S {
+ static int &operator[] (int); // { dg-warning "may be a static member function only with" "" { target c++20_down } }
+ static int &operator[] (); // { dg-warning "may be a static member function only with" "" { target c++20_down } }
+ // { dg-error "'static int& S::operator\\\[\\\]\\\(\\\)' must have exactly one argument" "" { target c++20_down } .-1 }
+ static int &operator[] (int, int, int); // { dg-warning "may be a static member function only with" "" { target c++20_down } }
+ // { dg-error "'static int& S::operator\\\[\\\]\\\(int, int, int\\\)' must have exactly one argument" "" { target c++20_down } .-1 }
+ int s;
+};
diff --git a/gcc/testsuite/g++.dg/cpp23/subscript9.C b/gcc/testsuite/g++.dg/cpp23/subscript9.C
new file mode 100644
index 0000000..72cea4b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/subscript9.C
@@ -0,0 +1,29 @@
+// P2589R1
+// { dg-do run { target c++23 } }
+
+extern "C" void abort ();
+
+struct S
+{
+ S () {};
+ static int &operator[] () { return a[0]; }
+ static int &operator[] (int x) { return a[x]; }
+ static int &operator[] (int x, long y) { return a[x + y * 8]; }
+ static int a[64];
+};
+int S::a[64];
+
+int
+main ()
+{
+ S s;
+ for (int i = 0; i < 64; i++)
+ s.a[i] = 64 - i;
+ if (s[] != 64 || s[3] != 61 || s[4, 5] != 20)
+ abort ();
+ s[]++;
+ s[42]++;
+ ++s[3, 2];
+ if (s.a[0] != 65 || s.a[42] != 23 || s.a[19] != 46)
+ abort ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/bit-cast7.C b/gcc/testsuite/g++.dg/cpp2a/bit-cast7.C
index 4a3c682..6927db3 100644
--- a/gcc/testsuite/g++.dg/cpp2a/bit-cast7.C
+++ b/gcc/testsuite/g++.dg/cpp2a/bit-cast7.C
@@ -16,7 +16,7 @@ struct J
struct K
{
long int a, b : 11, c;
- constexpr bool operator == (const K &x)
+ constexpr bool operator == (const K &x) const
{
return a == x.a && b == x.b && c == x.c;
}
@@ -29,7 +29,7 @@ struct L
struct M
{
long long int a, b : 11, c;
- constexpr bool operator == (const M &x)
+ constexpr bool operator == (const M &x) const
{
return a == x.a && b == x.b && c == x.c;
}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-dr2428.C b/gcc/testsuite/g++.dg/cpp2a/concepts-dr2428.C
new file mode 100644
index 0000000..d08ad36
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-dr2428.C
@@ -0,0 +1,22 @@
+// DR 2428
+// { dg-do compile { target c++20 } }
+
+template<typename T>
+concept C1 [[deprecated]] = true;
+
+template<typename T>
+concept C2 __attribute__((deprecated)) = false;
+
+template<typename T>
+concept C3 [[deprecated]] = true;
+
+template<typename T>
+concept C4 __attribute__((deprecated)) = false;
+
+static_assert(C3<int>); // { dg-warning "'C3' is deprecated" }
+static_assert(C4<int>); // { dg-error "static assertion failed" }
+ // { dg-warning "'C4' is deprecated" "" { target *-*-* } .-1 }
+
+template<typename T>
+ requires C3<T> // { dg-warning "'C3' is deprecated" }
+int fn1(T t) { return 0; }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-friend11.C b/gcc/testsuite/g++.dg/cpp2a/concepts-friend11.C
new file mode 100644
index 0000000..0350ac3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-friend11.C
@@ -0,0 +1,21 @@
+// CWG2596
+// { dg-do compile { target c++20 } }
+
+struct Base {};
+
+int foo(Base&) { return 0; } // #0
+
+template<int N>
+struct S : Base {
+ friend int foo(Base&) requires (N == 1) { return 1; } // #1
+ // friend int foo(Base&) requires (N == 2) { return 3; } // #2
+};
+
+S<1> s1;
+S<2> s2; // OK, no conflict between #1 and #0
+int x = foo(s1); // { dg-error "ambiguous" }
+int y = foo(s2); // OK, selects #0
+
+// ??? currently the foos all mangle the same, so comment out #2
+// and only test that #1 isn't multiply defined and overloads with #0.
+// The 2596 example does not include #0 and expects both calls to work.
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder10.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder10.C
new file mode 100644
index 0000000..b831531
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder10.C
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++20 } }
+// { dg-options "-Wno-pedantic" }
+
+template <class T> concept is_const = __is_same(T, const T);
+
+void f() {
+ int x[] = {1,2};
+ const int y[] = {3};
+ const is_const auto [a,b] = x; // { dg-error "constraints" }
+ const is_const auto [c] = y;
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder7.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder7.C
index 93219ff..7ba6ab9 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder7.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder7.C
@@ -7,16 +7,18 @@ template <class>
void f() {
int x[] = {1,2};
int y[] = {3};
- C1 auto [a,b] = x;
- C1 auto [c] = y; // { dg-error "constraints" }
+ C1 auto [a,b] = x; // { dg-error "structured binding declaration cannot have constrained 'auto' type 'auto \\\[requires ::C1<<placeholder>, >\\\]'" }
+ C1 auto [c] = y; // { dg-error "structured binding declaration cannot have constrained 'auto' type 'auto \\\[requires ::C1<<placeholder>, >\\\]'" }
+ // { dg-error "constraints" "" { target *-*-* } .-1 }
}
template <class T>
void g() {
T x[] = {1,2};
T y[] = {3};
- C1 auto [a,b] = x;
- C1 auto [c] = y; // { dg-error "constraints" }
+ C1 auto [a,b] = x; // { dg-error "structured binding declaration cannot have constrained 'auto' type 'auto \\\[requires ::C1<<placeholder>, >\\\]'" }
+ C1 auto [c] = y; // { dg-error "structured binding declaration cannot have constrained 'auto' type 'auto \\\[requires ::C1<<placeholder>, >\\\]'" }
+ // { dg-error "constraints" "" { target *-*-* } .-1 }
}
template void g<int>();
@@ -27,6 +29,6 @@ struct S { int a, b; } s;
template <class T>
void h() {
- const C2<T> auto& [a, b] = s;
+ const C2<T> auto& [a, b] = s; // { dg-error "structured binding declaration cannot have constrained 'auto' type 'const auto \\\[requires ::C2<<placeholder>, >\\\]'" }
}
template void h<int>();
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder8.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder8.C
index e786592..d887961 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder8.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder8.C
@@ -5,6 +5,7 @@ template <class T> concept is_const = __is_same(T, const T);
void f() {
int x[] = {1,2};
const int y[] = {3};
- const is_const auto [a,b] = x; // { dg-error "constraints" }
- const is_const auto [c] = y;
+ const is_const auto [a,b] = x; // { dg-error "structured binding declaration cannot have constrained 'auto' type 'const auto \\\[requires ::is_const<<placeholder>, >\\\]'" }
+ // { dg-error "constraints" "" { target *-*-* } .-1 }
+ const is_const auto [c] = y; // { dg-error "structured binding declaration cannot have constrained 'auto' type 'const auto \\\[requires ::is_const<<placeholder>, >\\\]'" }
}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder9.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder9.C
new file mode 100644
index 0000000..96732f3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder9.C
@@ -0,0 +1,33 @@
+// PR c++/99899
+// { dg-do compile { target c++20 } }
+// { dg-options "-Wno-pedantic" }
+
+template <class T> concept C1 = sizeof(T) > sizeof(int[1]);
+
+template <class>
+void f() {
+ int x[] = {1,2};
+ int y[] = {3};
+ C1 auto [a,b] = x;
+ C1 auto [c] = y; // { dg-error "constraints" }
+}
+
+template <class T>
+void g() {
+ T x[] = {1,2};
+ T y[] = {3};
+ C1 auto [a,b] = x;
+ C1 auto [c] = y; // { dg-error "constraints" }
+}
+template void g<int>();
+
+
+template <class... Ts> concept C2 = sizeof...(Ts) > 1;
+
+struct S { int a, b; } s;
+
+template <class T>
+void h() {
+ const C2<T> auto& [a, b] = s;
+}
+template void h<int>();
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr65575.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr65575.C
index 3ab7c9b..bec97e9 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr65575.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr65575.C
@@ -1,6 +1,6 @@
// PR c++/65575
// { dg-do compile { target c++17_only } }
-// { dg-additional-options "-fconcepts" }
+// { dg-additional-options "-fconcepts-ts" }
template<typename T>
concept bool C = false;
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr66091.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr66091.C
index ea51e31..cd3acf7 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr66091.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr66091.C
@@ -1,6 +1,6 @@
// PR c++/66091
// { dg-do compile { target c++17_only } }
-// { dg-additional-options "-fconcepts" }
+// { dg-additional-options "-fconcepts-ts" }
template<typename T>
concept bool C1()
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr84979-2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr84979-2.C
index 75f8e40..726c90f 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr84979-2.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr84979-2.C
@@ -4,10 +4,9 @@
template <typename T>
void foo1(T& t) {
typename T::template C<void> tcv = t;
- typename T::template C<auto> u = tcv; // { dg-error "" "" { target c++20 } }
+ typename T::template C<auto> u = tcv; // { dg-error "" }
T::template C<auto>::f (tcv, u); // { dg-error "" }
(typename T::template D<auto> (t)); // { dg-error "" }
-// { dg-warning "only available" "" { target c++17_down } .-1 }
}
struct T1 {
@@ -23,7 +22,7 @@ struct T1 {
template <typename T>
void foo2(T& t) {
typename T::template C<void> tcv = t;
- typename T::template C<auto> u = tcv; // { dg-error "" "" { target c++20 } }
+ typename T::template C<auto> u = tcv; // { dg-error "" }
T::template C<auto>::f (tcv, u); // { dg-error "" }
T::template D<auto> (t); // { dg-error "" }
}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr84979-3.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr84979-3.C
index 1c1a41c..ec8ae35 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr84979-3.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr84979-3.C
@@ -8,10 +8,9 @@
template <typename T>
void foo1(T& t) {
typename T::template C<void> tcv = t;
- typename T::template C<auto> u = tcv; // { dg-error "" "" { target c++20 } }
+ typename T::template C<auto> u = tcv; // { dg-error "" }
T::template C<auto>::f (tcv, u); // { dg-error "" }
(typename T::template D<auto> (t)); // { dg-error "" }
-// { dg-warning "only available" "" { target c++17_down } .-1 }
}
struct T1 {
@@ -27,7 +26,7 @@ struct T1 {
template <typename T>
void foo2(T& t) {
typename T::template C<void> tcv = t;
- typename T::template C<auto> u = tcv; // { dg-error "" "" { target c++20 } }
+ typename T::template C<auto> u = tcv; // { dg-error "" }
T::template C<auto>::f (tcv, u); // { dg-error "" }
T::template D<auto> (t); // { dg-error "" }
}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr84980.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr84980.C
index 1703de0..635a168 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr84980.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr84980.C
@@ -1,4 +1,4 @@
// { dg-do compile { target c++17_only } }
-// { dg-additional-options "-fconcepts" }
+// { dg-additional-options "-fconcepts-ts" }
template<T> concept bool C = true; // { dg-error "has not been declared" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr85265.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr85265.C
index 96aac69..d351b45 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr85265.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr85265.C
@@ -1,6 +1,6 @@
// PR c++/85265
// { dg-do compile { target c++17_only } }
-// { dg-additional-options "-fconcepts" }
+// { dg-additional-options "-fconcepts-ts" }
template<typename> concept bool C = true;
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires31.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires31.C
new file mode 100644
index 0000000..cd26b9c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires31.C
@@ -0,0 +1,15 @@
+// PR c++/107179
+// { dg-do compile { target c++20 } }
+
+template<bool B> struct bool_constant { static constexpr bool value = B; };
+
+template<typename T>
+ struct is_implicitly_default_constructible
+ : bool_constant<requires { T(); }>
+ { };
+
+struct X { private: X(); };
+struct Y { };
+
+static_assert( !is_implicitly_default_constructible<X>::value );
+static_assert( is_implicitly_default_constructible<Y>::value );
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires32.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires32.C
new file mode 100644
index 0000000..117b892
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires32.C
@@ -0,0 +1,11 @@
+// PR c++/101733
+// { dg-do compile { target c++20 } }
+
+template<class T>
+requires requires {
+ typename T::type;
+ (typename T::type()); // (1)
+ T::type(); // (2)
+ typename T::type(); // (3)
+}
+void f(T) { }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires33.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires33.C
new file mode 100644
index 0000000..1ff237a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires33.C
@@ -0,0 +1,10 @@
+// PR c++/107417
+// { dg-do compile { target c++20 } }
+
+template<class... T>
+void f() requires (requires (T x) { true; } && ...);
+
+int main() {
+ f<int>();
+ f<int, void>(); // { dg-error "no match" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval3.C b/gcc/testsuite/g++.dg/cpp2a/consteval3.C
index 8346386..627ab14 100644
--- a/gcc/testsuite/g++.dg/cpp2a/consteval3.C
+++ b/gcc/testsuite/g++.dg/cpp2a/consteval3.C
@@ -57,7 +57,6 @@ consteval int
f13 (int x)
{
static int a = 5; // { dg-error "'a' defined 'static' in 'consteval' function only available with" "" { target c++20_only } }
- // { dg-error "'a' defined 'static' in 'constexpr' context" "" { target c++23 } .-1 }
thread_local int b = 6; // { dg-error "'b' defined 'thread_local' in 'consteval' function only available with" "" { target c++20_only } }
return x;
}
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-new7.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-new7.C
index bb60a8e..b2c9885 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constexpr-new7.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-new7.C
@@ -13,7 +13,7 @@ void *operator new (std::size_t) noexcept;
constexpr bool
foo ()
{
- auto p = static_cast<int *> (::operator new (sizeof (int))); // { dg-error "call to non-'constexpr' function" }
+ auto p = static_cast<int *> (::operator new (sizeof (int))); // { dg-error "call to non-'constexpr' function" "" { target c++20_down } }
*p = 1;
::operator delete (p);
return false;
@@ -24,7 +24,7 @@ struct S { constexpr S () : s (0) {} int s; };
constexpr bool
bar ()
{
- auto p = static_cast<S *> (::operator new (sizeof (S))); // { dg-error "call to non-'constexpr' function" }
+ auto p = static_cast<S *> (::operator new (sizeof (S))); // { dg-error "call to non-'constexpr' function" "" { target c++20_down } }
auto q = new (p) S ();
q->s++;
q->~S ();
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-try5.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-try5.C
index 216634d..eb66105 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constexpr-try5.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-try5.C
@@ -6,7 +6,6 @@ constexpr int foo ()
try { // { dg-warning "function-try-block body of 'constexpr' function only available with" "" { target c++17_down } }
int a; // { dg-error "uninitialized variable 'a' in 'constexpr' function" "" { target c++17_down } }
static double b = 1.0;// { dg-error "'b' defined 'static' in 'constexpr' function only available with" "" { target c++20_down } }
- // { dg-error "'b' defined 'static' in 'constexpr' context" "" { target c++23 } .-1 }
goto l; // { dg-error "'goto' in 'constexpr' function only available with" "" { target c++20_down } }
l:;
return 0;
@@ -22,7 +21,6 @@ constexpr int bar ()
{
int a; // { dg-error "uninitialized variable 'a' in 'constexpr' function" "" { target c++17_down } }
static long double b = 3.0;// { dg-error "'b' defined 'static' in 'constexpr' function only available with" "" { target c++20_down } }
- // { dg-error "'b' defined 'static' in 'constexpr' context" "" { target c++23 } .-1 }
goto l; // { dg-error "'goto' in 'constexpr' function only available with" "" { target c++20_down } }
l:;
try { // { dg-warning "'try' in 'constexpr' function only available with" "" { target c++17_down } }
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual21.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual21.C
new file mode 100644
index 0000000..8b70c5f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual21.C
@@ -0,0 +1,10 @@
+// PR c++/93413
+// { dg-do compile { target c++20 } }
+
+struct Base {
+ virtual ~Base() = default;
+};
+constexpr Base b;
+
+struct Derived : Base { };
+constexpr Derived d;
diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit18.C b/gcc/testsuite/g++.dg/cpp2a/constinit18.C
new file mode 100644
index 0000000..51b4f02
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constinit18.C
@@ -0,0 +1,12 @@
+// PR c++/104066
+// { dg-do compile { target c++20 } }
+
+constinit void (*p)() = nullptr;
+constinit void (*pp)() = nullptr;
+void fn();
+constinit void (&r)() = fn;
+
+extern constinit long (* const syscall_reexported) (long, ...);
+
+constinit void bad (); // { dg-error ".constinit. on function return type is not allowed" }
+constinit void bad () { } // { dg-error ".constinit. on function return type is not allowed" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/decomp5.C b/gcc/testsuite/g++.dg/cpp2a/decomp5.C
new file mode 100644
index 0000000..9ea31c6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/decomp5.C
@@ -0,0 +1,19 @@
+// CWG2635 - Constrained structured bindings
+// { dg-do compile { target c++20 } }
+
+namespace std {
+ template<typename T> struct tuple_size;
+ template<int, typename> struct tuple_element;
+}
+
+struct A {
+ int i;
+ A(int x) : i(x) {}
+ template <int I> int& get() { return i; }
+};
+
+template<> struct std::tuple_size<A> { static const int value = 2; };
+template<int I> struct std::tuple_element<I,A> { using type = int; };
+
+template<class T> concept C = true;
+C auto [x, y] = A{1}; // { dg-error "structured binding declaration cannot have constrained 'auto' type 'auto \\\[requires ::C<<placeholder>, >\\\]'" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/decomp6.C b/gcc/testsuite/g++.dg/cpp2a/decomp6.C
new file mode 100644
index 0000000..e6cd034
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/decomp6.C
@@ -0,0 +1,20 @@
+// CWG2635 - Constrained structured bindings
+// { dg-do compile { target c++20 } }
+// { dg-options "-pedantic" }
+
+namespace std {
+ template<typename T> struct tuple_size;
+ template<int, typename> struct tuple_element;
+}
+
+struct A {
+ int i;
+ A(int x) : i(x) {}
+ template <int I> int& get() { return i; }
+};
+
+template<> struct std::tuple_size<A> { static const int value = 2; };
+template<int I> struct std::tuple_element<I,A> { using type = int; };
+
+template<class T> concept C = true;
+C auto [x, y] = A{1}; // { dg-warning "structured binding declaration cannot have constrained 'auto' type 'auto \\\[requires ::C<<placeholder>, >\\\]'" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/decomp7.C b/gcc/testsuite/g++.dg/cpp2a/decomp7.C
new file mode 100644
index 0000000..581797e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/decomp7.C
@@ -0,0 +1,20 @@
+// CWG2635 - Constrained structured bindings
+// { dg-do compile { target c++20 } }
+// { dg-options "-Wno-pedantic" }
+
+namespace std {
+ template<typename T> struct tuple_size;
+ template<int, typename> struct tuple_element;
+}
+
+struct A {
+ int i;
+ A(int x) : i(x) {}
+ template <int I> int& get() { return i; }
+};
+
+template<> struct std::tuple_size<A> { static const int value = 2; };
+template<int I> struct std::tuple_element<I,A> { using type = int; };
+
+template<class T> concept C = true;
+C auto [x, y] = A{1}; // { dg-bogus "structured binding declaration cannot have constrained 'auto' type 'auto \\\[requires ::C<<placeholder>, >\\\]'" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C b/gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C
index c548587..8f48ba8 100644
--- a/gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C
+++ b/gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C
@@ -55,10 +55,10 @@ static_assert (!std::is_layout_compatible_v<K, L>);
static_assert (!std::is_layout_compatible_v<M, N>);
static_assert (!std::is_layout_compatible_v<O, P>);
static_assert (!std::is_layout_compatible_v<P, D>);
-static_assert (!std::is_layout_compatible_v<Q, R>);
+static_assert (std::is_layout_compatible_v<Q, R>);
static_assert (!std::is_layout_compatible_v<U, V>);
static_assert (!std::is_layout_compatible_v<A, I>);
static_assert (!std::is_layout_compatible_v<C, I>);
-static_assert (std::is_layout_compatible_v<E, F>);
+static_assert (!std::is_layout_compatible_v<E, F>);
static_assert (std::is_layout_compatible_v<G, H>);
static_assert (std::is_layout_compatible_v<C1, D1>);
diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr1.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr1.C
index dff5927..fb62ecb 100644
--- a/gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr1.C
@@ -9,7 +9,7 @@ struct A
struct B
{
A a;
- bool operator==(const B&) const = default; // { dg-error "A::operator==" "" { target { ! implicit_constexpr } } }
+ bool operator==(const B&) const = default; // { dg-error "A::operator==" "" { target { { ! implicit_constexpr } && c++20_down } } }
};
constexpr bool x = B() == B(); // { dg-error "non-.constexpr" "" { target { ! implicit_constexpr } } }
diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq15.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq15.C
new file mode 100644
index 0000000..dc50956
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq15.C
@@ -0,0 +1,208 @@
+// P2468R2 - The Equality Operator You Are Looking For
+// { dg-do compile { target c++20 } }
+
+struct A {
+ bool operator== (const A &) { return true; }
+ bool operator!= (const A &) { return false; }
+};
+bool a = A{} != A{};
+
+template <typename T>
+struct B {
+ bool operator== (const T &) const;
+ bool operator!= (const T &) const;
+};
+struct B1 : B<B1> { };
+bool b1 = B1{} == B1{};
+bool b2 = B1{} != B1{};
+
+template <bool>
+struct C {
+ using C1 = C<true>;
+ using C2 = C<false>;
+ C () = default;
+ C (const C2 &);
+ bool operator== (C1) const;
+ bool operator!= (C1) const;
+};
+using C3 = C<false>;
+bool c = C3{} == C3{};
+
+struct D {
+ D ();
+ D (int *);
+ bool operator== (const D &) const; // { dg-message "candidate: 'bool D::operator==\\\(const D&\\\) const' \\\(reversed\\\)" }
+ operator int * () const;
+};
+bool d = nullptr != D{}; // { dg-error "ambiguous overload for 'operator!=' in 'nullptr != D\\\(\\\)' \\\(operand types are 'std::nullptr_t' and 'D'\\\)" }
+ // { dg-message "candidate: 'operator!=\\\(int\\\*, int\\\*\\\)' \\\(built-in\\\)" "" { target *-*-* } .-1 }
+
+using ubool = unsigned char;
+
+struct E {
+ operator bool () const;
+};
+unsigned char operator== (E, E);// { dg-message "candidate: 'unsigned char operator==\\\(E, E\\\)'" }
+ // { dg-message "no known conversion for argument 1 from 'int' to 'E'" "" { target *-*-* } .-1 }
+unsigned char e = E{} != E{}; // { dg-error "return type of 'unsigned char operator==\\\(E, E\\\)' is not 'bool'" }
+ // { dg-message "used as rewritten candidate for comparison of 'E' and 'E'" "" { target *-*-* } .-1 }
+
+// F-H are the testcase from [over.match.oper]
+struct F {};
+template <typename T>
+bool operator== (F, T); // { dg-message "candidate: 'template<class T> bool operator==\\\(F, T\\\)'" }
+ // { dg-message "template argument deduction/substitution failed:" "" { target *-*-* } .-1 }
+bool f1 = 0 == F (); // OK, calls reversed ==
+template <typename T>
+bool operator!= (F, T);
+bool f2 = 0 == F (); // { dg-error "no match for 'operator==' in '0 == F\\\(\\\)' \\\(operand types are 'int' and 'F'\\\)" }
+ // { dg-message "cannot convert '0' \\\(type 'int'\\\) to type 'F'" "" { target *-*-* } .-1 }
+
+struct G {
+ bool operator== (const G &);
+};
+struct G1 : G {
+ G1 ();
+ G1 (G);
+ bool operator!= (const G &);
+};
+bool g1 = G () == G1 (); // OK, != prevents rewrite
+bool g2 = G1 () == G (); // { dg-error "ambiguous, even though the second is reversed" }
+
+struct H {};
+template <typename T>
+bool operator== (H, T);
+inline namespace H1 {
+ template <typename T>
+ bool operator!= (H, T);
+}
+// [over.match.oper] currently says that this is OK because the inline
+// namespace isn't searched, but that seems wrong to me, so I'm going to go
+// ahead and search it for now. Remove the "0 &&" in add_candidates to
+// change this to the currently specified behavior.
+// { dg-error "no match" "" { target *-*-* } .+1 }
+bool h = 0 == H (); // OK, calls reversed ==
+
+template <class T>
+struct I {
+ int operator== (const double &) const;
+ friend inline int operator== (const double &, const T &) { return 1; }
+};
+struct I1 : I<I1> { };
+bool i = I1{} == 0.; // { dg-error "return type of 'int operator==\\\(const double&, const I1&\\\)' is not 'bool'" }
+ // { dg-message "used as rewritten candidate for comparison of 'I1' and 'double'" "" { target *-*-* } .-1 }
+
+struct J {
+ bool operator== (const J &) const;
+ bool operator!= (const J &) const;
+};
+struct J1 : J {
+ J1 (const J &);
+ bool operator== (const J1 &x) const {
+ return static_cast<const J &> (*this) == x; // { dg-error "ambiguous overload for 'operator==' in '\\\*\\\(const J\\\*\\\)\\\(\\\(const J1\\\*\\\)this\\\) == x' \\\(operand types are 'const J' and 'const J1'\\\)" }
+ }
+};
+
+struct K {
+ bool operator== (const K &);
+};
+bool k = K{} == K{}; // { dg-error "ambiguous, even though the second is reversed" }
+
+struct L {
+ bool operator== (const L &) const;
+};
+bool l = L{} == L{};
+
+struct M {
+ bool operator== (M);
+};
+bool m = M () == M ();
+
+struct N {
+ virtual bool operator== (const N &) const;
+};
+struct N1 : N {
+ bool operator== (const N &) const override;
+};
+bool n = N1 () == N1 (); // { dg-error "ambiguous, even though the second is reversed" }
+
+struct O {
+ virtual signed char operator== (const O &) const;
+ signed char operator!= (const O &x) const { return !operator== (x); }
+};
+struct O1 : O {
+ signed char operator== (const O &) const override;
+};
+bool o = O1 () != O1 ();
+
+template <class T>
+bool
+foo (T x, T y)
+requires requires { x == y; }
+{
+ return x == y;
+}
+bool b3 = foo (B1 (), B1 ());
+
+struct P {};
+template <typename T, class U = int>
+bool operator== (P, T);
+template <class T>
+bool operator!= (P, T);
+bool p = 0 == P ();
+
+struct Q {};
+template <typename T>
+bool operator== (Q, T);
+template <typename U>
+bool operator!= (Q, U);
+bool q = 0 == Q (); // { dg-error "" }
+
+struct R {
+ template <typename T>
+ bool operator== (const T &);
+};
+bool r = R () == R (); // { dg-error "ambiguous, even though the second is reversed" }
+
+struct S {
+ template <typename T>
+ bool operator== (const T &) const;
+ bool operator!= (const S &);
+};
+bool s = S () == S ();
+
+struct T {};
+template <class U = int>
+bool operator== (T, int);
+bool operator!= (T, int);
+bool t = 0 == T ();
+
+struct U {};
+bool operator== (U, int);
+bool u1 = 0 == U ();
+namespace U1 { bool operator!= (U, int); }
+bool u2 = 0 == U ();
+using U1::operator!=;
+bool u3 = 0 == U (); // { dg-error "" }
+
+struct V {};
+template <typename T>
+bool operator== (V, T);
+bool v1 = 0 == V ();
+namespace V1 { template <typename T> bool operator!= (V, T); }
+bool v2 = 0 == V ();
+using V1::operator!=;
+bool v3 = 0 == V (); // { dg-error "" }
+
+template <int N>
+struct W {
+bool operator== (int) requires (N == 1);
+bool operator!= (int) requires (N == 2);
+};
+int w = 0 == W<1> ();
+
+struct X {
+ bool operator== (X const &);
+ static bool operator!= (X const &, X const &); // { dg-error "'static bool X::operator!=\\\(const X&, const X&\\\)' must be either a non-static member function or a non-member function" }
+};
+bool x = X () == X (); // { dg-error "ambiguous, even though the second is reversed" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C
index 7a517a8..246839f 100644
--- a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C
+++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C
@@ -7,8 +7,9 @@ struct A {
struct D
{
A i;
- bool operator==(const D& x) const = default; // { dg-error "A::operator==" }
- bool operator!=(const D& z) const = default; // { dg-error "D::operator==" }
+ bool operator==(const D& x) const = default; // { dg-error "A::operator==" "" { target c++20_down } }
+ bool operator!=(const D& z) const = default; // { dg-error "D::operator==" "" { target c++20_down } }
+// { dg-error "called" "" { target { c++23 && implicit_constexpr } } .-1 }
};
constexpr D d{A()};
diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite1.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite1.C
index c4030cd..ebe81e4 100644
--- a/gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite1.C
@@ -11,5 +11,5 @@ int main()
{
A<int> a1;
A<void> a2;
- return a1 == a2;
+ return a1 == a2; // { dg-error "ambiguous, even though the second is reversed" }
}
diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite5.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite5.C
index d042437..460f633 100644
--- a/gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite5.C
+++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite5.C
@@ -12,4 +12,4 @@ struct A {
A<const int> a;
A<int> b;
-auto c = (a == b);
+auto c = (a == b); // { dg-error "ambiguous, even though the second is reversed" "" { target c++20 } }
diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-sfinae2.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-sfinae2.C
new file mode 100644
index 0000000..7105a2c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-sfinae2.C
@@ -0,0 +1,29 @@
+// PR c++/107542
+// { dg-do compile { target c++20 } }
+
+#include <compare>
+
+template<class T, class U>
+concept same_as = __is_same(T, U);
+
+template<class Lhs, class Rhs>
+concept Ord = requires(Lhs lhs, Rhs rhs) {
+ { lhs <=> rhs } -> same_as<std::strong_ordering>;
+};
+
+static_assert(Ord<int*, int*>); // Works.
+static_assert(!Ord<int*, char*>); // ICE.
+
+template<class T>
+struct S {
+ T* p;
+};
+
+template<class T, class U>
+ requires(Ord<const T*, const U*>)
+constexpr inline auto operator<=>(const S<T>& l, const S<U>& r) noexcept {
+ return l.p <=> r.p;
+}
+
+static_assert(Ord<S<int>, S<int>>); // Works.
+static_assert(!Ord<S<int>, S<char>>); // ICE.
diff --git a/gcc/testsuite/g++.dg/cpp2a/using-enum-10.C b/gcc/testsuite/g++.dg/cpp2a/using-enum-10.C
new file mode 100644
index 0000000..98fe064
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/using-enum-10.C
@@ -0,0 +1,16 @@
+// PR c++/103081
+// { dg-do compile { target c++20 } }
+
+enum class Pig { OINK };
+
+struct Hog {
+ using enum Pig;
+ Hog(Pig) { }
+};
+
+template<int>
+void pen() {
+ Hog(Hog::OINK);
+}
+
+template void pen<0>();
diff --git a/gcc/testsuite/g++.dg/cpp2a/using-enum-10a.C b/gcc/testsuite/g++.dg/cpp2a/using-enum-10a.C
new file mode 100644
index 0000000..daa3221
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/using-enum-10a.C
@@ -0,0 +1,19 @@
+// A version of using-enum-10.C where Hog is a template.
+// PR c++/103081
+// { dg-do compile { target c++20 } }
+
+enum class Pig { OINK };
+
+template<int>
+struct Hog {
+ using enum Pig;
+ Hog(Pig) { OINK; }
+};
+
+template<int N>
+void pen() {
+ Hog<1>(Hog<1>::OINK);
+ Hog<N>(Hog<N>::OINK);
+}
+
+template void pen<0>();
diff --git a/gcc/testsuite/g++.dg/cpp2a/volatile1.C b/gcc/testsuite/g++.dg/cpp2a/volatile1.C
index a0264a4..fc9d5e0 100644
--- a/gcc/testsuite/g++.dg/cpp2a/volatile1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/volatile1.C
@@ -74,17 +74,17 @@ fn2 ()
decltype(i = vi = 42) x3 = i;
// Compound assignments.
- vi += i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++20 } }
- vi -= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++20 } }
- vi %= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++20 } }
+ vi += i; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
+ vi -= i; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
+ vi %= i; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
vi ^= i; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
vi |= i; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
vi &= i; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
- vi /= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++20 } }
+ vi /= i; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
vi = vi += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++20 } }
vi += vi = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++20 } }
i *= vi;
- decltype(vi -= 42) x2 = vi; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++20 } }
+ decltype(vi -= 42) x2 = vi; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
// Structured bindings.
int a[] = { 10, 5 };
@@ -107,12 +107,12 @@ fn3 ()
volatile U u;
u.c = 42;
i = u.c = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++20 } }
- u.c += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++20 } }
+ u.c += 42; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
volatile T t;
t.a = 3;
j = t.a = 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++20 } }
- t.a += 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++20 } }
+ t.a += 3; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
volatile int *src = &i;
*src; // No assignment, don't warn.
@@ -135,7 +135,7 @@ void raccoon ()
volatile T t, u;
t = 42;
u = t = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++20 } }
- t += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++20 } }
+ t += 42; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
t &= 42; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
}
diff --git a/gcc/testsuite/g++.dg/cpp2a/volatile3.C b/gcc/testsuite/g++.dg/cpp2a/volatile3.C
index 58816dc..9f1a8dc 100644
--- a/gcc/testsuite/g++.dg/cpp2a/volatile3.C
+++ b/gcc/testsuite/g++.dg/cpp2a/volatile3.C
@@ -75,17 +75,17 @@ fn2 ()
decltype(i = vi = 42) x3 = i;
// Compound assignments.
- vi += i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
- vi -= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
- vi %= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
+ vi += i; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
+ vi -= i; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
+ vi %= i; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
vi ^= i; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
vi |= i; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
vi &= i; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
- vi /= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
+ vi /= i; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
vi = vi += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
vi += vi = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
i *= vi;
- decltype(vi -= 42) x2 = vi; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
+ decltype(vi -= 42) x2 = vi; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
// Structured bindings.
int a[] = { 10, 5 };
@@ -108,12 +108,12 @@ fn3 ()
volatile U u;
u.c = 42;
i = u.c = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
- u.c += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
+ u.c += 42; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
volatile T t;
t.a = 3;
j = t.a = 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
- t.a += 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
+ t.a += 3; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
volatile int *src = &i;
*src; // No assignment, don't warn.
@@ -136,7 +136,7 @@ void raccoon ()
volatile T t, u;
t = 42;
u = t = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
- t += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
+ t += 42; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
t &= 42; // { dg-bogus "assignment with .volatile.-qualified left operand is deprecated" }
}
diff --git a/gcc/testsuite/g++.dg/cpp2a/volatile5.C b/gcc/testsuite/g++.dg/cpp2a/volatile5.C
index 3684be9..291b9bc 100644
--- a/gcc/testsuite/g++.dg/cpp2a/volatile5.C
+++ b/gcc/testsuite/g++.dg/cpp2a/volatile5.C
@@ -7,7 +7,7 @@ void
f (bool b)
{
(b ? x : y) = 1;
- (b ? x : y) += 1; // { dg-warning "compound assignment" "" { target c++20 } }
+ (b ? x : y) += 1; // { dg-bogus "compound assignment" }
z = (b ? x : y) = 1; // { dg-warning "using value of assignment" "" { target c++20 } }
((z = 2) ? x : y) = 1; // { dg-warning "using value of assignment" "" { target c++20 } }
(b ? (x = 2) : y) = 1; // { dg-warning "using value of assignment" "" { target c++20 } }
diff --git a/gcc/testsuite/g++.dg/diagnostic/constexpr1.C b/gcc/testsuite/g++.dg/diagnostic/constexpr1.C
index c962a60..19242d1 100644
--- a/gcc/testsuite/g++.dg/diagnostic/constexpr1.C
+++ b/gcc/testsuite/g++.dg/diagnostic/constexpr1.C
@@ -1,7 +1,5 @@
// { dg-do compile { target c++11 } }
constexpr int foo() { thread_local int i __attribute__((unused)) {}; return 1; } // { dg-error "40:.i. defined .thread_local." "" { target c++20_down } }
-// { dg-error "40:.i. defined .thread_local. in .constexpr. context" "" { target c++23 } .-1 }
constexpr int bar() { static int i __attribute__((unused)) {}; return 1; } // { dg-error "34:.i. defined .static." "" { target c++20_down } }
-// { dg-error "34:.i. defined .static. in .constexpr. context" "" { target c++23 } .-1 }
diff --git a/gcc/testsuite/g++.dg/diagnostic/return-type-loc1.C b/gcc/testsuite/g++.dg/diagnostic/return-type-loc1.C
new file mode 100644
index 0000000..f96179e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/return-type-loc1.C
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++11 } }
+// { dg-additional-options -Waggregate-return }
+
+struct B { int i,j; };
+
+template <class T>
+struct A
+{
+ template <class U>
+ U // { dg-warning "aggregate" }
+ f() { return {}; }
+};
+
+int main()
+{
+ A<int>().f<B>(); // { dg-warning "aggregate" }
+}
+
+B // { dg-warning "aggregate" }
+g() { return {}; }
diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr19.C b/gcc/testsuite/g++.dg/ext/stmtexpr19.C
index 0c19a21..be395b6 100644
--- a/gcc/testsuite/g++.dg/ext/stmtexpr19.C
+++ b/gcc/testsuite/g++.dg/ext/stmtexpr19.C
@@ -8,7 +8,7 @@ const test* setup()
{
static constexpr test atest =
{
- ({ static const int inner = 123; &inner; }) // { dg-error "static" }
+ ({ static const int inner = 123; &inner; })
};
return &atest;
diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr25.C b/gcc/testsuite/g++.dg/ext/stmtexpr25.C
new file mode 100644
index 0000000..79c40fc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/stmtexpr25.C
@@ -0,0 +1,17 @@
+// PR c++/81073
+// { dg-options "" }
+// { dg-do compile { target c++11 } }
+
+struct test { const int *addr; };
+
+const test* setup()
+{
+ static constexpr test atest =
+ {
+ ({ static const int inner = (throw 1, 1); &inner; }) // { dg-error "static" "" }
+ };
+
+ return &atest;
+}
+
+int main(){}
diff --git a/gcc/testsuite/g++.dg/ext/vector25.C b/gcc/testsuite/g++.dg/ext/vector25.C
index 339865d..71eaac5 100644
--- a/gcc/testsuite/g++.dg/ext/vector25.C
+++ b/gcc/testsuite/g++.dg/ext/vector25.C
@@ -2,5 +2,5 @@ volatile int i __attribute__((vector_size(8)));
void foo()
{
- i += i; // { dg-warning "deprecated" "" { target c++2a } }
+ i += i; // { dg-bogus "deprecated" }
}
diff --git a/gcc/testsuite/g++.dg/gcov/gcov.exp b/gcc/testsuite/g++.dg/gcov/gcov.exp
index 04e7a01..def827d 100644
--- a/gcc/testsuite/g++.dg/gcov/gcov.exp
+++ b/gcc/testsuite/g++.dg/gcov/gcov.exp
@@ -24,9 +24,9 @@ global GXX_UNDER_TEST
# Find gcov in the same directory as $GXX_UNDER_TEST.
if { ![is_remote host] && [string match "*/*" [lindex $GXX_UNDER_TEST 0]] } {
- set GCOV [file dirname [lindex $GXX_UNDER_TEST 0]]/[transform gcov]
+ set GCOV [file dirname [lindex $GXX_UNDER_TEST 0]]/[gcc-transform-out-of-tree gcov]
} else {
- set GCOV [transform gcov]
+ set GCOV [gcc-transform-out-of-tree gcov]
}
# Initialize harness.
diff --git a/gcc/testsuite/g++.dg/gomp/for-21.C b/gcc/testsuite/g++.dg/gomp/for-21.C
index fbdaa71..f5a7bf7 100644
--- a/gcc/testsuite/g++.dg/gomp/for-21.C
+++ b/gcc/testsuite/g++.dg/gomp/for-21.C
@@ -24,9 +24,9 @@ void
f3 (S (&a)[10])
{
#pragma omp for collapse (2)
- for (auto [i, j, k] : a) // { dg-error "use of 'i' before deduction of 'auto'" "" { target *-*-* } .+1 }
- for (int l = i; l < j; l += k) // { dg-error "use of 'j' before deduction of 'auto'" }
- ; // { dg-error "use of 'k' before deduction of 'auto'" "" { target *-*-* } .-1 }
+ for (auto [i, j, k] : a) // { dg-error "initializer expression refers to iteration variable 'i'" }
+ for (int l = i; l < j; l += k) // { dg-error "condition expression refers to iteration variable 'j'" }
+ ; // { dg-error "increment expression refers to iteration variable 'k'" "" { target *-*-* } .-2 }
}
template <int N>
@@ -54,9 +54,9 @@ void
f6 (S (&a)[10])
{
#pragma omp for collapse (2)
- for (auto [i, j, k] : a) // { dg-error "use of 'i' before deduction of 'auto'" "" { target *-*-* } .-1 }
- for (int l = i; l < j; l += k) // { dg-error "use of 'j' before deduction of 'auto'" }
- ; // { dg-error "use of 'k' before deduction of 'auto'" "" { target *-*-* } .-3 }
+ for (auto [i, j, k] : a) // { dg-error "initializer expression refers to iteration variable 'i'" "" { target *-*-* } .-1 }
+ for (int l = i; l < j; l += k) // { dg-error "condition expression refers to iteration variable 'j'" }
+ ; // { dg-error "increment expression refers to iteration variable 'k'" "" { target *-*-* } .-3 }
}
template <typename T>
@@ -84,9 +84,9 @@ void
f9 (U (&a)[10])
{
#pragma omp for collapse (2)
- for (auto [i, j, k] : a) // { dg-error "use of 'i' before deduction of 'auto'" "" { target *-*-* } .-1 }
- for (T l = i; l < j; l += k) // { dg-error "use of 'j' before deduction of 'auto'" }
- ; // { dg-error "use of 'k' before deduction of 'auto'" "" { target *-*-* } .-3 }
+ for (auto [i, j, k] : a) // { dg-error "initializer expression refers to iteration variable 'i'" "" { target *-*-* } .-1 }
+ for (T l = i; l < j; l += k) // { dg-error "condition expression refers to iteration variable 'j'" }
+ ; // { dg-error "increment expression refers to iteration variable 'k'" "" { target *-*-* } .-3 }
}
void
diff --git a/gcc/testsuite/g++.dg/gomp/for-22.C b/gcc/testsuite/g++.dg/gomp/for-22.C
new file mode 100644
index 0000000..40802a0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/for-22.C
@@ -0,0 +1,57 @@
+// { dg-do compile { target c++17 } }
+
+namespace std {
+ template<typename T> struct tuple_size;
+ template<int, typename> struct tuple_element;
+}
+
+struct A {
+ int i;
+ template <int I> int& get() { return i; }
+};
+
+template<> struct std::tuple_size<A> { static const int value = 3; };
+template<int I> struct std::tuple_element<I,A> { using type = int; };
+
+struct B {
+ A *begin();
+ A *end();
+};
+
+void
+f1 (B a)
+{
+ #pragma omp for collapse (2)
+ for (auto [i, j, k] : a) // { dg-error "initializer expression refers to iteration variable 'i'" "" { target *-*-* } .+1 }
+ for (int l = i; l < j; l += k) // { dg-error "condition expression refers to iteration variable 'j'" }
+ ; // { dg-error "increment expression refers to iteration variable 'k'" "" { target *-*-* } .-1 }
+}
+
+template <int N>
+void
+f2 (B a)
+{
+ #pragma omp for collapse (2)
+ for (auto [i, j, k] : a) // { dg-error "initializer expression refers to iteration variable 'i'" "" { target *-*-* } .-1 }
+ for (int l = i; l < j; l += k) // { dg-error "condition expression refers to iteration variable 'j'" }
+ ; // { dg-error "increment expression refers to iteration variable 'k'" "" { target *-*-* } .-3 }
+}
+
+template <typename T>
+void
+f3 (T a)
+{
+ #pragma omp for collapse (2)
+ for (auto [i, j, k] : a) // { dg-error "initializer expression refers to iteration variable 'i'" "" { target *-*-* } .-1 }
+ for (int l = i; l < j; l += k) // { dg-error "condition expression refers to iteration variable 'j'" }
+ ; // { dg-error "increment expression refers to iteration variable 'k'" "" { target *-*-* } .-3 }
+}
+
+void
+test ()
+{
+ B b;
+ f1 (b);
+ f2 <0> (b);
+ f3 <B> (b);
+}
diff --git a/gcc/testsuite/g++.dg/gomp/pr79664.C b/gcc/testsuite/g++.dg/gomp/pr79664.C
index 582eedb..f4c30c0 100644
--- a/gcc/testsuite/g++.dg/gomp/pr79664.C
+++ b/gcc/testsuite/g++.dg/gomp/pr79664.C
@@ -1,6 +1,6 @@
// PR c++/79664
// { dg-do compile }
-// { dg-options "-std=c++14 -fopenmp" }
+// { dg-options "-std=c++14 -fopenmp -Winvalid-constexpr -pedantic-errors" }
constexpr int
f1 ()
diff --git a/gcc/testsuite/g++.dg/gomp/pr84469.C b/gcc/testsuite/g++.dg/gomp/pr84469.C
new file mode 100644
index 0000000..973debf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/pr84469.C
@@ -0,0 +1,24 @@
+// PR c++/84469
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct A {
+ template <typename T>
+ void bar () const {}
+};
+
+template <typename>
+void
+foo ()
+{
+ A a[1][1];
+ #pragma omp for
+ for (auto const& [b]: a) // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ b.bar<int> ();
+}
+
+int
+main ()
+{
+ foo<int> ();
+}
diff --git a/gcc/testsuite/g++.dg/gomp/target-simd-clone-1.C b/gcc/testsuite/g++.dg/gomp/target-simd-clone-1.C
new file mode 100644
index 0000000..10b5ac3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/target-simd-clone-1.C
@@ -0,0 +1,25 @@
+/* { dg-options "-fopenmp -O2" } */
+/* { dg-additional-options "-fopenmp-target-simd-clone=any -fdump-ipa-simdclone-details" } */
+
+/* Test that simd clones are generated for functions with "declare target". */
+
+#pragma omp declare target
+__attribute__ ((__noinline__)) int addit (int a, int b)
+{
+ return a + b;
+}
+#pragma omp end declare target
+
+void callit (int *a, int *b, int *c)
+{
+ int i;
+ #pragma omp for simd
+ for (i = 0; i < 16; i++)
+ c[i] = addit (a[i], b[i]);
+}
+
+/* Although addit has external linkage, we expect clones to be generated as
+ for a function with internal linkage. */
+
+/* { dg-final { scan-ipa-dump "Generated local clone _ZGV.*N.*__Z5additii" "simdclone" { target x86_64-*-* } } } */
+/* { dg-final { scan-ipa-dump "Generated local clone _ZGV.*M.*__Z5additii" "simdclone" { target x86_64-*-* } } } */
diff --git a/gcc/testsuite/g++.dg/gomp/target-simd-clone-2.C b/gcc/testsuite/g++.dg/gomp/target-simd-clone-2.C
new file mode 100644
index 0000000..08c0539
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/target-simd-clone-2.C
@@ -0,0 +1,23 @@
+/* { dg-options "-fopenmp -O2" } */
+/* { dg-additional-options "-fopenmp-target-simd-clone=any -fdump-ipa-simdclone-details" } */
+
+/* Test that simd clones are not generated for "declare target"
+ functions that throw. */
+
+#pragma omp declare target
+__attribute__ ((__noinline__)) int addit (int a, int b)
+{
+ if (a < 0) throw -1;
+ return a + b;
+}
+#pragma omp end declare target
+
+void callit (int *a, int *b, int *c)
+{
+ int i;
+ #pragma omp for simd
+ for (i = 0; i < 16; i++)
+ c[i] = addit (a[i], b[i]);
+}
+
+/* { dg-final { scan-ipa-dump-not "Generated .* clone" "simdclone" { target x86_64-*-* } } } */
diff --git a/gcc/testsuite/g++.dg/gomp/target-teams-1.C b/gcc/testsuite/g++.dg/gomp/target-teams-1.C
index f78a608..29e5597 100644
--- a/gcc/testsuite/g++.dg/gomp/target-teams-1.C
+++ b/gcc/testsuite/g++.dg/gomp/target-teams-1.C
@@ -88,5 +88,5 @@ foo (int a, int b, long c, long d)
/* { dg-final { scan-tree-dump-times "thread_limit\\(-1\\)" 3 "gimple" } } */
/* { dg-final { scan-tree-dump-times "num_teams\\(0\\)" 4 "gimple" } } */
/* { dg-final { scan-tree-dump-times "thread_limit\\(0\\)" 6 "gimple" } } */
-/* { dg-final { scan-tree-dump-times "num_teams\\(1\\)" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "num_teams\\(-2\\)" 2 "gimple" } } */
/* { dg-final { scan-tree-dump-times "thread_limit\\(1\\)" 0 "gimple" } } */
diff --git a/gcc/testsuite/g++.dg/guality/guality.exp b/gcc/testsuite/g++.dg/guality/guality.exp
index 1d5b65f..2d736d2 100644
--- a/gcc/testsuite/g++.dg/guality/guality.exp
+++ b/gcc/testsuite/g++.dg/guality/guality.exp
@@ -8,6 +8,10 @@ if { [istarget *-*-darwin*] } {
return
}
+if { [istarget hppa*-*-hpux*] } {
+ return
+}
+
if { [istarget "powerpc-ibm-aix*"] } {
set torture_execute_xfail "powerpc-ibm-aix*"
return
diff --git a/gcc/testsuite/g++.dg/ipa/pr107661.C b/gcc/testsuite/g++.dg/ipa/pr107661.C
new file mode 100644
index 0000000..cc6f853
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr107661.C
@@ -0,0 +1,45 @@
+/* { dg-do run { target c++11 } } */
+/* { dg-options "-O1 -fipa-cp -fipa-cp-clone" } */
+
+struct R {} RGood;
+struct L {} LBad;
+
+volatile int vi;
+static void __attribute__((noipa)) L_run(void) { vi = 0; __builtin_abort (); }
+static void callback_fn_L(void) { vi = 1; L_run(); }
+static void callback_fn_R(void) { vi = 2; }
+
+struct function_ref {
+ void (*callback)(void) = nullptr;
+
+ function_ref(L * pl) { callback = callback_fn_L; }
+ function_ref(R * pr) { callback = callback_fn_R; }
+};
+
+// allow one level of recursion to call callback twice
+static int is_recur(void) {
+ static int n = 0;
+ switch (n++) {
+ case 0: return 1;
+ default: return 0;
+ }
+}
+
+static void do3(volatile int * punused, function_ref Expired) {
+ Expired.callback();
+
+ if (is_recur())
+ do3(punused, Expired);
+}
+
+static void do1(function_ref Expired) {
+ volatile int unused = 42;
+
+ do3(&unused, Expired);
+}
+
+int main(int, const char **) { do1(&RGood); return 0; }
+
+void seemingly_unused_foo(void) { do1(&LBad); }
+
+void (*fnptr)(void) = seemingly_unused_foo;
diff --git a/gcc/testsuite/g++.dg/modules/bad-mapper-3.C b/gcc/testsuite/g++.dg/modules/bad-mapper-3.C
index 9dab332..ab14dd3 100644
--- a/gcc/testsuite/g++.dg/modules/bad-mapper-3.C
+++ b/gcc/testsuite/g++.dg/modules/bad-mapper-3.C
@@ -1,6 +1,6 @@
// { dg-additional-options "-fmodules-ts -fmodule-mapper=localhost:172477262" }
import unique3.bob;
-// { dg-error {failed connecting mapper 'localhost:172477262'} "" { target *-*-* } 0 }
+// { dg-error {failed (connecting|disabled) mapper 'localhost:172477262'} "" { target *-*-* } 0 }
// { dg-prune-output "fatal error:" }
// { dg-prune-output "failed to read" }
// { dg-prune-output "compilation terminated" }
diff --git a/gcc/testsuite/g++.dg/modules/contracts-1_a.C b/gcc/testsuite/g++.dg/modules/contracts-1_a.C
new file mode 100644
index 0000000..f991ef8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/contracts-1_a.C
@@ -0,0 +1,46 @@
+// Basic test to ensure that guarded templates correctly serialize and
+// deserialize their contracts through the CMI.
+// { dg-additional-options "-fmodules-ts -fcontracts -fcontract-continuation-mode=on" }
+module;
+#include <cstdio>
+#include <experimental/contract>
+export module foo;
+// { dg-module-cmi foo }
+
+export int violation_count{0};
+extern "C++" export void handle_contract_violation(const std::experimental::contract_violation &violation)
+{
+ violation_count++;
+ printf("violation_count: %d\n", violation_count);
+}
+
+export int nontemplate(int n)
+ [[ pre: n > 0 ]]
+ [[ post r: r > 0 ]]
+{
+ return -n;
+}
+
+export
+template<typename T>
+T fn(T n)
+ [[ pre: n > 0 ]]
+ [[ post r: r > 0 ]]
+{
+ printf("%s(%d)\n", __FUNCTION__, n);
+ return n;
+}
+
+export
+template<typename T>
+void void_fn(T n)
+ [[ pre: n < 0 ]]
+{
+ printf("%s(%d)\n", __FUNCTION__, n);
+}
+
+export void foo_fn()
+{
+ fn(5);
+}
+
diff --git a/gcc/testsuite/g++.dg/modules/contracts-1_b.C b/gcc/testsuite/g++.dg/modules/contracts-1_b.C
new file mode 100644
index 0000000..30c15f6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/contracts-1_b.C
@@ -0,0 +1,33 @@
+// { dg-module-do run }
+// { dg-additional-options "-fmodules-ts -fcontracts -fcontract-continuation-mode=on" }
+module;
+#include <cstdio>
+export module bar;
+// { dg-module-cmi bar }
+import foo;
+
+template<typename T>
+bool bar_fn_pre(T n) { printf("bar fn pre(%d)\n", n); return true; }
+
+export
+template<typename T>
+T bar_fn(T n)
+ [[ pre: bar_fn_pre(n) && n > 0 ]]
+{
+ printf("%s(%d)\n", __FUNCTION__, n);
+ return n;
+}
+
+int main(int, char**)
+{
+ nontemplate(5);
+ nontemplate(-5);
+ fn(5);
+ fn(-5);
+ void_fn(5);
+ void_fn(-5);
+ bar_fn(5);
+ bar_fn(-5);
+ return violation_count == 6 ? 0 : -1;
+}
+
diff --git a/gcc/testsuite/g++.dg/modules/contracts-2_a.C b/gcc/testsuite/g++.dg/modules/contracts-2_a.C
new file mode 100644
index 0000000..828d680
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/contracts-2_a.C
@@ -0,0 +1,49 @@
+// Basic test to ensure that guarded function contracts are correctly
+// serialized and deserialized through the CMI.
+// This also tries to ensure that entities referenced in a function's
+// contracts are correctly marked as a dependency of the function itself and
+// serialized in the correct order.
+// { dg-additional-options "-fmodules-ts -fcontracts -fcontract-role=default:maybe,maybe,ignore" }
+module;
+#include <cstdio>
+#include <experimental/contract>
+export module foo;
+// { dg-module-cmi foo }
+
+export int violation_count{0};
+export int violation_line_sum{0};
+extern "C++" export void handle_contract_violation(const std::experimental::contract_violation &violation)
+{
+ violation_count++;
+ violation_line_sum += violation.line_number () * violation_count;
+ printf("violation: %d %d\n", violation_count, violation_line_sum);
+}
+
+export int fn2(int n);
+export int fn_in2(int n);
+export int pre_print(int n) { printf("pre_print(%d)\n", n); return n; }
+
+export int fn_in1(int n) [[ pre: pre_print(n) > 0 ]]
+{
+ printf("%s blah (%d)\n", __FUNCTION__, n);
+ return n;
+}
+export int fn_in2(int x) [[ pre: pre_print(x) > 0 ]]
+{
+ printf("%s(%d)\n", __FUNCTION__, x);
+ return x;
+}
+
+export int fn_iso(int n);
+
+export int fn1(int n)
+ [[ pre: pre_print(n) > 0 ]];
+
+export int fn2(int n)
+ [[ pre: pre_print(n) > 0 ]];
+
+export int pre_print2(int n);
+
+export int fn3(int n)
+ [[ pre: pre_print2(n) > 0 ]];
+
diff --git a/gcc/testsuite/g++.dg/modules/contracts-2_b.C b/gcc/testsuite/g++.dg/modules/contracts-2_b.C
new file mode 100644
index 0000000..01939ae
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/contracts-2_b.C
@@ -0,0 +1,35 @@
+// { dg-additional-options "-fmodules-ts -fcontracts -fcontract-role=default:maybe,maybe,ignore" }
+module;
+#include <cstdio>
+module foo;
+
+int fn1(int x)
+{
+ printf("%s(%d)\n", __FUNCTION__, x);
+ return x;
+}
+
+int fn_iso(int n) [[ pre: pre_print(n) > 0 ]]
+{
+ printf("%s(%d)\n", __FUNCTION__, n);
+ return n;
+}
+
+int pre_print2(int n)
+{
+ printf("pre_print(%d)\n", n);
+ return n;
+}
+
+int fn2(int x)
+{
+ printf("%s(%d)\n", __FUNCTION__, x);
+ return x;
+}
+
+int fn3(int x)
+{
+ printf("%s(%d)\n", __FUNCTION__, x);
+ return x;
+}
+
diff --git a/gcc/testsuite/g++.dg/modules/contracts-2_c.C b/gcc/testsuite/g++.dg/modules/contracts-2_c.C
new file mode 100644
index 0000000..58938e0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/contracts-2_c.C
@@ -0,0 +1,22 @@
+// { dg-module-do run }
+// { dg-additional-options "-fmodules-ts -fcontracts -fcontract-role=default:maybe,maybe,ignore" }
+import foo;
+
+int main(int, char**)
+{
+ int x = -1;
+
+ fn_iso(x--);
+ fn1(x--);
+ fn2(x--);
+ fn3(x--);
+ fn_in1(x--);
+ fn_in2(x--);
+ return (violation_count == 6 && violation_line_sum == 729) ? 0 : -1;
+}
+
+// TODO does any of this actually get verified?
+// { dg-output "pre_print.-1.(\n|\r\n|\r)*" }
+// { dg-output "violation: 1 12(\n|\r\n|\r)*" }
+// { dg-output "fn_iso.-1.(\n|\r\n|\r)*" }
+
diff --git a/gcc/testsuite/g++.dg/modules/contracts-3_a.C b/gcc/testsuite/g++.dg/modules/contracts-3_a.C
new file mode 100644
index 0000000..a4f03d3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/contracts-3_a.C
@@ -0,0 +1,41 @@
+// Basic test to ensure that guarded templates correctly serialize and
+// deserialize their contracts through the CMI.
+// { dg-additional-options "-fmodules-ts -fcontracts -fcontract-continuation-mode=on" }
+module;
+#include <cstdio>
+#include <experimental/contract>
+export module foo;
+// { dg-module-cmi foo }
+
+export int violation_count{0};
+extern "C++" export void handle_contract_violation(const std::experimental::contract_violation &violation)
+{
+ violation_count++;
+ printf("violation_count: %d\n", violation_count);
+}
+
+export int nontemplate(int n)
+ [[ pre: n > 0 ]]
+ [[ post r: r > 0 ]]
+{
+ return -n;
+}
+
+export
+template<typename T>
+T fn(T n)
+ [[ pre: n > 0 ]]
+ [[ post r: r > 0 ]]
+{
+ printf("%s(%d)\n", __FUNCTION__, n);
+ return n;
+}
+
+export
+template<typename T>
+void void_fn(T n)
+ [[ pre: n < 0 ]]
+{
+ printf("%s(%d)\n", __FUNCTION__, n);
+}
+
diff --git a/gcc/testsuite/g++.dg/modules/contracts-3_b.C b/gcc/testsuite/g++.dg/modules/contracts-3_b.C
new file mode 100644
index 0000000..b1d6375
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/contracts-3_b.C
@@ -0,0 +1,35 @@
+// { dg-module-do run }
+// { dg-additional-options "-fmodules-ts -fcontracts -fcontract-role=default:ignore,ignore,ignore" }
+module;
+#include <cstdio>
+export module bar;
+// { dg-module-cmi bar }
+import foo;
+
+template<typename T>
+bool bar_fn_pre(T n) { printf("bar fn pre(%d)\n", n); return true; }
+
+export
+template<typename T>
+T bar_fn(T n)
+ [[ pre: bar_fn_pre(n) && n > 0 ]]
+{
+ printf("%s(%d)\n", __FUNCTION__, n);
+ return n;
+}
+
+int main(int, char**)
+{
+ nontemplate(5);
+ nontemplate(-5);
+ fn(5);
+ fn(-5);
+ fn(5.3);
+ fn(-5.3);
+ void_fn(5);
+ void_fn(-5);
+ bar_fn(5);
+ bar_fn(-5);
+ return violation_count == 7 ? 0 : -1;
+}
+
diff --git a/gcc/testsuite/g++.dg/modules/contracts-4_a.C b/gcc/testsuite/g++.dg/modules/contracts-4_a.C
new file mode 100644
index 0000000..f269e6c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/contracts-4_a.C
@@ -0,0 +1,28 @@
+// Test that template contracts are not reintpreted when the reinterpret
+// contracts flag is not set, regardless of the current TU's contract
+// configuration.
+// { dg-additional-options "-fmodules-ts -fcontracts -fcontract-role=default:maybe,maybe,ignore" }
+module;
+#include <cstdio>
+#include <experimental/contract>
+export module foo;
+// { dg-module-cmi foo }
+
+export int violation_count{0};
+extern "C++" export void handle_contract_violation(const std::experimental::contract_violation &violation)
+{
+ violation_count++;
+ printf("violation_count: %d\n", violation_count);
+}
+
+export template<typename T>
+T fn_t(T t)
+ [[ pre: t > 0 ]]
+ [[ pre audit %custom: t > 0 ]]
+{
+ printf("%s(%d)\n", __FUNCTION__, t);
+ return t;
+}
+
+export int fn_int(int n);
+
diff --git a/gcc/testsuite/g++.dg/modules/contracts-4_b.C b/gcc/testsuite/g++.dg/modules/contracts-4_b.C
new file mode 100644
index 0000000..65b9287
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/contracts-4_b.C
@@ -0,0 +1,8 @@
+// { dg-additional-options "-fmodules-ts -fcontracts -fcontract-role=default:ignore,ignore,ignore" }
+module foo;
+
+int fn_int(int n)
+{
+ return fn_t(n);
+}
+
diff --git a/gcc/testsuite/g++.dg/modules/contracts-4_c.C b/gcc/testsuite/g++.dg/modules/contracts-4_c.C
new file mode 100644
index 0000000..84fcb61
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/contracts-4_c.C
@@ -0,0 +1,9 @@
+// { dg-additional-options "-fmodules-ts -fcontracts -fcontract-role=default:ignore,ignore,ignore" }
+export module bar;
+import foo;
+
+export int bar_fn_int(int n)
+{
+ return fn_t(n);
+}
+
diff --git a/gcc/testsuite/g++.dg/modules/contracts-4_d.C b/gcc/testsuite/g++.dg/modules/contracts-4_d.C
new file mode 100644
index 0000000..dc56251
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/contracts-4_d.C
@@ -0,0 +1,22 @@
+// { dg-module-do run }
+// { dg-additional-options "-fmodules-ts -fcontracts" }
+module;
+#include <cstdio>
+export module baz;
+import foo;
+import bar;
+
+int main(int, char**)
+{
+ int x = -1;
+
+ printf("calling fn_int\n");
+ fn_int(x--);
+ printf("calling bar_fn_int\n");
+ bar_fn_int(x--);
+
+ return violation_count - 4;
+}
+
+// TODO verify dg-output as well once the testsuite supports it
+
diff --git a/gcc/testsuite/g++.dg/modules/contracts-tpl-friend-1_a.C b/gcc/testsuite/g++.dg/modules/contracts-tpl-friend-1_a.C
new file mode 100644
index 0000000..5e6d848
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/contracts-tpl-friend-1_a.C
@@ -0,0 +1,17 @@
+// { dg-additional-options "-fmodules-ts -fcontracts" }
+
+export module foo;
+// { dg-module-cmi foo }
+
+void foo (int, void *);
+void foo (float, void *);
+
+template <typename T> class TPL
+{
+ friend void foo (T, void *); // { dg-warning "non-template function" }
+
+ T member;
+};
+
+template class TPL<float>; // instantiate
+
diff --git a/gcc/testsuite/g++.dg/modules/contracts-tpl-friend-1_b.C b/gcc/testsuite/g++.dg/modules/contracts-tpl-friend-1_b.C
new file mode 100644
index 0000000..f872c92
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/contracts-tpl-friend-1_b.C
@@ -0,0 +1,19 @@
+// { dg-additional-options "-fmodules-ts -fcontracts" }
+
+module foo;
+
+void foo (int x, void *p)
+ [[ pre: x > 0 ]]
+{
+ auto *obj = reinterpret_cast<TPL<int> *> (p);
+
+ obj->member = x;
+}
+
+void foo (float x, void *p)
+ [[ pre: x > 0 ]]
+{
+ auto *obj = reinterpret_cast<TPL<float> *> (p);
+
+ obj->member = x;
+}
diff --git a/gcc/testsuite/g++.dg/modules/modules.exp b/gcc/testsuite/g++.dg/modules/modules.exp
index afb323d..cacbd75 100644
--- a/gcc/testsuite/g++.dg/modules/modules.exp
+++ b/gcc/testsuite/g++.dg/modules/modules.exp
@@ -187,8 +187,9 @@ proc module_do_it { do_what testcase std asm_list } {
lappend options "additional_flags=$std"
set ident "$ident $std"
}
- if { [llength $do_what] > 3 } {
- lappend options "additional_flags=[lindex $do_what 3]"
+ global extra_tool_flags
+ if { [llength $extra_tool_flags] } {
+ lappend options "additional_flags=$extra_tool_flags"
}
set execname "./[file tail $testcase].exe"
@@ -250,6 +251,8 @@ proc module-init { src } {
set option_list {}
set have_std 0
set std_prefix "-std=c++"
+ global extra_tool_flags
+ set extra_tool_flags {}
foreach op $tmp {
switch [lindex $op 0] {
@@ -258,11 +261,13 @@ proc module-init { src } {
if { [string match "*-std=*" [lindex $op 2]] } {
set have_std 1
}
+ eval lappend extra_tool_flags [lindex $op 2]
}
"dg-additional-options" {
if { [string match "*-std=*" [lindex $op 2]] } {
set have_std 1
}
+ eval lappend extra_tool_flags [lindex $op 2]
}
}
}
@@ -279,6 +284,29 @@ proc module-init { src } {
return $option_list
}
+# Return 1 if requirements are met
+proc module-check-requirements { tests } {
+ foreach test $tests {
+ set tmp [dg-get-options $test]
+ foreach op $tmp {
+ switch [lindex $op 0] {
+ "dg-additional-options" {
+ # Example strings to match:
+ # -fmodules-ts -fmodule-mapper=|@g++-mapper-server\\ -t\\ [srcdir]/inc-xlate-1.map
+ # -fmodules-ts -fmodule-mapper=|@g++-mapper-server
+ if [regexp -- {(^| )-fmodule-mapper=\|@([^\\ ]*)} [lindex $op 2] dummy dummy2 prog] {
+ verbose "Checking that mapper exist: $prog"
+ if { ![ check_is_prog_name_available $prog ] } {
+ return 0
+ }
+ }
+ }
+ }
+ }
+ }
+ return 1
+}
+
# cleanup any detritus from previous run
cleanup_module_files [find $DEFAULT_REPO *.gcm]
@@ -307,6 +335,14 @@ foreach src [lsort [find $srcdir/$subdir {*_a.[CHX}]] {
set tests [lsort [find [file dirname $src] \
[regsub {_a.[CHX]$} [file tail $src] {_[a-z].[CHX]}]]]
+ if { ![module-check-requirements $tests] } {
+ set testcase [regsub {_a.[CH]} $src {}]
+ set testcase \
+ [string range $testcase [string length "$srcdir/"] end]
+ unsupported $testcase
+ continue
+ }
+
set std_list [module-init $src]
foreach std $std_list {
set mod_files {}
diff --git a/gcc/testsuite/g++.dg/modules/pr99023_b.X b/gcc/testsuite/g++.dg/modules/pr99023_b.X
index 3d82f34..ca5f32e 100644
--- a/gcc/testsuite/g++.dg/modules/pr99023_b.X
+++ b/gcc/testsuite/g++.dg/modules/pr99023_b.X
@@ -3,5 +3,5 @@
// { dg-prune-output {linker input file unused} }
-// { dg-regexp {[^\n]*: note: include '[^\n]*/initializer_list' translated to import\n} }
+// { dg-regexp {[^\n]*: note: include '[^\n]*[/\\]initializer_list' translated to import\n} }
NO DO NOT COMPILE
diff --git a/gcc/testsuite/g++.dg/other/i386-2.C b/gcc/testsuite/g++.dg/other/i386-2.C
index dd3e71f..fc910ce 100644
--- a/gcc/testsuite/g++.dg/other/i386-2.C
+++ b/gcc/testsuite/g++.dg/other/i386-2.C
@@ -1,5 +1,5 @@
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
-/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert" } */
+/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint" } */
/* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h,
xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h,
diff --git a/gcc/testsuite/g++.dg/other/i386-3.C b/gcc/testsuite/g++.dg/other/i386-3.C
index cd7045c..64741b1 100644
--- a/gcc/testsuite/g++.dg/other/i386-3.C
+++ b/gcc/testsuite/g++.dg/other/i386-3.C
@@ -1,5 +1,5 @@
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
-/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert" } */
+/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint" } */
/* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h,
xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h,
diff --git a/gcc/testsuite/g++.dg/pr107803.C b/gcc/testsuite/g++.dg/pr107803.C
new file mode 100644
index 0000000..f814e96
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr107803.C
@@ -0,0 +1,19 @@
+// { dg-do compile }
+// { dg-options "-O -fno-tree-dominator-opts -fno-tree-fre -Wmaybe-uninitialized" }
+
+void printf(...);
+void __sigsetjmp_cancel() __attribute__((__returns_twice__));
+int z, main_ret;
+void func(void *) {}
+
+int
+main()
+{
+ int x;
+ void (*__cancel_routine)(void *)(func);
+ __sigsetjmp_cancel();
+ __cancel_routine(0);
+ if (main_ret)
+ x = z;
+ printf(x);
+}
diff --git a/gcc/testsuite/g++.dg/pr107867.C b/gcc/testsuite/g++.dg/pr107867.C
new file mode 100644
index 0000000..16c7499
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr107867.C
@@ -0,0 +1,19 @@
+// { dg-do compile }
+// { dg-options "-Os -fno-tree-ccp -Wuninitialized" }
+
+void printf(...);
+void __sigsetjmp_cancel() __attribute__((__returns_twice__));
+int z, main_ret;
+void func(void *) {}
+
+int
+main()
+{
+ int x;
+ void (*__cancel_routine)(void *)(func);
+ __sigsetjmp_cancel();
+ __cancel_routine(0);
+ if (main_ret)
+ x = z;
+ printf(x);
+}
diff --git a/gcc/testsuite/g++.dg/pr107985.C b/gcc/testsuite/g++.dg/pr107985.C
new file mode 100644
index 0000000..8d244b5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr107985.C
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -ftree-vrp -fno-tree-ccp -fno-tree-forwprop -fno-tree-fre" } */
+
+struct B {
+ int f;
+};
+
+struct D : public B {
+};
+
+void foo() {
+ D d;
+ d.f = 7;
+
+ int B::* pfb = &B::f;
+ int D::* pfd = pfb;
+ int v = d.*pfd;
+}
diff --git a/gcc/testsuite/g++.dg/pr93195a.C b/gcc/testsuite/g++.dg/pr93195a.C
index b14f1b3..26d265d 100644
--- a/gcc/testsuite/g++.dg/pr93195a.C
+++ b/gcc/testsuite/g++.dg/pr93195a.C
@@ -1,5 +1,4 @@
/* { dg-do link { target { ! { nvptx*-*-* visium-*-* } } } } */
-/* { dg-skip-if "not supported" { { powerpc*-*-* } && lp64 } } */
// { dg-require-effective-target o_flag_in_section }
/* { dg-options "-O0 -fpatchable-function-entry=1" } */
/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */
diff --git a/gcc/testsuite/g++.dg/pr99966.C b/gcc/testsuite/g++.dg/pr99966.C
new file mode 100644
index 0000000..4d68982
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr99966.C
@@ -0,0 +1,23 @@
+// { dg-do compile }
+// { dg-require-effective-target c++17 }
+// { dg-options "-O2 -fdump-tree-vrp1" }
+
+// Test we can remove a range bound after the assert.
+
+#include <cassert>
+#include <cstdint>
+#include <cstddef>
+#include <vector>
+
+uint64_t f(std::vector<uint64_t>& data, size_t start, size_t end){
+ assert(start < end && start < data.size() && end <= data.size());
+
+
+ uint64_t total = 0;
+ for (size_t i = start; i < end; i++) {
+ total += data.at(i);
+ }
+ return total;
+}
+
+/* { dg-final { scan-tree-dump-not "throw" "vrp1"} } */
diff --git a/gcc/testsuite/g++.dg/special/initpri3.C b/gcc/testsuite/g++.dg/special/initpri3.C
new file mode 100644
index 0000000..3d745a42
--- /dev/null
+++ b/gcc/testsuite/g++.dg/special/initpri3.C
@@ -0,0 +1,10 @@
+// Verify __has_attribute(init_priority) is false on targets that
+// don't support init priorities, and is treated as an unrecognized
+// attribute in that case.
+
+#if !__has_attribute(init_priority)
+#error unsupported // { dg-error "" "" { target { ! init_priority } } }
+#endif
+
+struct A { A(); } a __attribute__((init_priority(500)));
+// { dg-warning "attribute directive ignored" "" { target { ! init_priority } } .-1 }
diff --git a/gcc/testsuite/g++.dg/template/canon-type-19.C b/gcc/testsuite/g++.dg/template/canon-type-19.C
new file mode 100644
index 0000000..27ef3f1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/canon-type-19.C
@@ -0,0 +1,18 @@
+// PR c++/107539
+// { dg-do compile { target c++11 } }
+
+template<class T>
+struct A { };
+
+template<template<class> class C>
+struct B {
+ template<class T>
+ void f(T t) {
+ A<C<decltype(t)>> a1;
+ }
+
+ template<class T>
+ void g(T t) {
+ A<C<decltype(t)>> a2;
+ }
+};
diff --git a/gcc/testsuite/g++.dg/template/crash55.C b/gcc/testsuite/g++.dg/template/crash55.C
index 5416e32..8a7fc11 100644
--- a/gcc/testsuite/g++.dg/template/crash55.C
+++ b/gcc/testsuite/g++.dg/template/crash55.C
@@ -1,7 +1,6 @@
//PR c++/27668
template<typename class T, T = T()> // { dg-error "nested-name-specifier|two or more|class type|incomplete" }
-// { dg-error "cast" "" { target c++98_only } .-1 }
struct A {};
-template<int> void foo(A<int>); // { dg-error "template argument 2" "" { target c++98_only } }
+template<int> void foo(A<int>);
diff --git a/gcc/testsuite/g++.dg/template/ref3.C b/gcc/testsuite/g++.dg/template/ref3.C
index 91e3c93..976c093 100644
--- a/gcc/testsuite/g++.dg/template/ref3.C
+++ b/gcc/testsuite/g++.dg/template/ref3.C
@@ -5,8 +5,7 @@ template<const int&> struct A {};
template<typename T> struct B
{
A<(T)0> b; // { dg-error "constant|not a valid" }
- A<T(0)> a; // { dg-error "constant|not a valid" "" { xfail c++98_only } }
- // PR c++/68699
+ A<T(0)> a; // { dg-error "constant|not a valid" }
};
B<const int&> b;
diff --git a/gcc/testsuite/g++.dg/tree-ssa/allocator-opt1.C b/gcc/testsuite/g++.dg/tree-ssa/allocator-opt1.C
new file mode 100644
index 0000000..e8394c7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/allocator-opt1.C
@@ -0,0 +1,12 @@
+// PR c++/105838
+// { dg-additional-options -fdump-tree-gimple }
+
+// Check that there's only one allocator (temporary) variable.
+// Currently the dump doesn't print the allocator template arg in this context.
+// { dg-final { scan-tree-dump-times "struct allocator D" 1 "gimple" } }
+
+#include <string>
+void f (const char *p)
+{
+ std::string lst[] = { p, p, p, p };
+}
diff --git a/gcc/testsuite/g++.dg/tree-ssa/initlist-opt1.C b/gcc/testsuite/g++.dg/tree-ssa/initlist-opt1.C
new file mode 100644
index 0000000..053317b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/initlist-opt1.C
@@ -0,0 +1,25 @@
+// PR c++/105838
+// { dg-additional-options -fdump-tree-gimple }
+// { dg-do compile { target c++11 } }
+
+// Test that we do range-initialization from const char *.
+// { dg-final { scan-tree-dump {_M_range_initialize<const char\* const\*>} "gimple" } }
+
+#include <string>
+#include <vector>
+
+void g (const void *);
+
+void f (const char *p)
+{
+ std::vector<std::string> lst = {
+ "aahing", "aaliis", "aarrgh", "abacas", "abacus", "abakas", "abamps", "abands", "abased", "abaser", "abases", "abasia",
+ "abated", "abater", "abates", "abatis", "abator", "abattu", "abayas", "abbacy", "abbess", "abbeys", "abbots", "abcees",
+ "abdabs", "abduce", "abduct", "abears", "abeigh", "abeles", "abelia", "abends", "abhors", "abided", "abider", "abides",
+ "abject", "abjure", "ablate", "ablaut", "ablaze", "ablest", "ablets", "abling", "ablins", "abloom", "ablush", "abmhos",
+ "aboard", "aboded", "abodes", "abohms", "abolla", "abomas", "aboral", "abords", "aborne", "aborts", "abound", "abouts",
+ "aboves", "abrade", "abraid", "abrash", "abrays", "abrazo", "abrege", "abrins", "abroad", "abrupt", "abseil", "absent",
+ };
+
+ g(&lst);
+}
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr106922.C b/gcc/testsuite/g++.dg/tree-ssa/pr106922.C
index 2aec497..4b6a4ad 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr106922.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr106922.C
@@ -1,5 +1,5 @@
// { dg-require-effective-target c++20 }
-// { dg-options "-O2 -fdump-tree-cddce3" }
+// { dg-options "-O2 -fdump-tree-dce7" }
template <typename> struct __new_allocator {
void deallocate(int *, int) { operator delete(0); }
@@ -87,4 +87,4 @@ void testfunctionfoo() {
}
}
-// { dg-final { scan-tree-dump-not "m_initialized" "cddce3" } }
+// { dg-final { scan-tree-dump-not "m_initialized" "dce7" } }
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr107876.C b/gcc/testsuite/g++.dg/tree-ssa/pr107876.C
new file mode 100644
index 0000000..6cff2f1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr107876.C
@@ -0,0 +1,38 @@
+// { dg-do compile }
+// { dg-require-effective-target c++11 }
+// { dg-options "-O2 -funswitch-loops --param max-unswitch-insns=5 -fdump-tree-unswitch-details" }
+
+class X {
+public:
+ X();
+ X(const X&);
+ X(const volatile X &);
+ ~X();
+};
+
+X test17(int i) {
+ if (false) {
+ impossible:
+ if (i == 3)
+ return X();
+ }
+
+ while (true) {
+ X x;
+ if (i == 0)
+ return x;
+ if (i == 1)
+ break;
+ if (i == 2)
+ continue;
+ if (i == 3)
+ goto impossible;
+ if (i == 4)
+ __builtin_exit(1);
+ if (i == 5)
+ return x;
+ }
+ return X();
+}
+
+// { dg-final { scan-tree-dump "unswitching loop 1 on .switch. with condition: i_\[0-9\]+\\(D\\) == 2" "unswitch" } }
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C b/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C
index fc26857..1023285 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C
@@ -21,4 +21,4 @@ double foo (void)
}
/* GCC 8 emits operator new () != NULL with -fcheck-new. */
-/* { dg-final { scan-tree-dump "Replaced .* != 0B. with .1" "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times " != 0B\\)" 1 "forwprop1" } } */
diff --git a/gcc/testsuite/g++.dg/ubsan/vptr-4.C b/gcc/testsuite/g++.dg/ubsan/vptr-4.C
index a21d3d6..1efd3f7 100644
--- a/gcc/testsuite/g++.dg/ubsan/vptr-4.C
+++ b/gcc/testsuite/g++.dg/ubsan/vptr-4.C
@@ -1,7 +1,7 @@
// Verify that -fsanitize=vptr downcast instrumentation works properly
// inside of constexpr.
// { dg-do compile }
-// { dg-options "-std=c++11 -fsanitize=vptr" }
+// { dg-options "-std=c++11 -fsanitize=vptr -Winvalid-constexpr -pedantic-errors" }
struct S {
constexpr S() : a(0) {}
diff --git a/gcc/testsuite/g++.dg/vect/pr107766.cc b/gcc/testsuite/g++.dg/vect/pr107766.cc
new file mode 100644
index 0000000..744bcc9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/pr107766.cc
@@ -0,0 +1,23 @@
+// { dg-do compile }
+// { dg-additional-options "-ffp-contract=off" }
+
+typedef double btScalar;
+struct btVector3 {
+ operator btScalar *() const;
+};
+double m_vec[2];
+struct btShapeMatrix {
+ double &operator[](int i) { return m_vec[i]; }
+};
+btScalar shape_function___1pxt1pz, shape_function__fac;
+struct btMiniSDF {
+ void shape_function_(btVector3 const &) const;
+};
+void btMiniSDF::shape_function_(btVector3 const &xi) const {
+ btShapeMatrix res;
+ btScalar _1m3y = 1.0 - 3.0 * xi[1], _1p3y = 1.0 + 3.0 * xi[1],
+ fact1m3y = shape_function__fac * _1m3y,
+ fact1p3y = shape_function__fac * _1p3y;
+ res[22] = fact1m3y * shape_function___1pxt1pz;
+ res[23] = fact1p3y * shape_function___1pxt1pz;
+}
diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-pr104165-1.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-pr104165-1.C
new file mode 100644
index 0000000..bc46285
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-pr104165-1.C
@@ -0,0 +1,27 @@
+// { dg-do compile }
+// { dg-require-effective-target c++11 }
+// { dg-options "-O2 -Warray-bounds" }
+
+#include <algorithm>
+
+static int bar(int n, int l)
+{
+ int f[l];
+ int x = 0;
+ int r = n;
+
+ for (; x < l;)
+ if (r)
+ x = l;
+ else
+ r = 1;
+
+ if (r == 1)
+ std::sort(f, f + x, [](int a, int b) { return a > b; });
+ return 1;
+}
+
+int foo(int n)
+{
+ return bar(n, 4);
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wdangling-reference1.C b/gcc/testsuite/g++.dg/warn/Wdangling-reference1.C
index 97c81ee..1718c28 100644
--- a/gcc/testsuite/g++.dg/warn/Wdangling-reference1.C
+++ b/gcc/testsuite/g++.dg/warn/Wdangling-reference1.C
@@ -139,6 +139,6 @@ struct Y {
// x1 = Y::operator int&& (&TARGET_EXPR <D.2410, {}>)
int&& x1 = Y(); // { dg-warning "dangling reference" }
int&& x2 = Y{}; // { dg-warning "dangling reference" }
-int& x3 = Y(); // { dg-warning "dangling reference" }
-int& x4 = Y{}; // { dg-warning "dangling reference" }
+int& x3 = Y(); // { dg-bogus "dangling reference" }
+int& x4 = Y{}; // { dg-bogus "dangling reference" }
const int& t1 = Y().foo(10); // { dg-warning "dangling reference" }
diff --git a/gcc/testsuite/g++.dg/warn/Wdangling-reference6.C b/gcc/testsuite/g++.dg/warn/Wdangling-reference6.C
new file mode 100644
index 0000000..bf849e2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wdangling-reference6.C
@@ -0,0 +1,38 @@
+// { dg-do compile { target c++17 } }
+// { dg-options "-Wdangling-reference" }
+// Test -Wdangling-reference with std::minmax.
+
+#include <algorithm>
+
+using U = std::pair<const int&, const int&>;
+
+int
+fn1 ()
+{
+ std::pair<const int&, const int&> v = std::minmax(1, 2); // { dg-warning "dangling reference" }
+ U v2 = std::minmax(1, 2); // { dg-warning "dangling reference" }
+ auto v3 = std::minmax(1, 2); // { dg-warning "dangling reference" }
+ return v.first + v2.second + v3.first;
+}
+
+int
+fn2 ()
+{
+ int n = 1;
+ auto p = std::minmax(n, n + 1); // { dg-warning "dangling reference" }
+ int m = p.first; // ok
+ int x = p.second; // undefined behavior
+
+ // Note that structured bindings have the same issue
+ auto [mm, xx] = std::minmax(n, n + 1); // { dg-warning "dangling reference" }
+ (void) xx; // undefined behavior
+
+ return m + x;
+}
+
+int
+fn3 ()
+{
+ auto v = std::minmax({1, 2});
+ return v.first;
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wdangling-reference7.C b/gcc/testsuite/g++.dg/warn/Wdangling-reference7.C
new file mode 100644
index 0000000..4b0de2d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wdangling-reference7.C
@@ -0,0 +1,16 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wdangling-reference" }
+
+int& ref(const int&);
+int&& rref(const int&);
+
+void
+g ()
+{
+ const int& r1 = ref (1); // { dg-warning "dangling reference" }
+ int& r2 = ref (2); // { dg-bogus "dangling reference" }
+ auto& r3 = ref (3); // { dg-bogus "dangling reference" }
+ int&& r4 = rref (4); // { dg-warning "dangling reference" }
+ auto&& r5 = rref (5); // { dg-warning "dangling reference" }
+ const int&& r6 = rref (6); // { dg-warning "dangling reference" }
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wignored-qualifiers3.C b/gcc/testsuite/g++.dg/warn/Wignored-qualifiers3.C
new file mode 100644
index 0000000..dedb38f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wignored-qualifiers3.C
@@ -0,0 +1,24 @@
+// PR c++/107492
+// { dg-do compile { target c++14 } }
+// { dg-additional-options "-Wignored-qualifiers" }
+
+// Here the 'const' matters, so don't warn.
+template<typename T> struct S { };
+template<> struct S<void(*)()> { };
+template<> struct S<const void(*)()> { }; // { dg-bogus "ignored" }
+
+template<typename T, typename U> constexpr bool is_same_v = false;
+template<typename T> constexpr bool is_same_v<T, T> = true;
+
+static_assert( ! is_same_v< void(*)(), const void(*)() >, ""); // { dg-bogus "ignored" }
+
+// Here the 'const' matters as well -> don't warn.
+auto g() -> const void (*)(); // { dg-bogus "ignored" }
+auto g() -> const void (*)() { return nullptr; } // { dg-bogus "ignored" }
+
+// Here as well.
+const void (*h)() = static_cast<const void (*)()>(h); // { dg-bogus "ignored" }
+
+// But let's keep the warning here.
+const void f(); // { dg-warning "ignored" }
+const void f() { } // { dg-warning "ignored" }
diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-pr107919-1.C b/gcc/testsuite/g++.dg/warn/Wuninitialized-pr107919-1.C
new file mode 100644
index 0000000..dd631dc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-pr107919-1.C
@@ -0,0 +1,15 @@
+// { dg-do compile }
+// { dg-require-effective-target c++17 }
+// { dg-options "-O -Wuninitialized" }
+
+#include <memory>
+#include <variant>
+
+using Event = std::variant<std::variant<std::tuple<std::unique_ptr<int>>>, int, char>;
+
+void do_something(void* storage)
+{
+ Event event {};
+ auto& swappedValue = *reinterpret_cast<Event*>(storage);
+ std::swap(event, swappedValue);
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900210_10.C b/gcc/testsuite/g++.old-deja/g++.bugs/900210_10.C
index b1b1067..7fbee3f 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900210_10.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900210_10.C
@@ -9,7 +9,7 @@
// keywords: operator[], static function members
struct struct0 {
- static int operator[] (); /* { dg-error "" } */
+ static int operator[] (); /* { dg-error "" "" { target c++20_down } } */
};
int main () { return 0; }
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/byval2.C b/gcc/testsuite/g++.old-deja/g++.jason/byval2.C
index 40bf2a3..0575109 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/byval2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/byval2.C
@@ -18,6 +18,6 @@ inline char operator == (const Char a, const char b) { return 0; }
char mystrcmp(Char s[31], Char t[31])
{
- for (; *s == *t; ++s, ++t) if (*s == '\0') return 0;
+ for (; *s == *t; ++s, ++t) if (*s == '\0') return 0; // { dg-error "reversed" "" { target c++20 } }
return char(*s - *t);
}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/overload13.C b/gcc/testsuite/g++.old-deja/g++.other/overload13.C
index 54ab404..f59bd4a 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/overload13.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/overload13.C
@@ -2,7 +2,7 @@
// Origin: Nathan Sidwell <nathan@codesourcery.com>
struct A {
- bool operator== (A const &);
+ bool operator== (A const &) const;
operator bool () const;
operator int * () const;
};
diff --git a/gcc/testsuite/g++.target/aarch64/sve/pr107920.C b/gcc/testsuite/g++.target/aarch64/sve/pr107920.C
new file mode 100644
index 0000000..179b2b6
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/sve/pr107920.C
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fnon-call-exceptions" } */
+
+#include "arm_sve.h"
+
+svint8_t
+test_s8(int8_t *x)
+{
+ try
+ {
+ return svld1rq_s8 (svptrue_b8 (), &x[0]);
+ }
+ catch (...)
+ {
+ return svdup_s8 (1);
+ }
+}
+
+/* { dg-final { scan-assembler "__cxa_begin_catch" } } */
diff --git a/gcc/testsuite/g++.target/i386/mv16.C b/gcc/testsuite/g++.target/i386/mv16.C
index 6839287..772791b 100644
--- a/gcc/testsuite/g++.target/i386/mv16.C
+++ b/gcc/testsuite/g++.target/i386/mv16.C
@@ -92,6 +92,18 @@ int __attribute__ ((target("arch=rocketlake"))) foo () {
return 24;
}
+int __attribute__ ((target("arch=sierraforest"))) foo () {
+ return 25;
+}
+
+int __attribute__ ((target("arch=graniterapids"))) foo () {
+ return 26;
+}
+
+int __attribute__ ((target("arch=grandridge"))) foo () {
+ return 27;
+}
+
int main ()
{
int val = foo ();
@@ -130,6 +142,12 @@ int main ()
assert (val == 23);
else if (__builtin_cpu_is ("rocketlake"))
assert (val == 24);
+ else if (__builtin_cpu_is ("sierraforest"))
+ assert (val == 25);
+ else if (__builtin_cpu_is ("graniterapids"))
+ assert (val == 26);
+ else if (__builtin_cpu_is ("grandridge"))
+ assert (val == 27);
else
assert (val == 0);
diff --git a/gcc/testsuite/g++.target/i386/pr102566-7.C b/gcc/testsuite/g++.target/i386/pr102566-7.C
new file mode 100644
index 0000000..ce90214
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/pr102566-7.C
@@ -0,0 +1,22 @@
+/* { dg-do compile { target c++11 } } */
+/* { dg-options "-O2" } */
+
+#include <atomic>
+
+template<uint32_t b>
+void lock_bts(std::atomic<uint32_t> &a) { while (!(a.fetch_or(b) & b)); }
+template<uint32_t b>
+void lock_btr(std::atomic<uint32_t> &a) { while (a.fetch_and(~b) & b); }
+template<uint32_t b>
+void lock_btc(std::atomic<uint32_t> &a) { while (a.fetch_xor(b) & b); }
+template void lock_bts<1U<<30>(std::atomic<uint32_t> &a);
+template void lock_btr<1U<<30>(std::atomic<uint32_t> &a);
+template void lock_btc<1U<<30>(std::atomic<uint32_t> &a);
+template void lock_bts<1U<<31>(std::atomic<uint32_t> &a);
+template void lock_btr<1U<<31>(std::atomic<uint32_t> &a);
+template void lock_btc<1U<<31>(std::atomic<uint32_t> &a);
+
+/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btsl" 2 } } */
+/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btrl" 2 } } */
+/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btcl" 2 } } */
+/* { dg-final { scan-assembler-not "cmpxchg" } } */
diff --git a/gcc/testsuite/g++.target/i386/pr106875.C b/gcc/testsuite/g++.target/i386/pr106875.C
new file mode 100644
index 0000000..eeab510
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/pr106875.C
@@ -0,0 +1,5 @@
+// PR target/106875
+// { dg-do compile { target { c++11 && lp64 } } }
+// { dg-options "-O0 -mabi=ms -fabi-version=3 -mcall-ms2sysv-xlogues" }
+
+#include "pr101180.C"
diff --git a/gcc/testsuite/g++.target/i386/pr107404.C b/gcc/testsuite/g++.target/i386/pr107404.C
new file mode 100644
index 0000000..e47d0fd
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/pr107404.C
@@ -0,0 +1,53 @@
+// PR target/107404
+// { dg-do run }
+// { dg-options "-O3" }
+
+unsigned long long a;
+void b(unsigned long long *f, int p2) { *f ^= p2; }
+long c;
+char e, i;
+short g, m;
+long long ab[1][25][21][22];
+unsigned long long aa[1][21][22];
+unsigned long long ae[1][25][21][21];
+long long ac[129360];
+char ad[25][1][21];
+char ah[1][25][1][21];
+short af[100];
+long max(long f, unsigned long p2) { return f < p2 ? p2 : f; }
+const int &max2(const int &f, const int &p2) { return f < p2 ? p2 : f; }
+void foo(unsigned f, unsigned p2, char l, char p4, long long n[][25][21][22],
+ unsigned long long p6[][21][22], unsigned long long u[][25][21][21]) {
+ long an;
+ for (int j = 0; j < 4; j = p2)
+ for (short k = 0; k < 7; k += 2)
+ for (short o = 0; o < (short)p2 + 21742; o = l) {
+ for (signed char p = 2; p < 9; p += p4)
+ if (p6[j][o][p])
+ for (long q(3); 4 ? n[0][k][o][0] : 0;
+ q += p6[0][o][0] ? p6[j][0][p] : 0)
+ ac[j + q] = 5066799590;
+ for (long r(p4 - 16); r < 21; r += 4) {
+ ad[k][o][r] = max(u[j][k][o][r], f + u[j][k][o][r]);
+ long d = u[j][k][o][r];
+ an = d < p2 ? p2 : d;
+ e = ah[j][k][o][r] = an;
+ af[o * r] = i;
+ }
+ for (short s(c); s < (short)p2; s = 2)
+ for (short am(m); am; am = max2(3, p2))
+ for (long y = 0; y; y = 3)
+ for (short t(0); t < max2(g, 0);)
+ ;
+ }
+}
+int main() {
+ foo(7, 1558227751, 104, 16, ab, aa, ae);
+ for (unsigned long v = 0; v < 5; ++v)
+ for (unsigned long w = 0; w < 1; ++w)
+ for (unsigned long x = 0; x < 21; ++x)
+ b(&a, ad[v][w][x]);
+
+ if (a)
+ __builtin_abort();
+}
diff --git a/gcc/testsuite/g++.target/powerpc/pr90259.C b/gcc/testsuite/g++.target/powerpc/pr90259.C
new file mode 100644
index 0000000..db75ac7
--- /dev/null
+++ b/gcc/testsuite/g++.target/powerpc/pr90259.C
@@ -0,0 +1,103 @@
+/* { dg-require-effective-target long_double_ibm128 } */
+/* { dg-options "-O2 -ffloat-store -fgcse -fnon-call-exceptions -fno-forward-propagate -fno-omit-frame-pointer -fstack-protector-all" } */
+/* { dg-add-options long_double_ibm128 } */
+
+/* Verify there is no ICE. */
+
+template <int a> struct b
+{
+ static constexpr int c = a;
+};
+template <bool a> using d = b<a>;
+struct e
+{
+ int f;
+ int
+ g ()
+ {
+ return __builtin_ceil (f / (long double) h);
+ }
+ float h;
+};
+template <typename, typename> using k = d<!bool ()>;
+template <typename> class n
+{
+public:
+ e ae;
+ void af ();
+};
+template <typename l>
+void
+n<l>::af ()
+{
+ ae.g ();
+}
+template <bool> using m = int;
+template <typename ag, typename ah, typename ai = m<k<ag, ah>::c>>
+using aj = n<ai>;
+struct o
+{
+ void
+ af ()
+ {
+ al.af ();
+ }
+ aj<int, int> al;
+};
+template <typename> class am;
+template <typename i> class ao
+{
+protected:
+ static i *ap (int);
+};
+template <typename, typename> class p;
+template <typename ar, typename i, typename... j> class p<ar (j...), i> : ao<i>
+{
+public:
+ static ar
+ as (const int &p1, j...)
+ {
+ (*ao<i>::ap (p1)) (j ()...);
+ }
+};
+template <typename ar, typename... j> class am<ar (j...)>
+{
+ template <typename, typename> using av = int;
+
+public:
+ template <typename i, typename = av<d<!bool ()>, void>,
+ typename = av<i, void>>
+ am (i);
+ using aw = ar (*) (const int &, j...);
+ aw ax;
+};
+template <typename ar, typename... j>
+template <typename i, typename, typename>
+am<ar (j...)>::am (i)
+{
+ ax = p<ar (j...), i>::as;
+}
+struct G
+{
+ void ba (am<void (o)>);
+};
+struct q
+{
+ q ()
+ {
+ G a;
+ a.ba (r ());
+ }
+ struct r
+ {
+ void
+ operator() (o p1)
+ try
+ {
+ p1.af ();
+ }
+ catch (int)
+ {
+ }
+ };
+} s;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr107835.c b/gcc/testsuite/gcc.c-torture/compile/pr107835.c
new file mode 100644
index 0000000..122beff
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr107835.c
@@ -0,0 +1,11 @@
+/* PR tree-optimization/107835 */
+
+int *
+foo (void)
+{
+ int *x = 0;
+ unsigned n = n;
+ for (; n; --n, ++x)
+ ;
+ return x;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr107997.c b/gcc/testsuite/gcc.c-torture/compile/pr107997.c
new file mode 100644
index 0000000..89e1fd3
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr107997.c
@@ -0,0 +1,23 @@
+/* PR tree-optimization/107997 */
+
+int a, b;
+void bar (int);
+int baz (void);
+
+void *
+foo (int x, void *y)
+{
+ asm goto ("" : : "r" (x || !a) : : l);
+l:
+ if (y)
+ return 0;
+ bar (b ? b : x);
+ while (x--)
+ {
+ if (!baz ())
+ baz ();
+ asm goto ("" : : : : l2);
+ l2:;
+ }
+ return y;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-6.x b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-6.x
index e7c051d..6655a07 100644
--- a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-6.x
+++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-6.x
@@ -1,3 +1,4 @@
+lappend additional_flags "-fno-trapping-math"
# The ARM VxWorks kernel uses an external floating-point library in
# which routines like __ledf2 are just aliases for __cmpdf2. These
# routines therefore don't handle NaNs correctly.
diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-9.c b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-9.c
new file mode 100644
index 0000000..7172634
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-9.c
@@ -0,0 +1,31 @@
+
+const double dnan = 1.0/0.0 - 1.0/0.0;
+double x = 1.0;
+
+extern void link_error (void);
+extern void abort (void);
+
+main ()
+{
+#if ! defined (__vax__) && ! defined (_CRAY)
+ /* NaN is an IEEE unordered operand. All these test should be false. */
+ if (dnan == dnan)
+ link_error ();
+ if (dnan != x)
+ x = 1.0;
+ else
+ link_error ();
+
+ if (dnan == x)
+ link_error ();
+#endif
+ exit (0);
+}
+
+#ifndef __OPTIMIZE__
+void link_error (void)
+{
+ abort ();
+}
+#endif
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-9.x b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-9.x
new file mode 100644
index 0000000..e7c051d
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-9.x
@@ -0,0 +1,16 @@
+# The ARM VxWorks kernel uses an external floating-point library in
+# which routines like __ledf2 are just aliases for __cmpdf2. These
+# routines therefore don't handle NaNs correctly.
+if [istarget "arm*-*-vxworks*"] {
+ set torture_eval_before_execute {
+ global compiler_conditional_xfail_data
+ set compiler_conditional_xfail_data {
+ "The ARM kernel uses a flawed floating-point library."
+ { "*-*-*" }
+ { "-O0" }
+ { "-mrtp" }
+ }
+ }
+}
+
+return 0
diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp b/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp
index 6d3c371..fda34a7 100644
--- a/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp
+++ b/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp
@@ -52,6 +52,9 @@ if { [istarget "alpha*-*-*"]
|| [istarget "sh*-*-*"] } then {
lappend additional_flags "-mieee"
}
+if [istarget rx-*-*] then {
+ lappend additional_flags "-mnofpu"
+}
if { ![check_effective_target_signal] } {
lappend additional_flags "-DSIGNAL_SUPPRESS"
diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/inf-4.c b/gcc/testsuite/gcc.c-torture/execute/ieee/inf-4.c
new file mode 100644
index 0000000..119775d
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/ieee/inf-4.c
@@ -0,0 +1,26 @@
+__attribute__((noipa)) int
+foo (double a, double b)
+{
+ double c = a - b;
+ if (!__builtin_isfinite (c))
+ {
+ if (__builtin_isnan (c))
+ {
+ if (!__builtin_isnan (a) && !__builtin_isnan (b))
+ return 1;
+ }
+ else if (__builtin_isfinite (a) && __builtin_isfinite (b))
+ return 2;
+ }
+ else if (c == 0 && a != b)
+ return 3;
+ return 4;
+}
+
+int
+main ()
+{
+ double a = __builtin_inf ();
+ if (foo (a, a) != 1)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr107879.c b/gcc/testsuite/gcc.c-torture/execute/pr107879.c
new file mode 100644
index 0000000..2aabe8e
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr107879.c
@@ -0,0 +1,25 @@
+/* PR tree-optimization/107879 */
+
+__attribute__((noipa)) static double
+foo (double *y)
+{
+ volatile int ph = 0;
+ volatile double vf = 1.0;
+ double factor = vf;
+ double x = - (double) ph * factor;
+ if (x == 0)
+ *y = 1.0;
+ else
+ *y = 1.0 / x;
+ double w = 2.0 * x / factor;
+ double omww = 1 - w;
+ return omww > 0.0 ? omww : 0.0;
+}
+
+int
+main ()
+{
+ double y = 42.0;
+ if (foo (&y) != 1.0)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-11.c b/gcc/testsuite/gcc.dg/Warray-bounds-11.c
index c9fc461..3ba2bb6 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-11.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-11.c
@@ -78,7 +78,7 @@ void foo(int (*a)[3])
h->j[4] = 1; // flexible array member
h0->j[4] = 1; // zero-sized array extension
- h1->j[4] = 1; /* { dg-warning "subscript 4 is above array bound" } */
+ h1->j[4] = 1; /* { dg-bogus "subscript 4 is above array bound" } */
h3->j[4] = 1; /* { dg-warning "subscript 4 is above array bound" } */
struct h0b* h0b = malloc(sizeof(struct h) + 3 * sizeof(int));
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-34.c b/gcc/testsuite/gcc.dg/Warray-bounds-34.c
index cea7c4b..1b2a098 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-34.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-34.c
@@ -7,7 +7,7 @@ int x;
inline void foo (int i)
{
- a[i + 1] = 123; /* { dg-warning "\\\[-Warray-bounds]" } */
+ a[i + 1] = 123; /* { dg-warning "\\\[-Warray-bounds" } */
}
int bar (void)
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-43.c b/gcc/testsuite/gcc.dg/Warray-bounds-43.c
index 0f521a7..43a8331 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-43.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-43.c
@@ -19,7 +19,7 @@ NOIPA int g2 (int i)
sink (p0, p1, p2);
- return p2[8]; // { dg-warning "\\\[-Warray-bounds]" }
+ return p2[8]; // { dg-warning "\\\[-Warray-bounds" }
}
NOIPA int g3 (int i)
@@ -33,7 +33,7 @@ NOIPA int g3 (int i)
sink (p0, p1, p2, p3);
- return p3[7]; // { dg-warning "\\\[-Warray-bounds]" }
+ return p3[7]; // { dg-warning "\\\[-Warray-bounds" }
}
NOIPA int g4 (int i)
@@ -48,7 +48,7 @@ NOIPA int g4 (int i)
sink (p0, p1, p2, p3, p4);
- return p4[6]; // { dg-warning "\\\[-Warray-bounds]" }
+ return p4[6]; // { dg-warning "\\\[-Warray-bounds" }
}
NOIPA int g5 (int i)
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48.c b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
index 775b301..e920314 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-48.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
@@ -4,6 +4,11 @@
{ dg-options "-O2 -Wall" }
{ dg-require-effective-target alloca } */
+/* pr102706: disabled warnings because the now-disabled conditions for the
+ bogus warnings to come up do not take cost analysis into account, and often
+ come up wrong. */
+/* { dg-additional-options "-Wno-stringop-overflow" } */
+
typedef __INT16_TYPE__ int16_t;
typedef __INT32_TYPE__ int32_t;
@@ -30,7 +35,8 @@ static void nowarn_ax_extern (struct AX *p)
static void warn_ax_local_buf (struct AX *p)
{
- p->ax[0] = 4; p->ax[1] = 5; // { dg-warning "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v2hi_store_align && { ! vect_slp_v4hi_store_unalign } } } }
+ p->ax[0] = 4; p->ax[1] = 5; // { dg-bogus "\\\[-Wstringop-overflow" "pr102706" }
+ // { xfail { vect_slp_v2hi_store_align && { ! vect_slp_v4hi_store_unalign } } }
p->ax[2] = 6; // { dg-warning "\\\[-Warray-bounds" }
p->ax[3] = 7; // { dg-warning "\\\[-Warray-bounds" }
@@ -130,7 +136,8 @@ static void warn_a0_extern (struct A0 *p)
static void warn_a0_local_buf (struct A0 *p)
{
- p->a0[0] = 4; p->a0[1] = 5; // { dg-warning "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v2hi_store_align && { ! vect_slp_v4hi_store_unalign } } } }
+ p->a0[0] = 4; p->a0[1] = 5; // { dg-bogus "\\\[-Wstringop-overflow" "pr102706" }
+ // { xfail { vect_slp_v2hi_store_align && { ! vect_slp_v4hi_store_unalign } } }
p->a0[2] = 6; // { dg-warning "\\\[-Warray-bounds" }
p->a0[3] = 7; // { dg-warning "\\\[-Warray-bounds" }
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c
new file mode 100644
index 0000000..d36ba4d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c
@@ -0,0 +1,39 @@
+/* Test -fstrict-flex-arrays + -Warray-bounds. */
+/* { dg-do compile} */
+/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds" } */
+
+struct trailing_array_1 {
+ int a;
+ int b;
+ int c[4];
+};
+
+struct trailing_array_2 {
+ int a;
+ int b;
+ int c[1];
+};
+
+struct trailing_array_3 {
+ int a;
+ int b;
+ int c[0];
+};
+struct trailing_array_4 {
+ int a;
+ int b;
+ int c[];
+};
+
+void __attribute__((__noinline__)) stuff(
+ struct trailing_array_1 *normal,
+ struct trailing_array_2 *trailing_1,
+ struct trailing_array_3 *trailing_0,
+ struct trailing_array_4 *trailing_flex)
+{
+ normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */
+ trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */
+ trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */
+ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */
+
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c
new file mode 100644
index 0000000..f63206e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c
@@ -0,0 +1,39 @@
+/* Test -fstrict-flex-arrays + -Warray-bounds. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds" } */
+
+struct trailing_array_1 {
+ int a;
+ int b;
+ int c[4];
+};
+
+struct trailing_array_2 {
+ int a;
+ int b;
+ int c[1];
+};
+
+struct trailing_array_3 {
+ int a;
+ int b;
+ int c[0];
+};
+struct trailing_array_4 {
+ int a;
+ int b;
+ int c[];
+};
+
+void __attribute__((__noinline__)) stuff(
+ struct trailing_array_1 *normal,
+ struct trailing_array_2 *trailing_1,
+ struct trailing_array_3 *trailing_0,
+ struct trailing_array_4 *trailing_flex)
+{
+ normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */
+ trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of" } */
+ trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */
+ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */
+
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c
new file mode 100644
index 0000000..e327371
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c
@@ -0,0 +1,39 @@
+/* Test -fstrict-flex-arrays + -Warray-bounds. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds" } */
+
+struct trailing_array_1 {
+ int a;
+ int b;
+ int c[4];
+};
+
+struct trailing_array_2 {
+ int a;
+ int b;
+ int c[1];
+};
+
+struct trailing_array_3 {
+ int a;
+ int b;
+ int c[0];
+};
+struct trailing_array_4 {
+ int a;
+ int b;
+ int c[];
+};
+
+void __attribute__((__noinline__)) stuff(
+ struct trailing_array_1 *normal,
+ struct trailing_array_2 *trailing_1,
+ struct trailing_array_3 *trailing_0,
+ struct trailing_array_4 *trailing_flex)
+{
+ normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */
+ trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */
+ trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */
+ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript" } */
+
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c
new file mode 100644
index 0000000..cabaea7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c
@@ -0,0 +1,39 @@
+/* Test -fstrict-flex-arrays + -Warray-bounds=2. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds=2" } */
+
+struct trailing_array_1 {
+ int a;
+ int b;
+ int c[4];
+};
+
+struct trailing_array_2 {
+ int a;
+ int b;
+ int c[1];
+};
+
+struct trailing_array_3 {
+ int a;
+ int b;
+ int c[0];
+};
+struct trailing_array_4 {
+ int a;
+ int b;
+ int c[];
+};
+
+void __attribute__((__noinline__)) stuff(
+ struct trailing_array_1 *normal,
+ struct trailing_array_2 *trailing_1,
+ struct trailing_array_3 *trailing_0,
+ struct trailing_array_4 *trailing_flex)
+{
+ normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */
+ trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */
+ trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */
+ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */
+
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c
new file mode 100644
index 0000000..8b7db6e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c
@@ -0,0 +1,39 @@
+/* Test -fstrict-flex-arrays + -Warray-bounds=2. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds=2" } */
+
+struct trailing_array_1 {
+ int a;
+ int b;
+ int c[4];
+};
+
+struct trailing_array_2 {
+ int a;
+ int b;
+ int c[1];
+};
+
+struct trailing_array_3 {
+ int a;
+ int b;
+ int c[0];
+};
+struct trailing_array_4 {
+ int a;
+ int b;
+ int c[];
+};
+
+void __attribute__((__noinline__)) stuff(
+ struct trailing_array_1 *normal,
+ struct trailing_array_2 *trailing_1,
+ struct trailing_array_3 *trailing_0,
+ struct trailing_array_4 *trailing_flex)
+{
+ normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */
+ trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */
+ trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */
+ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */
+
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c
new file mode 100644
index 0000000..035bf48
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c
@@ -0,0 +1,39 @@
+/* Test -fstrict-flex-arrays + -Warray-bounds=2. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds=2" } */
+
+struct trailing_array_1 {
+ int a;
+ int b;
+ int c[4];
+};
+
+struct trailing_array_2 {
+ int a;
+ int b;
+ int c[1];
+};
+
+struct trailing_array_3 {
+ int a;
+ int b;
+ int c[0];
+};
+struct trailing_array_4 {
+ int a;
+ int b;
+ int c[];
+};
+
+void __attribute__((__noinline__)) stuff(
+ struct trailing_array_1 *normal,
+ struct trailing_array_2 *trailing_1,
+ struct trailing_array_3 *trailing_0,
+ struct trailing_array_4 *trailing_flex)
+{
+ normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */
+ trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */
+ trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */
+ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */
+
+}
diff --git a/gcc/testsuite/gcc.dg/Wdangling-pointer-pr106868.c b/gcc/testsuite/gcc.dg/Wdangling-pointer-pr106868.c
new file mode 100644
index 0000000..f782a5e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wdangling-pointer-pr106868.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O -Wdangling-pointer" } */
+
+void alloc(void **p);
+void false_dangling(char **p)
+{
+ {
+ void *q;
+ alloc(&q);
+ *p = q;
+ }
+ char *a = __builtin_memcpy(*p, "", 1);
+ *a = 0; /* { dg-bogus "dangling" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Wformat-overflow1.c b/gcc/testsuite/gcc.dg/Wformat-overflow1.c
new file mode 100644
index 0000000..cf9766f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wformat-overflow1.c
@@ -0,0 +1,28 @@
+/*
+ { dg-do compile }
+ { dg-options "-Wformat-overflow -std=c2x" }
+*/
+
+extern int sprintf (char* restrict, const char* restrict, ...);
+
+void test_warn () {
+
+ int n = __INT_MAX__;
+ char dst [5] = {0};
+ sprintf (dst, "%b", n); /* { dg-warning "-Wformat-overflow" } */
+
+ sprintf (dst, "%#b", n); /* { dg-warning "-Wformat-overflow" } */
+
+}
+
+void test_no_warn () {
+
+ char dst [5] = {0};
+ int n = 8;
+ sprintf (dst, "%b", n);
+
+ char another_dst [34] = {0};
+ n = __INT_MAX__;
+ sprintf (another_dst, "%#b", n);
+
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-pr106904.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-pr106904.c
new file mode 100644
index 0000000..15e67c2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-pr106904.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wstringop-overflow -fno-vect-cost-model" } */
+
+struct windowpos
+{
+ int hwnd;
+ int hwnd2;
+};
+
+struct packed_windowpos
+{
+ int hwnd;
+ int pad1;
+ int hwnd2;
+ int pad2;
+};
+
+struct packed_structs
+{
+ struct packed_windowpos wp;
+};
+
+void func(struct packed_structs *ps)
+{
+ struct windowpos wp;
+
+ wp.hwnd = ps->wp.hwnd;
+ wp.hwnd2 = ps->wp.hwnd2;
+ __builtin_memcpy(&ps->wp, &wp, sizeof(wp)); /* { dg-bogus "into a region" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
index 2ef5ccd..19932d0 100644
--- a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
+++ b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
@@ -4,6 +4,11 @@
{ dg-do compile }
{ dg-options "-O2 -Wall" } */
+/* pr102706: disabled warnings because the now-disabled conditions for the
+ bogus warnings to come up do not take cost analysis into account, and often
+ come up wrong. */
+/* { dg-additional-options "-Wno-stringop-overflow" } */
+
void sink (void*);
struct A { int i; };
@@ -87,7 +92,8 @@ void test_C_global_buf (void)
p->b1.a[ 1].i = 0; // { dg-warning "\\\[-Wzero-length-bounds" }
sink (p);
- p->b2.a[ 0].i = 0; // { dg-warning "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v2si_store_align && { ! vect_slp_v4si_store_unalign } } } }
+ p->b2.a[ 0].i = 0; // { dg-bogus "\\\[-Wstringop-overflow" "pr102706" }
+ // { xfail { vect_slp_v2si_store_align && { ! vect_slp_v4si_store_unalign } } }
p->b2.a[ 1].i = 0;
p->b2.a[ 2].i = 0; // { dg-warning "\\\[-Warray-bounds" }
p->b2.a[ 3].i = 0; // { dg-warning "\\\[-Warray-bounds" }
@@ -117,7 +123,8 @@ void test_C_local_buf (void)
p->b1.a[ 1].i = 8; // { dg-warning "\\\[-Wzero-length-bounds" }
sink (p);
- p->b2.a[ 0].i = 9;
+ p->b2.a[ 0].i = 9; // { dg-bogus "\\\[-Wstringop-overflow" "pr102706" }
+ // { xfail { vect_slp_v2si_store_align && { ! vect_slp_v4si_store_unalign } } }
p->b2.a[ 1].i = 10;
p->b2.a[ 2].i = 11; // { dg-warning "\\\[-Warray-bounds" }
p->b2.a[ 3].i = 12; // { dg-warning "\\\[-Warray-bounds" }
diff --git a/gcc/testsuite/gcc.dg/analyzer/CWE-131-examples.c b/gcc/testsuite/gcc.dg/analyzer/CWE-131-examples.c
new file mode 100644
index 0000000..3bc898c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/CWE-131-examples.c
@@ -0,0 +1,146 @@
+/* Examples adapted from https://cwe.mitre.org/data/definitions/131.html
+ which states "Copyright © 2006–2022, The MITRE Corporation. CWE, CWSS, CWRAF, and the CWE logo are trademarks of The MITRE Corporation."
+ and which has this on:
+ https://cwe.mitre.org/about/termsofuse.html
+
+ Terms of Use
+
+ CWE™ is free to use by any organization or individual for any research, development, and/or commercial purposes, per these CWE Terms of Use. The MITRE Corporation ("MITRE") has copyrighted the CWE List, Top 25, CWSS, and CWRAF for the benefit of the community in order to ensure each remains a free and open standard, as well as to legally protect the ongoing use of it and any resulting content by government, vendors, and/or users. CWE is a trademark of MITRE. Please contact cwe@mitre.org if you require further clarification on this issue.
+
+ LICENSE
+
+ CWE Submissions: By submitting materials to The MITRE Corporation’s ("MITRE") Common Weakness Enumeration Program (CWE™), you hereby grant to MITRE a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to use, reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute your submitted materials and derivative works. Unless otherwise required by applicable law or agreed to in writing, it is understood that you are providing such materials on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
+
+ CWE Usage: MITRE hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy.
+
+ DISCLAIMERS
+
+ ALL DOCUMENTS AND THE INFORMATION CONTAINED IN THE CWE ARE PROVIDED ON AN "AS IS" BASIS AND THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE MITRE CORPORATION, ITS BOARD OF TRUSTEES, OFFICERS, AGENTS, AND EMPLOYEES, DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION THEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+
+ IN NO EVENT SHALL THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE MITRE CORPORATION, ITS BOARD OF TRUSTEES, OFFICERS, AGENTS, AND EMPLOYEES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE INFORMATION OR THE USE OR OTHER DEALINGS IN THE CWE. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Support decls for example 1. */
+
+extern unsigned int GetUntrustedSizeValue();
+extern void ExitError(const char *) __attribute__((noreturn));
+
+typedef struct Widget
+{
+} Widget;
+
+#define MAX_NUM_WIDGETS 100
+
+extern Widget *InitializeWidget();
+extern void showWidgets(Widget **);
+
+void example_1 (void)
+{
+ int i;
+ unsigned int numWidgets;
+ Widget **WidgetList;
+
+ numWidgets = GetUntrustedSizeValue();
+ if ((numWidgets == 0) || (numWidgets > MAX_NUM_WIDGETS)) {
+ ExitError("Incorrect number of widgets requested!");
+ }
+ WidgetList = (Widget **)malloc(numWidgets * sizeof(Widget *));
+ printf("WidgetList ptr=%p\n", WidgetList);
+ for(i=0; i<numWidgets; i++) {
+ WidgetList[i] = InitializeWidget(); /* { dg-warning "dereference of possibly-NULL 'WidgetList'" } */
+ }
+ WidgetList[numWidgets] = NULL; /* { dg-warning "heap-based buffer overflow" } */
+ showWidgets(WidgetList);
+}
+
+/* Support decls for example 2. */
+
+typedef struct img_t
+{
+ char placeholder[1024];
+} img_t;
+
+extern int get_num_imgs();
+
+img_t *example_2 (void)
+{
+ img_t *table_ptr; /*struct containing img data, 10kB each*/
+ int num_imgs;
+ /* ... */
+ num_imgs = get_num_imgs();
+ table_ptr = (img_t*)malloc(sizeof(img_t)*num_imgs); /* TODO: ideally we'd warn about possible overflow here. */
+ /* ... */
+ return table_ptr;
+}
+
+/* Support decls for example 3. */
+
+#define MAX_SIZE 100
+extern void die(const char *) __attribute__((noreturn));
+
+char * example_3 (char *user_supplied_string)
+{
+ int i, dst_index;
+ char *dst_buf = (char*)malloc(4*sizeof(char) * MAX_SIZE);
+ if ( MAX_SIZE <= strlen(user_supplied_string) ){
+ die("user string too long, die evil hacker!");
+ }
+ dst_index = 0;
+ for ( i = 0; i < strlen(user_supplied_string); i++ ){
+ if( '&' == user_supplied_string[i] ){
+ dst_buf[dst_index++] = '&'; /* { dg-warning "dereference of possibly-NULL 'dst_buf'" } */
+ dst_buf[dst_index++] = 'a';
+ dst_buf[dst_index++] = 'm';
+ dst_buf[dst_index++] = 'p';
+ dst_buf[dst_index++] = ';'; /* TODO: ideally we'd warn about possible out-of-bounds write here. */
+ }
+ else if ('<' == user_supplied_string[i] ){
+ /* encode to &lt; */
+ }
+ else dst_buf[dst_index++] = user_supplied_string[i]; /* { dg-warning "dereference of possibly-NULL 'dst_buf'" } */
+ }
+ return dst_buf;
+}
+
+/* Support decls for example 4. */
+
+typedef struct DataPacket { int headers; } DataPacket;
+typedef struct PacketHeader {} PacketHeader;
+extern int AcceptSocketConnection();
+extern void ReadPacket(DataPacket *, int);
+extern void ParsePacketHeaders(DataPacket *, PacketHeader *);
+
+void example_4 (DataPacket *packet)
+{
+ int sock;
+
+ int numHeaders;
+ PacketHeader *headers;
+
+ sock=AcceptSocketConnection();
+ ReadPacket(packet, sock);
+ numHeaders =packet->headers;
+
+ if (numHeaders > 100) {
+ ExitError("too many headers!");
+ }
+ headers = malloc(numHeaders * sizeof(PacketHeader)); /* TODO: ideally we'd warn about possible overflow here with negative numHeaders. */
+ ParsePacketHeaders(packet, headers);
+}
+
+void example_5 (void)
+{
+ int *id_sequence;
+
+ /* Allocate space for an array of three ids. */
+ id_sequence = (int*) malloc(3); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */
+ if (id_sequence == NULL) exit(1);
+
+ /* Populate the id array. */
+ id_sequence[0] = 13579; /* { dg-warning "heap-based buffer overflow" } */
+ id_sequence[1] = 24680; /* { dg-warning "heap-based buffer overflow" } */
+ id_sequence[2] = 97531; /* { dg-warning "heap-based buffer overflow" } */
+} /* { dg-warning "leak of 'id_sequence'" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/aliasing-pr106473.c b/gcc/testsuite/gcc.dg/analyzer/aliasing-pr106473.c
new file mode 100644
index 0000000..afd1492
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/aliasing-pr106473.c
@@ -0,0 +1,5 @@
+void foo(char **args[], int *argc)
+{
+ *argc = 1;
+ (*args)[0] = __builtin_malloc(42);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c b/gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c
index 42c39e2..2cf64e9 100644
--- a/gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c
+++ b/gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c
@@ -1,3 +1,6 @@
+/* { dg-additional-options "-fanalyzer-fine-grained" }
+ -fanalyzer-fine-grained is currently required; see PR analyzer/107851. */
+
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-3.c b/gcc/testsuite/gcc.dg/analyzer/allocation-size-3.c
index 9590e31..6751441 100644
--- a/gcc/testsuite/gcc.dg/analyzer/allocation-size-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/allocation-size-3.c
@@ -1,3 +1,6 @@
+/* { dg-additional-options "-fanalyzer-fine-grained" }
+ -fanalyzer-fine-grained is currently required; see PR analyzer/107851. */
+
/* { dg-additional-options -Wno-analyzer-out-of-bounds } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-4.c b/gcc/testsuite/gcc.dg/analyzer/allocation-size-4.c
index 235c156..a56b25b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/allocation-size-4.c
+++ b/gcc/testsuite/gcc.dg/analyzer/allocation-size-4.c
@@ -56,6 +56,6 @@ void test_5 (void)
free (ptr);
/* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc5 } */
- /* { dg-message "1 bytes" "note" { target *-*-* } malloc5 } */
+ /* { dg-message "allocated 1 byte here" "note" { target *-*-* } malloc5 } */
/* { dg-message "'struct base \\*' here; 'sizeof \\(struct base\\)' is '\\d+'" "note" { target *-*-* } malloc5 } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-1.c b/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-1.c
new file mode 100644
index 0000000..7251665
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-1.c
@@ -0,0 +1,59 @@
+/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
+
+#include <stdint.h>
+
+void test_constant_1 (void)
+{
+ int32_t *ptr = __builtin_malloc (1); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */
+ __builtin_free (ptr);
+}
+
+/* { dg-begin-multiline-output "" }
+ int32_t *ptr = __builtin_malloc (1);
+ ^~~~~~~~~~~~~~~~~~~~
+ 'test_constant_1': events 1-2
+ |
+ | int32_t *ptr = __builtin_malloc (1);
+ | ^~~~~~~~~~~~~~~~~~~~
+ | |
+ | (1) allocated 1 byte here
+ | (2) assigned to 'int32_t *'
+ |
+ { dg-end-multiline-output "" } */
+
+void test_constant_2 (void)
+{
+ int32_t *ptr = __builtin_malloc (2); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */
+ __builtin_free (ptr);
+}
+
+/* { dg-begin-multiline-output "" }
+ int32_t *ptr = __builtin_malloc (2);
+ ^~~~~~~~~~~~~~~~~~~~
+ 'test_constant_2': events 1-2
+ |
+ | int32_t *ptr = __builtin_malloc (2);
+ | ^~~~~~~~~~~~~~~~~~~~
+ | |
+ | (1) allocated 2 bytes here
+ | (2) assigned to 'int32_t *'
+ |
+ { dg-end-multiline-output "" } */
+
+void test_symbolic (int n)
+{
+ int32_t *ptr = __builtin_malloc (n * 2); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */
+ __builtin_free (ptr);
+}
+
+/* { dg-begin-multiline-output "" }
+ int32_t *ptr = __builtin_malloc (n * 2);
+ ^~~~~~~~~~~~~~~~~~~~~~~~
+ 'test_symbolic': event 1
+ |
+ | int32_t *ptr = __builtin_malloc (n * 2);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~
+ | |
+ | (1) allocated 'n * 2' bytes and assigned to 'int32_t *'
+ |
+ { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-2.c b/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-2.c
new file mode 100644
index 0000000..7cadbb7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-2.c
@@ -0,0 +1,62 @@
+/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret -fanalyzer-fine-grained" } */
+/* { dg-require-effective-target alloca } */
+
+#include <stdint.h>
+
+void test_constant_1 (void)
+{
+ int32_t *ptr = __builtin_alloca (1); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */
+}
+
+/* { dg-begin-multiline-output "" }
+ int32_t *ptr = __builtin_alloca (1);
+ ^~~~~~~~~~~~~~~~~~~~
+ 'test_constant_1': events 1-2
+ |
+ | int32_t *ptr = __builtin_alloca (1);
+ | ^~~~~~~~~~~~~~~~~~~~
+ | |
+ | (1) allocated 1 byte here
+ | (2) assigned to 'int32_t *'
+ |
+ { dg-end-multiline-output "" } */
+
+void test_constant_2 (void)
+{
+ int32_t *ptr = __builtin_alloca (2); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */
+}
+
+/* { dg-begin-multiline-output "" }
+ int32_t *ptr = __builtin_alloca (2);
+ ^~~~~~~~~~~~~~~~~~~~
+ 'test_constant_2': events 1-2
+ |
+ | int32_t *ptr = __builtin_alloca (2);
+ | ^~~~~~~~~~~~~~~~~~~~
+ | |
+ | (1) allocated 2 bytes here
+ | (2) assigned to 'int32_t *'
+ |
+ { dg-end-multiline-output "" } */
+
+void test_symbolic (int n)
+{
+ int32_t *ptr = __builtin_alloca (n * 2); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */
+}
+
+/* { dg-begin-multiline-output "" }
+ int32_t *ptr = __builtin_alloca (n * 2);
+ ^~~~~~~~~~~~~~~~~~~~~~~~
+ 'test_symbolic': events 1-2
+ |
+ | int32_t *ptr = __builtin_alloca (n * 2);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~
+ | |
+ | (1) allocated 'n * 2' bytes here
+ | (2) assigned to 'int32_t *'
+ |
+ { dg-end-multiline-output "" } */
+
+/* FIXME: am getting a duplicate warning here for some reason
+ without -fanalyzer-fine-grained (PR PR analyzer/107851). */
+
diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer-debugging-fns-1.c b/gcc/testsuite/gcc.dg/analyzer/analyzer-debugging-fns-1.c
new file mode 100644
index 0000000..6a23344
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/analyzer-debugging-fns-1.c
@@ -0,0 +1,11 @@
+/* Various wrong declarations for the decls
+ in analyzer-decls.h.
+
+ Make sure we don't ICE on these. */
+
+extern void __analyzer_dump_capacity (int);
+
+void wrong_analyzer_dump_capacity (void)
+{
+ __analyzer_dump_capacity (42);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h
index 4478d74..d9a32ed 100644
--- a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h
+++ b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h
@@ -31,6 +31,9 @@ extern void __analyzer_dump_escaped (void);
will also dump all of the states within those nodes. */
extern void __analyzer_dump_exploded_nodes (int);
+/* Emit a warning describing what is known about the value of NAME. */
+extern void __analyzer_dump_named_constant (const char *name);
+
/* Emit a placeholder "note" diagnostic with a path to this call site,
if the analyzer finds a feasible path to it. */
extern void __analyzer_dump_path (void);
diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-const-3.c b/gcc/testsuite/gcc.dg/analyzer/attr-const-3.c
index 2e6ccda..fc8527a 100644
--- a/gcc/testsuite/gcc.dg/analyzer/attr-const-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/attr-const-3.c
@@ -1,7 +1,7 @@
/* Verify that we handle unknown values passed to __attribute__ ((const))
(by imposing a complexity limit). */
-/* { dg-additional-options "--param analyzer-max-svalue-depth=0" } */
+/* { dg-additional-options "--param analyzer-max-svalue-depth=4" } */
#include "analyzer-decls.h"
diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-nonnull-pr106325.c b/gcc/testsuite/gcc.dg/analyzer/attr-nonnull-pr106325.c
new file mode 100644
index 0000000..3b26471
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/attr-nonnull-pr106325.c
@@ -0,0 +1,250 @@
+typedef long int signed_frame_t;
+
+typedef struct Track Track;
+typedef struct ZRegion ZRegion;
+typedef struct AutomationTrack AutomationTrack;
+typedef struct MidiNote MidiNote;
+typedef struct ArrangerObject ArrangerObject;
+typedef struct Project Project;
+typedef struct ZRegion ZRegion;
+typedef struct Position Position;
+typedef struct Track Track;
+typedef struct ClipEditor ClipEditor;
+
+typedef enum ArrangerObjectType
+{
+ /* .... */
+ ARRANGER_OBJECT_TYPE_REGION,
+ ARRANGER_OBJECT_TYPE_MIDI_NOTE,
+ /* .... */
+} ArrangerObjectType;
+
+typedef enum ArrangerObjectPositionType
+{
+ ARRANGER_OBJECT_POSITION_TYPE_START,
+ ARRANGER_OBJECT_POSITION_TYPE_END,
+ ARRANGER_OBJECT_POSITION_TYPE_CLIP_START,
+ ARRANGER_OBJECT_POSITION_TYPE_LOOP_START,
+ ARRANGER_OBJECT_POSITION_TYPE_LOOP_END,
+ ARRANGER_OBJECT_POSITION_TYPE_FADE_IN,
+ ARRANGER_OBJECT_POSITION_TYPE_FADE_OUT,
+} ArrangerObjectPositionType;
+
+typedef struct Position
+{
+ /* .... */
+ double ticks;
+ /* .... */
+} Position;
+
+typedef enum RegionType
+{
+ /* .... */
+ REGION_TYPE_AUTOMATION = 1 << 2,
+ /* .... */
+} RegionType;
+
+typedef struct RegionIdentifier
+{
+ /* .... */
+ RegionType type;
+ /* .... */
+ int lane_pos;
+ /* .... */
+} RegionIdentifier;
+
+typedef struct ArrangerObject
+{
+ /* .... */
+
+ ArrangerObjectType type;
+ /* .... */
+ Position pos;
+ Position end_pos;
+ Position clip_start_pos;
+
+ Position loop_start_pos;
+ Position loop_end_pos;
+
+ Position fade_in_pos;
+ Position fade_out_pos;
+
+ /* .... */
+} ArrangerObject;
+
+typedef struct ZRegion
+{
+ /* .... */
+ RegionIdentifier id;
+ /* .... */
+ int num_midi_notes;
+ /* .... */
+} ZRegion;
+
+typedef struct Zrythm
+{
+ /* ... */
+ Project *project;
+ /* ... */
+} Zrythm;
+
+typedef struct Project
+{
+ /* ... */
+
+ ClipEditor *clip_editor;
+
+ /* ... */
+} Project;
+
+extern Zrythm *zrythm;
+
+extern void g_return_if_fail_warning (const char *log_domain,
+ const char *pretty_function,
+ const char *expression);
+extern void position_add_ticks (Position *self, double ticks);
+extern _Bool
+arranger_object_is_position_valid (const ArrangerObject *const self,
+ const Position *pos,
+ ArrangerObjectPositionType pos_type);
+extern Track *arranger_object_get_track (const ArrangerObject *const self);
+extern void midi_region_insert_midi_note (ZRegion *region, MidiNote *midi_note,
+ int idx, int pub_events);
+extern ZRegion *midi_note_get_region (MidiNote *self);
+extern AutomationTrack *
+region_get_automation_track (const ZRegion *const region);
+extern void track_add_region (Track *track, ZRegion *region,
+ AutomationTrack *at, int lane_pos, int gen_name,
+ int fire_events);
+extern void clip_editor_set_region (ClipEditor *self, ZRegion *region,
+ _Bool fire_events);
+extern ZRegion *clip_editor_get_region (ClipEditor *self);
+
+static Position *
+get_position_ptr (ArrangerObject *self, ArrangerObjectPositionType pos_type)
+{
+ switch (pos_type)
+ {
+ case ARRANGER_OBJECT_POSITION_TYPE_START:
+ return &self->pos;
+ case ARRANGER_OBJECT_POSITION_TYPE_END:
+ return &self->end_pos;
+ case ARRANGER_OBJECT_POSITION_TYPE_CLIP_START:
+ return &self->clip_start_pos;
+ case ARRANGER_OBJECT_POSITION_TYPE_LOOP_START:
+ return &self->loop_start_pos;
+ case ARRANGER_OBJECT_POSITION_TYPE_LOOP_END:
+ return &self->loop_end_pos;
+ case ARRANGER_OBJECT_POSITION_TYPE_FADE_IN:
+ return &self->fade_in_pos;
+ case ARRANGER_OBJECT_POSITION_TYPE_FADE_OUT:
+ return &self->fade_out_pos;
+ }
+ return (((void *)0));
+}
+
+void
+arranger_object_set_position (ArrangerObject *self, const Position *pos,
+ ArrangerObjectPositionType pos_type,
+ const int validate)
+{
+ if (!(self && pos))
+ {
+ g_return_if_fail_warning ("zrythm", ((const char *)(__func__)),
+ "self && pos");
+ return;
+ }
+
+ if (validate && !arranger_object_is_position_valid (self, pos, pos_type))
+ return;
+
+ Position *pos_ptr;
+ pos_ptr = get_position_ptr (self, pos_type);
+ if (!pos_ptr)
+ {
+ g_return_if_fail_warning ("zrythm", ((const char *)(__func__)),
+ "pos_ptr");
+ return;
+ }
+ *(pos_ptr) = *(pos);
+}
+
+void
+arranger_object_end_pos_setter (ArrangerObject *self, const Position *pos)
+{
+ arranger_object_set_position (self, pos, ARRANGER_OBJECT_POSITION_TYPE_END,
+ 1);
+}
+
+ArrangerObject *
+arranger_object_clone (const ArrangerObject *self)
+{
+ if (!self)
+ {
+ g_return_if_fail_warning ("zrythm", ((const char *)(__func__)), "self");
+ return (((void *)0));
+ }
+ /* .... */
+ return (((void *)0));
+}
+
+__attribute__((nonnull(1, 2)))
+void
+arranger_object_unsplit (ArrangerObject *r1, ArrangerObject *r2,
+ ArrangerObject **obj, _Bool fire_events)
+{
+ ZRegion *clip_editor_region
+ = clip_editor_get_region (((zrythm)->project->clip_editor));
+
+ _Bool set_clip_editor_region = 0;
+ if (clip_editor_region == (ZRegion *)r1
+ || clip_editor_region == (ZRegion *)r2)
+ {
+ set_clip_editor_region = 1;
+ clip_editor_set_region (((zrythm)->project->clip_editor), ((void *)0),
+ 1);
+ }
+
+ *obj = arranger_object_clone (r1);
+
+ arranger_object_end_pos_setter (*obj, &r2->end_pos);
+ Position fade_out_pos;
+ *(&fade_out_pos) = *(&r2->end_pos);
+ position_add_ticks (&fade_out_pos, -r2->pos.ticks);
+ arranger_object_set_position (*obj, &fade_out_pos,
+ ARRANGER_OBJECT_POSITION_TYPE_FADE_OUT, 0);
+
+ switch (r1->type) /* { dg-bogus "dereference of NULL 'r1'" } */
+ {
+ case ARRANGER_OBJECT_TYPE_REGION:
+ {
+ ZRegion *r1_region = (ZRegion *)r1;
+ AutomationTrack *at = ((void *)0);
+ if (r1_region->id.type == REGION_TYPE_AUTOMATION)
+ {
+ at = region_get_automation_track (r1_region);
+ }
+ track_add_region (arranger_object_get_track (r1), (ZRegion *)*obj, at,
+ ((ZRegion *)r1)->id.lane_pos, 1, fire_events);
+ }
+ break;
+ case ARRANGER_OBJECT_TYPE_MIDI_NOTE:
+ {
+ ZRegion *parent_region = midi_note_get_region (((MidiNote *)r1));
+ midi_region_insert_midi_note (
+ parent_region, (MidiNote *)*obj,
+ ((ZRegion *)(parent_region))->num_midi_notes, 1);
+ }
+ break;
+ default:
+ break;
+ }
+
+ switch (r1->type) /* { dg-bogus "dereference of NULL 'r1'" } */
+ {
+ /* .... */
+ default:
+ break;
+ }
+ /* .... */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/attribute-nonnull.c b/gcc/testsuite/gcc.dg/analyzer/attribute-nonnull.c
index 70bb921..7c71a71 100644
--- a/gcc/testsuite/gcc.dg/analyzer/attribute-nonnull.c
+++ b/gcc/testsuite/gcc.dg/analyzer/attribute-nonnull.c
@@ -1,3 +1,5 @@
+#include "analyzer-decls.h"
+
#include <stdlib.h>
extern void foo(void *ptrA, void *ptrB, void *ptrC) /* { dg-message "argument 1 of 'foo' must be non-null" } */
@@ -81,3 +83,19 @@ void test_5 (void *q, void *r)
free(p);
}
+
+__attribute__((nonnull(1, 3)))
+void test_6 (void *p, void *q, void *r)
+{
+ __analyzer_eval (p != NULL); /* { dg-warning "TRUE" } */
+ __analyzer_eval (q != NULL); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (r != NULL); /* { dg-warning "TRUE" } */
+}
+
+__attribute__((nonnull))
+void test_7 (void *p, void *q, void *r)
+{
+ __analyzer_eval (p != NULL); /* { dg-warning "TRUE" } */
+ __analyzer_eval (q != NULL); /* { dg-warning "TRUE" } */
+ __analyzer_eval (r != NULL); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c b/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c
index 85cece7..22ca475 100644
--- a/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c
+++ b/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c
@@ -329,7 +329,8 @@ int test_returns_element_ptr (int j)
__analyzer_eval (*returns_element_ptr (0) == 7); /* { dg-warning "TRUE" } */
__analyzer_eval (*returns_element_ptr (1) == 8); /* { dg-warning "TRUE" } */
__analyzer_eval (*returns_element_ptr (2) == 9); /* { dg-warning "TRUE" } */
- return *returns_element_ptr (3); /* { dg-warning "buffer overread" } */
+ return *returns_element_ptr (3); /* { dg-warning "buffer over-read" } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[2\\\]'" "valid subscript note" { target *-*-* } .-1 } */
}
int returns_offset (int arr[3], int i)
@@ -465,7 +466,7 @@ int test_returns_external_result (void)
int uses_alloca (int i)
{
- int *p = alloca (sizeof (int));
+ int *p = __builtin_alloca (sizeof (int));
*p = i;
return *p;
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-errno.c b/gcc/testsuite/gcc.dg/analyzer/call-summaries-errno.c
new file mode 100644
index 0000000..e4333b3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/call-summaries-errno.c
@@ -0,0 +1,17 @@
+/* { dg-additional-options "-fanalyzer-call-summaries" } */
+
+#include <errno.h>
+#include "analyzer-decls.h"
+
+void sets_errno (int x)
+{
+ errno = x;
+}
+
+void test_sets_errno (int y)
+{
+ sets_errno (y);
+ sets_errno (y);
+
+ __analyzer_eval (errno == y); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-23.c b/gcc/testsuite/gcc.dg/analyzer/data-model-23.c
index c76dd4e..d10dd05 100644
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-23.c
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-23.c
@@ -24,3 +24,14 @@ void test_2 (void)
__analyzer_eval (hide (NULL) - 1 == NULL); /* { dg-warning "FALSE" } */
__analyzer_eval (hide (NULL) + 1 == NULL); /* { dg-warning "FALSE" } */
}
+
+void test_3 (void *p)
+{
+ if (!p)
+ return;
+ __analyzer_eval (hide (p) == NULL); /* { dg-warning "FALSE" } */
+ __analyzer_eval (hide (p) + 1 != NULL); /* { dg-warning "TRUE" } */
+ __analyzer_eval (hide (p) + 1 == NULL); /* { dg-warning "FALSE" } */
+ __analyzer_eval (hide (p) - 1 != NULL); /* { dg-warning "TRUE" } */
+ __analyzer_eval (hide (p) - 1 == NULL); /* { dg-warning "FALSE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-1.c b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-1.c
new file mode 100644
index 0000000..e1c7a00
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-1.c
@@ -0,0 +1,169 @@
+#define NULL ((void *)0)
+
+int test_from_pr77432 (int *a)
+{
+ int b = *a; /* { dg-message "pointer 'a' is dereferenced here" } */
+ if (a) /* { dg-warning "check of 'a' for NULL after already dereferencing it \\\[-Wanalyzer-deref-before-check\\\]" "warning" } */
+ /* { dg-message "pointer 'a' is checked for NULL here but it was already dereferenced at \\(1\\)" "final event" { target *-*-* } .-1 } */
+ return b;
+ return 0;
+}
+
+int test_1a (int *p, int x)
+{
+ *p = x; /* { dg-message "pointer 'p' is dereferenced here" } */
+
+ if (p) /* { dg-warning "check of 'p' for NULL after already dereferencing it \\\[-Wanalyzer-deref-before-check\\\]" "warning" } */
+ /* { dg-message "pointer 'p' is checked for NULL here but it was already dereferenced at \\(1\\)" "final event" { target *-*-* } .-1 } */
+ return 1;
+ else
+ return 0;
+}
+
+int test_1b (int *p, int *q)
+{
+ *q = *p; /* { dg-message "8: pointer 'p' is dereferenced here" } */
+
+ if (p) /* { dg-warning "check of 'p' for NULL after already dereferencing it \\\[-Wanalyzer-deref-before-check\\\]" "warning" } */
+ /* { dg-message "pointer 'p' is checked for NULL here but it was already dereferenced at \\(1\\)" "final event" { target *-*-* } .-1 } */
+ return 1;
+ else
+ return 0;
+}
+
+struct s2
+{
+ int x;
+ int y;
+};
+
+int test_2a (struct s2 *p)
+{
+ int sum = p->x + p->y; /* { dg-message "pointer 'p' is dereferenced here" } */
+ if (!p) /* { dg-warning "check of 'p' for NULL after already dereferencing it" } */
+ __builtin_abort ();
+ return sum;
+}
+
+int test_2b (struct s2 *p)
+{
+ if (!p)
+ __builtin_abort ();
+ int sum = p->x + p->y;
+ return sum;
+}
+
+struct s3
+{
+ int flag;
+};
+
+extern void err (const char *);
+
+void test_3 (struct s3 *p)
+{
+ if (p->flag) /* { dg-message "pointer 'p' is dereferenced here" } */
+ err ("p->flag");
+ if (!p) /* { dg-warning "check of 'p' for NULL after already dereferencing it" } */
+ err ("p was NULL");
+}
+
+struct s4
+{
+ struct s4 *m_next;
+ int m_val;
+};
+
+int test_4 (struct s4 *p)
+{
+ if (p->m_next->m_val > 0) /* { dg-message "pointer '\\*p.m_next' is dereferenced here" } */
+ return -1;
+ if (!p->m_next) /* { dg-warning "check of '\\*p.m_next' for NULL after already dereferencing it" } */
+ return -2;
+ return p->m_next->m_val;
+}
+
+struct s5
+{
+ const char *str;
+ int val;
+};
+
+int test_5 (struct s5 *p)
+{
+ __builtin_printf ("%s: %i\n", p->str, p->val); /* { dg-message "pointer 'p' is dereferenced here" } */
+ if (p != NULL) /* { dg-warning "check of 'p' for NULL after already dereferencing it" } */
+ return p->val;
+ return -1;
+}
+
+static int __attribute__((noinline))
+__analyzer_check_ptr (int *p)
+{
+ if (p)
+ return *p;
+ else
+ return 42;
+}
+
+int test_calling_check_ptr_after_deref_1 (int *q)
+{
+ int v = *q; /* { dg-bogus "dereferenced here" } */
+ v += __analyzer_check_ptr (q);
+ return v;
+}
+
+int test_calling_check_ptr_after_deref_2 (int *q)
+{
+ int v = *q; /* { dg-bogus "dereferenced here" } */
+ v += __analyzer_check_ptr (q);
+ *q = 17;
+ return v;
+}
+
+int test_calling_check_ptr_after_deref_3 (int *q)
+{
+ int v = *q; /* { dg-message "pointer 'q' is dereferenced here" } */
+ v += __analyzer_check_ptr (q);
+ if (q) /* { dg-warning "check of 'q' for NULL after already dereferencing it" } */
+ *q = 17;
+ return v;
+}
+
+static int __attribute__((noinline))
+__analyzer_deref_ptr (int *p)
+{
+ return *p;
+}
+
+int test_calling_check_ptr_after_calling_deref_1 (int *q)
+{
+ int v = __analyzer_deref_ptr (q);
+ v += __analyzer_check_ptr (q);
+ return v;
+}
+
+int test_calling_check_ptr_after_calling_deref_2 (int *q)
+{
+ int v = __analyzer_deref_ptr (q);
+ v += __analyzer_check_ptr (q);
+ *q = 17;
+ return v;
+}
+
+int test_calling_check_ptr_after_calling_deref_3 (int *q)
+{
+ int v = __analyzer_deref_ptr (q);
+ v += __analyzer_check_ptr (q);
+ if (q)
+ *q = 17;
+ return v;
+}
+
+int test_checking_ptr_after_calling_deref (int *q)
+{
+ int v = __analyzer_deref_ptr (q);
+ if (q)
+ return 0;
+ return v;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-2.c b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-2.c
new file mode 100644
index 0000000..c0409c4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-2.c
@@ -0,0 +1,130 @@
+#include <stdio.h>
+
+struct st
+{
+ char *str;
+ int i;
+};
+
+int test_1 (struct st *p)
+{
+ fprintf (stderr, "str: %s\n", p->str); /* { dg-message "pointer 'p' is dereferenced here" } */
+ if (!p) /* { dg-warning "check of 'p' for NULL after already dereferencing it" } */
+ return -1;
+ return p->i;
+}
+
+int test_2 (int flag_a, int flag_b, struct st *p)
+{
+ if (flag_a)
+ {
+ int j = p->i; /* { dg-message "pointer 'p' is dereferenced here" } */
+ if (flag_b && p) /* { dg-warning "check of 'p' for NULL after already dereferencing it" } */
+ return 1;
+ return j;
+ }
+ return 2;
+}
+
+int test_3 (struct st *a, struct st *b)
+{
+ if (!a)
+ return b->i;
+ if (!b)
+ return a->i;
+ return 0;
+}
+
+int test_4 (struct st *p)
+{
+ int *q = &p->i;
+ if (!p)
+ return -1;
+ return *q;
+}
+
+void test_check_after_strlen (const char *str)
+{
+ size_t len_a = __builtin_strlen (str); /* { dg-message "pointer 'str' is dereferenced here" } */
+ size_t len_b = str ? __builtin_strlen (str) : 0; /* { dg-warning "check of 'str' for NULL after already dereferencing it" } */
+}
+
+void test_6 (struct st *a, struct st *b)
+{
+ int diff = a->i - b->i; /* { dg-message "pointer 'b' is dereferenced here" } */
+
+ /* ... */
+
+ if (b) /* { dg-warning "check of 'b' for NULL after already dereferencing it" } */
+ fprintf (stderr, "str: %s\n", b->str);
+}
+
+void test_check_after_strcmp (const char *s1, const char *s2)
+{
+ if (!__builtin_strcmp (s1, s2)) /* { dg-message "pointer 's1' is dereferenced here" } */
+ return;
+
+ /* ... */
+
+ if (s1) /* { dg-warning "check of 's1' for NULL after already dereferencing it" } */
+ return;
+}
+
+void test_more_than_one_deref (struct st *p)
+{
+ char *str = p->str; /* { dg-message "pointer 'p' is dereferenced here" } */
+ int i = p->i;
+
+ /* ... */
+
+ if (p) /* { dg-warning "check of 'p' for NULL after already dereferencing it" } */
+ return;
+
+ /* ... */
+}
+
+void test_deref_under_another_name (struct st *p)
+{
+ struct st *q = p;
+ int i = q->i; /* { dg-message "pointer 'p' is dereferenced here" } */
+
+ /* ... */
+
+ if (p) /* { dg-warning "check of 'p' for NULL after already dereferencing it" } */
+ return;
+
+ /* ... */
+}
+
+void test_check_after_memcpy_src (struct st *dst, struct st *src)
+{
+ __builtin_memcpy (dst, src, sizeof (struct st)); /* { dg-message "pointer 'src' is dereferenced here" } */
+
+ /* ... */
+
+ if (!src) /* { dg-warning "check of 'src' for NULL after already dereferencing it" } */
+ return;
+
+ /* ... */
+}
+
+void test_check_after_memcpy_dst (struct st *dst, struct st *src)
+{
+ __builtin_memcpy (dst, src, sizeof (struct st)); /* { dg-message "pointer 'dst' is dereferenced here" } */
+
+ /* ... */
+
+ if (!dst) /* { dg-warning "check of 'dst' for NULL after already dereferencing it" } */
+ return;
+
+ /* ... */
+}
+
+void test_merger (int *p, int flag)
+{
+ int x = *p;
+ if (flag)
+ __builtin_free (p);
+ if (!flag)
+ __builtin_free (p); /* { dg-bogus "double-'free'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr77425.c b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr77425.c
new file mode 100644
index 0000000..1ceea97
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr77425.c
@@ -0,0 +1,43 @@
+/* Fixed in r7-2945-g61f46d0e6dd568.
+ Simplified from gcc/ipa-devirt.c. */
+
+#define NULL ((void *)0)
+typedef struct odr_type_d {
+ /* .... */
+ int id;
+ /* .... */
+} *odr_type;
+static odr_type **odr_types_ptr;
+#define odr_types (*odr_types_ptr) /* { dg-message "pointer 'odr_types_ptr' is dereferenced here" } */
+
+int cond, other_cond;
+
+odr_type some_logic ();
+
+odr_type
+get_odr_type (/* ... */)
+{
+ /* .... */
+ odr_type val = NULL;
+ /* .... */
+
+ val = some_logic ();
+
+ /* .... */
+ if (cond)
+ {
+ /* .... */
+ }
+ else if (other_cond)
+ {
+ odr_types[val->id] = 0; /* { dg-message "in expansion of macro 'odr_types'" } */
+ /* .... */
+ if (odr_types_ptr) /* { dg-warning "check of 'odr_types_ptr' for NULL after already dereferencing it" } */
+ {
+ /* .... */
+ val->id = 42;
+ }
+ /* .... */
+ }
+ return val;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/errno-1.c b/gcc/testsuite/gcc.dg/analyzer/errno-1.c
new file mode 100644
index 0000000..6b9d28c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/errno-1.c
@@ -0,0 +1,23 @@
+#include <errno.h>
+#include "analyzer-decls.h"
+
+extern void external_fn (void);
+
+int test_reading_errno (void)
+{
+ return errno;
+}
+
+void test_setting_errno (int val)
+{
+ errno = val;
+}
+
+void test_storing_to_errno (int val)
+{
+ __analyzer_eval (errno == val); /* { dg-warning "UNKNOWN" } */
+ errno = val;
+ __analyzer_eval (errno == val); /* { dg-warning "TRUE" } */
+ external_fn ();
+ __analyzer_eval (errno == val); /* { dg-warning "UNKNOWN" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/errno-___errno.c b/gcc/testsuite/gcc.dg/analyzer/errno-___errno.c
new file mode 100644
index 0000000..17ff8b7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/errno-___errno.c
@@ -0,0 +1,29 @@
+#include "analyzer-decls.h"
+
+/* According to PR 107807 comment #2, Solaris implements "errno"
+ like this: */
+
+extern int *___errno(void) __attribute__((__const__));
+#define errno (*(___errno()))
+
+
+extern void external_fn (void);
+
+int test_reading_errno (void)
+{
+ return errno;
+}
+
+void test_setting_errno (int val)
+{
+ errno = val;
+}
+
+void test_storing_to_errno (int val)
+{
+ __analyzer_eval (errno == val); /* { dg-warning "UNKNOWN" } */
+ errno = val;
+ __analyzer_eval (errno == val); /* { dg-warning "TRUE" } */
+ external_fn ();
+ __analyzer_eval (errno == val); /* { dg-warning "UNKNOWN" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/errno-__error.c b/gcc/testsuite/gcc.dg/analyzer/errno-__error.c
new file mode 100644
index 0000000..19bc4f9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/errno-__error.c
@@ -0,0 +1,28 @@
+#include "analyzer-decls.h"
+
+/* According to PR 107807 comment #2, OS X implements "errno"
+ like this: */
+
+extern int * __error(void);
+#define errno (*__error())
+
+extern void external_fn (void);
+
+int test_reading_errno (void)
+{
+ return errno;
+}
+
+void test_setting_errno (int val)
+{
+ errno = val;
+}
+
+void test_storing_to_errno (int val)
+{
+ __analyzer_eval (errno == val); /* { dg-warning "UNKNOWN" } */
+ errno = val;
+ __analyzer_eval (errno == val); /* { dg-warning "TRUE" } */
+ external_fn ();
+ __analyzer_eval (errno == val); /* { dg-warning "UNKNOWN" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/errno-global-var.c b/gcc/testsuite/gcc.dg/analyzer/errno-global-var.c
new file mode 100644
index 0000000..fdf1b17
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/errno-global-var.c
@@ -0,0 +1,26 @@
+#include "analyzer-decls.h"
+
+/* "errno" declared as a global var. */
+
+extern int errno;
+
+extern void external_fn (void);
+
+int test_reading_errno (void)
+{
+ return errno;
+}
+
+void test_setting_errno (int val)
+{
+ errno = val;
+}
+
+void test_storing_to_errno (int val)
+{
+ __analyzer_eval (errno == val); /* { dg-warning "UNKNOWN" } */
+ errno = val;
+ __analyzer_eval (errno == val); /* { dg-warning "TRUE" } */
+ external_fn ();
+ __analyzer_eval (errno == val); /* { dg-warning "UNKNOWN" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/errno-pr107777.c b/gcc/testsuite/gcc.dg/analyzer/errno-pr107777.c
new file mode 100644
index 0000000..6568739
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/errno-pr107777.c
@@ -0,0 +1,20 @@
+int *
+__errno_location (void);
+
+long int
+read (int, void *, unsigned long int);
+
+struct IOBUF {
+ int fd;
+};
+
+void
+do_getline_end_data (struct IOBUF *iop, int tree)
+{
+ char end_data;
+
+ if (tree)
+ *__errno_location () = 0;
+
+ read (iop->fd, &end_data, sizeof end_data);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/explode-1.c b/gcc/testsuite/gcc.dg/analyzer/explode-1.c
index 9b95afd..7d05f40 100644
--- a/gcc/testsuite/gcc.dg/analyzer/explode-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/explode-1.c
@@ -47,7 +47,8 @@ void test (void)
{
default:
case 0:
- *pp = malloc (16); /* { dg-warning "leak" } */
+ *pp = malloc (16); /* { dg-warning "leak" "" { xfail *-*-* } } */
+ // TODO: xfail
break;
case 1:
free (*pp);
diff --git a/gcc/testsuite/gcc.dg/analyzer/explode-3.c b/gcc/testsuite/gcc.dg/analyzer/explode-3.c
new file mode 100644
index 0000000..1657836
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/explode-3.c
@@ -0,0 +1,43 @@
+/* { dg-additional-options "-Wno-analyzer-too-complex" } */
+
+#include <stdlib.h>
+
+extern int get (void);
+
+/* In theory each of p0...p1 can be in various malloc states,
+ independently, so the total combined number of states
+ at any program point within the loop is NUM_VARS * NUM_STATES. */
+
+void test (void)
+{
+ void *p0, *p1;
+ void **pp;
+ while (get ())
+ {
+ switch (get ())
+ {
+ default:
+ case 0:
+ pp = &p0;
+ break;
+ case 1:
+ pp = &p1;
+ break;
+ }
+
+ switch (get ())
+ {
+ default:
+ case 0:
+ *pp = malloc (16); /* { dg-warning "leak" "" { xfail *-*-* } } */
+ // TODO: xfail
+ break;
+ case 1:
+ free (*pp);
+ break;
+ case 2:
+ /* no-op. */
+ break;
+ }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-4.c b/gcc/testsuite/gcc.dg/analyzer/fd-4.c
index 842a26b..994bad8 100644
--- a/gcc/testsuite/gcc.dg/analyzer/fd-4.c
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-4.c
@@ -8,6 +8,7 @@ void close(int fd);
int write (int fd, void *buf, int nbytes);
int read (int fd, void *buf, int nbytes);
+#define O_ACCMODE 0xf
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-accept.c b/gcc/testsuite/gcc.dg/analyzer/fd-accept.c
new file mode 100644
index 0000000..1b25012
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-accept.c
@@ -0,0 +1,76 @@
+/* { dg-require-effective-target sockets } */
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include "analyzer-decls.h"
+
+int test_accept (int fd, struct sockaddr *addr, socklen_t *addrlen)
+{
+ return accept (fd, addr, addrlen);
+}
+
+void test_accept_leak_no_lhs (int fd, struct sockaddr *addr, socklen_t *addrlen)
+{
+ accept (fd, addr, addrlen); /* { dg-warning "leak of file descriptor" } */
+}
+
+void test_accept_leak_with_lhs (int fd, struct sockaddr *addr, socklen_t *addrlen)
+{
+ int newfd = accept (fd, addr, addrlen); /* { dg-message "socket created here" } */
+} /* { dg-warning "leak of file descriptor 'newfd'" } */
+
+int test_accept_null_addr (int fd)
+{
+ return accept (fd, NULL, 0);
+}
+
+int test_accept_uninit_addrlen (int fd)
+{
+ struct sockaddr_storage addr;
+ socklen_t addr_len;
+ return accept (fd, (struct sockaddr *)&addr, &addr_len); /* { dg-warning "use of uninitialized value 'addr_len'" } */
+}
+
+int test_accept_writes_to_addr_and_len (int fd)
+{
+ struct sockaddr_storage addr;
+ socklen_t addr_len = sizeof (addr);
+ __analyzer_eval (addr_len == sizeof (addr)); /* { dg-warning "TRUE" } */
+ int newfd = accept (fd, (struct sockaddr *)&addr, &addr_len);
+ if (newfd == -1)
+ return newfd;
+ /* Check that the analyzer considers addr and addr_len to
+ have been written to. */
+ __analyzer_eval (((char *)&addr)[0]); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (addr_len == sizeof (addr)); /* { dg-warning "UNKNOWN" } */
+ return newfd;
+}
+
+void test_accept_on_new_datagram_socket (void)
+{
+ int fd = socket (AF_UNIX, SOCK_DGRAM, 0);
+ if (fd == -1)
+ return;
+ accept (fd, NULL, NULL); /* { dg-message "'accept' on datagram socket file descriptor 'fd' \\\[-Wanalyzer-fd-type-mismatch\\\]" "warning" } */
+ /* { dg-message "'accept' expects a stream socket file descriptor but 'fd' is a datagram socket" "final event" { target *-*-* } .-1 } */
+ close (fd);
+}
+
+int test_accept_on_accept (int fd_a)
+{
+ int fd_b = accept (fd_a, NULL, 0);
+ if (fd_b == -1)
+ return -1;
+
+ int fd_c = accept (fd_b, NULL, 0); /* { dg-warning "'accept' on file descriptor 'fd_b' in wrong phase \\\[-Wanalyzer-fd-phase-mismatch\\\]" "warning" } */
+ /* { dg-message "'accept' expects a listening stream socket file descriptor but 'fd_b' is connected" "final event" { target *-*-* } .-1 } */
+
+ return fd_b;
+}
+
+int test_accept_on_constant ()
+{
+ return accept (0, NULL, 0);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-access-mode-enum.c b/gcc/testsuite/gcc.dg/analyzer/fd-access-mode-enum.c
new file mode 100644
index 0000000..5226569
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-access-mode-enum.c
@@ -0,0 +1,60 @@
+int open(const char *, int mode);
+void close(int fd);
+int write (int fd, void *buf, int nbytes);
+int read (int fd, void *buf, int nbytes);
+
+/* Example of these flags as an enum, and with
+ non-standard values for them. */
+
+enum {
+ O_RDONLY = 0x10,
+ O_WRONLY = 0x20,
+ O_RDWR = 0x40,
+
+ O_ACCMODE = 0xf0
+};
+
+void f (int fd) __attribute__((fd_arg(1))); /* { dg-message "argument 1 of 'f' must be an open file descriptor, due to '__attribute__\\(\\(fd_arg\\(1\\)\\)\\)'" } */
+
+void
+test_1 (const char *path)
+{
+ int fd = open (path, O_RDWR);
+ close(fd);
+ f(fd); /* { dg-warning "'f' on closed file descriptor 'fd'" } */
+ /* { dg-message "\\(3\\) 'f' on closed file descriptor 'fd'; 'close' was at \\(2\\)" "" { target *-*-* } .-1 } */
+}
+
+void g (int fd) __attribute__((fd_arg_read(1))); /* { dg-message "argument 1 of 'g' must be a readable file descriptor, due to '__attribute__\\(\\(fd_arg_read\\(1\\)\\)\\)'" } */
+
+void
+test_2 (const char *path)
+{
+ int fd = open (path, O_WRONLY);
+ if (fd != -1)
+ {
+ g (fd); /* { dg-warning "'g' on write-only file descriptor 'fd'" } */
+ }
+ close (fd);
+}
+
+void h (int fd) __attribute__((fd_arg_write(1))); /* { dg-message "argument 1 of 'h' must be a writable file descriptor, due to '__attribute__\\(\\(fd_arg_write\\(1\\)\\)\\)'" } */
+void
+test_3 (const char *path)
+{
+ int fd = open (path, O_RDONLY);
+ if (fd != -1)
+ {
+ h (fd); /* { dg-warning "'h' on read-only file descriptor 'fd'" } */
+ }
+ close(fd);
+}
+
+void ff (int fd) __attribute__((fd_arg(1))); /* { dg-message "argument 1 of 'ff' must be an open file descriptor, due to '__attribute__\\(\\(fd_arg\\(1\\)\\)\\)'" } */
+
+void test_4 (const char *path)
+{
+ int fd = open (path, O_RDWR);
+ ff (fd); /* { dg-warning "'ff' on possibly invalid file descriptor 'fd'" } */
+ close(fd);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-5.c b/gcc/testsuite/gcc.dg/analyzer/fd-access-mode-macros.c
index c18b2ad..f9a6931 100644
--- a/gcc/testsuite/gcc.dg/analyzer/fd-5.c
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-access-mode-macros.c
@@ -6,6 +6,7 @@ int read (int fd, void *buf, int nbytes);
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
+#define O_ACCMODE 0x3
void f (int fd) __attribute__((fd_arg(1))); /* { dg-message "argument 1 of 'f' must be an open file descriptor, due to '__attribute__\\(\\(fd_arg\\(1\\)\\)\\)'" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-access-mode-target-headers.c b/gcc/testsuite/gcc.dg/analyzer/fd-access-mode-target-headers.c
new file mode 100644
index 0000000..b76eb66
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-access-mode-target-headers.c
@@ -0,0 +1,56 @@
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "analyzer-decls.h"
+
+void f (int fd) __attribute__((fd_arg(1))); /* { dg-message "argument 1 of 'f' must be an open file descriptor, due to '__attribute__\\(\\(fd_arg\\(1\\)\\)\\)'" } */
+
+void
+test_1 (const char *path)
+{
+ int fd = open (path, O_RDWR);
+ close(fd);
+ f(fd); /* { dg-warning "'f' on closed file descriptor 'fd'" } */
+ /* { dg-message "\\(3\\) 'f' on closed file descriptor 'fd'; 'close' was at \\(2\\)" "" { target *-*-* } .-1 } */
+}
+
+void g (int fd) __attribute__((fd_arg_read(1))); /* { dg-message "argument 1 of 'g' must be a readable file descriptor, due to '__attribute__\\(\\(fd_arg_read\\(1\\)\\)\\)'" } */
+
+void
+test_2 (const char *path)
+{
+ int fd = open (path, O_WRONLY);
+ if (fd != -1)
+ {
+ g (fd); /* { dg-warning "'g' on write-only file descriptor 'fd'" } */
+ }
+ close (fd);
+}
+
+void h (int fd) __attribute__((fd_arg_write(1))); /* { dg-message "argument 1 of 'h' must be a writable file descriptor, due to '__attribute__\\(\\(fd_arg_write\\(1\\)\\)\\)'" } */
+void
+test_3 (const char *path)
+{
+ int fd = open (path, O_RDONLY);
+ if (fd != -1)
+ {
+ h (fd); /* { dg-warning "'h' on read-only file descriptor 'fd'" } */
+ }
+ close(fd);
+}
+
+void ff (int fd) __attribute__((fd_arg(1))); /* { dg-message "argument 1 of 'ff' must be an open file descriptor, due to '__attribute__\\(\\(fd_arg\\(1\\)\\)\\)'" } */
+
+void test_4 (const char *path)
+{
+ int fd = open (path, O_RDWR);
+ ff (fd); /* { dg-warning "'ff' on possibly invalid file descriptor 'fd'" } */
+ close(fd);
+}
+
+void test_sm_fd_constants (void)
+{
+ __analyzer_dump_named_constant ("O_ACCMODE"); /* { dg-warning "named constant 'O_ACCMODE' has value '\[0-9\]+'" } */
+ __analyzer_dump_named_constant ("O_RDONLY"); /* { dg-warning "named constant 'O_RDONLY' has value '\[0-9\]+'" } */
+ __analyzer_dump_named_constant ("O_WRONLY"); /* { dg-warning "named constant 'O_WRONLY' has value '\[0-9\]+'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-bind-pr107783.c b/gcc/testsuite/gcc.dg/analyzer/fd-bind-pr107783.c
new file mode 100644
index 0000000..3630417
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-bind-pr107783.c
@@ -0,0 +1,5 @@
+int
+foo (void)
+{
+ return bind (0, 0, 0); /* { dg-warning "implicit declaration of function 'bind'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-bind-pr107928.c b/gcc/testsuite/gcc.dg/analyzer/fd-bind-pr107928.c
new file mode 100644
index 0000000..acc1a1d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-bind-pr107928.c
@@ -0,0 +1,10 @@
+struct sa {};
+
+int
+bind (int, struct sa *, int);
+
+int
+foo (struct sa sa)
+{
+ return bind (1, &sa, sizeof sa);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-bind.c b/gcc/testsuite/gcc.dg/analyzer/fd-bind.c
new file mode 100644
index 0000000..d027b1a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-bind.c
@@ -0,0 +1,81 @@
+/* { dg-require-effective-target sockets } */
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include "analyzer-decls.h"
+
+void test_bind (int fd, const char *sockname)
+{
+ struct sockaddr_un addr;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ if (bind (fd, (struct sockaddr *)&addr, sizeof (addr)) == -1)
+ __analyzer_dump_path (); /* { dg-message "path" } */
+ else
+ __analyzer_dump_path (); /* { dg-message "path" } */
+}
+
+void test_null_bind (int fd)
+{
+ errno = 0;
+ int result = bind (fd, NULL, 0);
+ __analyzer_eval (result == -1); /* { dg-warning "TRUE" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+}
+
+void test_double_bind (int fd, const char *sockname)
+{
+ struct sockaddr_un addr;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr));
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-warning "'bind' on file descriptor 'fd' in wrong phase \\\[-Wanalyzer-fd-phase-mismatch\\\]" "warning" } */
+ /* { dg-message "'bind' expects a new socket file descriptor but 'fd' has already been bound" "final event" { target *-*-* } .-1 } */
+}
+
+int test_uninit_addr (int fd, const char *sockname)
+{
+ struct sockaddr_un addr;
+ return bind (fd, (struct sockaddr *)&addr, sizeof (addr));
+ // TODO: complain about uninit addr.
+}
+
+void test_bind_after_connect (int fd, const char *sockname,
+ const struct sockaddr *caddr, socklen_t caddrlen)
+{
+ if (connect (fd, caddr, caddrlen) == -1)
+ return;
+
+ struct sockaddr_un addr;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr));
+ /* TODO: we don't warn for this; after the plain "connect" we're
+ in the stop state. */
+}
+
+void test_bind_after_accept (int fd, const char *sockname)
+{
+ int afd = accept (fd, NULL, NULL);
+ if (afd == -1)
+ return;
+
+ struct sockaddr_un addr;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (afd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-warning "'bind' on file descriptor 'afd' in wrong phase \\\[-Wanalyzer-fd-phase-mismatch\\\]" "warning" } */
+ /* { dg-message "'bind' expects a new socket file descriptor but 'afd' is already connected" "final event" { target *-*-* } .-1 } */
+
+ close (afd);
+}
+
+int test_bind_on_constant ()
+{
+ return bind (0, NULL, 0);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-connect-pr107928.c b/gcc/testsuite/gcc.dg/analyzer/fd-connect-pr107928.c
new file mode 100644
index 0000000..f3bdc87
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-connect-pr107928.c
@@ -0,0 +1,10 @@
+struct sa {};
+
+int
+connect (int, struct sa *, int);
+
+int
+foo (struct sa sa)
+{
+ return connect (1, &sa, sizeof sa);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-connect.c b/gcc/testsuite/gcc.dg/analyzer/fd-connect.c
new file mode 100644
index 0000000..ad837c9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-connect.c
@@ -0,0 +1,53 @@
+/* { dg-require-effective-target sockets } */
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include "analyzer-decls.h"
+
+int test_connect (int sockfd, const struct sockaddr *addr,
+ socklen_t addrlen)
+{
+ return connect (sockfd, addr, addrlen);
+}
+
+void test_null_connect (int fd)
+{
+ errno = 0;
+ int result = connect (fd, NULL, 0);
+ __analyzer_eval (result == -1); /* { dg-warning "TRUE" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+}
+
+int test_uninit_addr (int fd, const char *sockname)
+{
+ struct sockaddr_un addr;
+ return connect (fd, (struct sockaddr *)&addr, sizeof (addr));
+ // TODO: complain about uninit addr.
+}
+
+void test_connect_after_bind (const char *sockname,
+ const struct sockaddr *baddr, socklen_t baddrlen,
+ const struct sockaddr *caddr, socklen_t caddrlen)
+{
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0); /* { dg-message "stream socket created here" } */
+ if (fd == -1)
+ return;
+
+ if (bind (fd, baddr, baddrlen) == -1)
+ {
+ close (fd);
+ return;
+ }
+
+ connect (fd, caddr, caddrlen); /* { dg-warning "'connect' on file descriptor 'fd' in wrong phase" "warning" } */
+ /* { dg-message "'connect' expects a new socket file descriptor but 'fd' is bound" "final event" { target *-*-* } .-1 } */
+
+ close (fd);
+}
+
+int test_connect_on_constant ()
+{
+ return connect (0, NULL, 0);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-datagram-socket.c b/gcc/testsuite/gcc.dg/analyzer/fd-datagram-socket.c
new file mode 100644
index 0000000..5850857
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-datagram-socket.c
@@ -0,0 +1,110 @@
+/* { dg-require-effective-target sockets } */
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include "analyzer-decls.h"
+
+void test_leak_socket (void)
+{
+ int fd = socket (AF_UNIX, SOCK_DGRAM, 0); /* { dg-message "datagram socket created here" } */
+} /* { dg-warning "leak of file descriptor 'fd'" } */
+
+void test_leak_socket_no_lhs (void)
+{
+ socket (AF_UNIX, SOCK_DGRAM, 0); /* { dg-warning "leak of file descriptor" } */
+}
+
+void test_close_unchecked_socket (void)
+{
+ int fd = socket (AF_UNIX, SOCK_DGRAM, 0);
+ close (fd);
+}
+
+void test_close_checked_socket (void)
+{
+ int fd = socket (AF_UNIX, SOCK_DGRAM, 0);
+ if (fd == -1)
+ return;
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-new-datagram-socket'" } */
+ close (fd);
+}
+
+void test_leak_checked_socket (void)
+{
+ int fd = socket (AF_UNIX, SOCK_DGRAM, 0); /* { dg-message "datagram socket created here" } */
+ if (fd == -1) /* { dg-warning "leak of file descriptor 'fd'" } */
+ return;
+ // TODO: strange location for leak message
+}
+
+void test_bind (const char *sockname)
+{
+ struct sockaddr_un addr;
+ int fd = socket (AF_UNIX, SOCK_DGRAM, 0);
+ if (fd == -1)
+ return;
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-new-datagram-socket'" } */
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr));
+ close (fd);
+}
+
+void test_bind_on_unchecked_socket (const char *sockname)
+{
+ struct sockaddr_un addr;
+ int fd = socket (AF_UNIX, SOCK_DGRAM, 0); /* { dg-message "when 'socket' fails" } */
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-warning "'bind' on possibly invalid file descriptor 'fd'" } */
+ close (fd);
+}
+
+void test_leak_of_bound_socket (const char *sockname)
+{
+ struct sockaddr_un addr;
+ int fd = socket (AF_UNIX, SOCK_DGRAM, 0); /* { dg-message "datagram socket created here" } */
+ if (fd == -1)
+ return;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-warning "leak of file descriptor 'fd'" } */
+}
+
+void test_listen_on_datagram_socket_without_bind (void)
+{
+ int fd = socket (AF_UNIX, SOCK_DGRAM, 0); /* { dg-message "datagram socket created here" } */
+ if (fd == -1)
+ return;
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-new-datagram-socket'" } */
+ listen (fd, 5); /* { dg-warning "'listen' on datagram socket file descriptor 'fd' \\\[-Wanalyzer-fd-type-mismatch\\\]" "warning" } */
+ /* { dg-message "'listen' expects a stream socket file descriptor but 'fd' is a datagram socket" "final event" { target *-*-* } .-1 } */
+ close (fd);
+}
+
+void test_listen_on_datagram_socket_with_bind (const char *sockname)
+{
+ int fd = socket (AF_UNIX, SOCK_DGRAM, 0); /* { dg-message "datagram socket created here" } */
+ if (fd == -1)
+ return;
+
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-new-datagram-socket'" } */
+
+ struct sockaddr_un addr;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ if (bind (fd, (struct sockaddr *)&addr, sizeof (addr)) == -1) /* { dg message "datagram socket bound here" } */
+ {
+ close (fd);
+ return;
+ }
+ listen (fd, 5); /* { dg-warning "'listen' on datagram socket file descriptor 'fd' \\\[-Wanalyzer-fd-type-mismatch\\\]" "warning" } */
+ /* { dg-message "'listen' expects a stream socket file descriptor but 'fd' is a datagram socket" "final event" { target *-*-* } .-1 } */
+ close (fd);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-dup-1.c b/gcc/testsuite/gcc.dg/analyzer/fd-dup-1.c
index b4f43e7..bb58e9d 100644
--- a/gcc/testsuite/gcc.dg/analyzer/fd-dup-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-dup-1.c
@@ -8,6 +8,7 @@ int read (int fd, void *buf, int nbytes);
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
+#define O_ACCMODE 3
void test_1 (const char *path)
{
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-glibc-byte-stream-connection-server.c b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-byte-stream-connection-server.c
new file mode 100644
index 0000000..5a1a6f5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-byte-stream-connection-server.c
@@ -0,0 +1,134 @@
+/* Example from glibc manual (16.9.7). */
+/* { dg-require-effective-target sockets } */
+/* { dg-additional-options "-Wno-analyzer-too-complex" } */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#define PORT 5555
+#define MAXMSG 512
+
+int
+make_socket (uint16_t port)
+{
+ int sock;
+ struct sockaddr_in name;
+
+ /* Create the socket. */
+ sock = socket (PF_INET, SOCK_STREAM, 0);
+ if (sock < 0)
+ {
+ perror ("socket");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Give the socket a name. */
+ name.sin_family = AF_INET;
+ name.sin_port = htons (port);
+ name.sin_addr.s_addr = htonl (INADDR_ANY);
+ if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
+ {
+ perror ("bind");
+ exit (EXIT_FAILURE);
+ }
+
+ return sock;
+}
+
+int
+read_from_client (int filedes)
+{
+ char buffer[MAXMSG];
+ int nbytes;
+
+ nbytes = read (filedes, buffer, MAXMSG);
+ if (nbytes < 0)
+ {
+ /* Read error. */
+ perror ("read");
+ exit (EXIT_FAILURE);
+ }
+ else if (nbytes == 0)
+ /* End-of-file. */
+ return -1;
+ else
+ {
+ /* Data read. */
+ fprintf (stderr, "Server: got message: `%s'\n", buffer);
+ return 0;
+ }
+}
+
+int
+main (void)
+{
+ int sock;
+ fd_set active_fd_set, read_fd_set;
+ int i;
+ struct sockaddr_in clientname;
+ socklen_t size;
+
+ /* Create the socket and set it up to accept connections. */
+ sock = make_socket (PORT);
+ if (listen (sock, 1) < 0)
+ {
+ perror ("listen");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Initialize the set of active sockets. */
+ FD_ZERO (&active_fd_set);
+ FD_SET (sock, &active_fd_set);
+
+ while (1)
+ {
+ /* Block until input arrives on one or more active sockets. */
+ read_fd_set = active_fd_set;
+ if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
+ {
+ perror ("select");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Service all the sockets with input pending. */
+ for (i = 0; i < FD_SETSIZE; ++i)
+ if (FD_ISSET (i, &read_fd_set))
+ {
+ if (i == sock)
+ {
+ /* Connection request on original socket. */
+ int new;
+ size = sizeof (clientname);
+ new = accept (sock,
+ (struct sockaddr *) &clientname,
+ &size);
+ if (new < 0)
+ {
+ perror ("accept");
+ exit (EXIT_FAILURE);
+ }
+ fprintf (stderr,
+ "Server: connect from host %s, port %hd.\n",
+ inet_ntoa (clientname.sin_addr),
+ ntohs (clientname.sin_port));
+ FD_SET (new, &active_fd_set);
+ }
+ else
+ {
+ /* Data arriving on an already-connected socket. */
+ if (read_from_client (i) < 0)
+ {
+ close (i);
+ FD_CLR (i, &active_fd_set);
+ }
+ }
+ }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-glibc-byte-stream-socket.c b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-byte-stream-socket.c
new file mode 100644
index 0000000..806bb24
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-byte-stream-socket.c
@@ -0,0 +1,63 @@
+/* Example from glibc manual (16.9.6). */
+/* { dg-require-effective-target sockets } */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#define PORT 5555
+#define MESSAGE "Yow!!! Are we having fun yet?!?"
+#define SERVERHOST "www.gnu.org"
+
+void
+write_to_server (int filedes)
+{
+ int nbytes;
+
+ nbytes = write (filedes, MESSAGE, strlen (MESSAGE) + 1);
+ if (nbytes < 0)
+ {
+ perror ("write");
+ exit (EXIT_FAILURE);
+ }
+}
+
+
+int
+main (void)
+{
+ extern void init_sockaddr (struct sockaddr_in *name,
+ const char *hostname,
+ uint16_t port);
+ int sock;
+ struct sockaddr_in servername;
+
+ /* Create the socket. */
+ sock = socket (PF_INET, SOCK_STREAM, 0);
+ if (sock < 0)
+ {
+ perror ("socket (client)");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Connect to the server. */
+ init_sockaddr (&servername, SERVERHOST, PORT);
+ if (0 > connect (sock,
+ (struct sockaddr *) &servername,
+ sizeof (servername)))
+ {
+ perror ("connect (client)");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Send data to the server. */
+ write_to_server (sock);
+ close (sock);
+ exit (EXIT_SUCCESS);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-client.c b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-client.c
new file mode 100644
index 0000000..072ac4c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-client.c
@@ -0,0 +1,57 @@
+/* Example from the glibc manual (16.10.4). */
+/* { dg-require-effective-target sockets } */
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include "fd-glibc-make_named_socket.h"
+
+#define SERVER "/tmp/serversocket"
+#define CLIENT "/tmp/mysocket"
+#define MAXMSG 512
+#define MESSAGE "Yow!!! Are we having fun yet?!?"
+
+int
+main (void)
+{
+ int sock;
+ char message[MAXMSG];
+ struct sockaddr_un name;
+ size_t size;
+ int nbytes;
+
+ /* Make the socket. */
+ sock = make_named_socket (CLIENT);
+
+ /* Initialize the server socket address. */
+ name.sun_family = AF_LOCAL;
+ strcpy (name.sun_path, SERVER);
+ size = strlen (name.sun_path) + sizeof (name.sun_family);
+
+ /* Send the datagram. */
+ nbytes = sendto (sock, MESSAGE, strlen (MESSAGE) + 1, 0,
+ (struct sockaddr *) & name, size);
+ if (nbytes < 0)
+ {
+ perror ("sendto (client)");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Wait for a reply. */
+ nbytes = recvfrom (sock, message, MAXMSG, 0, NULL, 0);
+ if (nbytes < 0)
+ {
+ perror ("recfrom (client)");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Print a diagnostic message. */
+ fprintf (stderr, "Client: got message: %s\n", message);
+
+ /* Clean up. */
+ remove (CLIENT);
+ close (sock);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-socket.c b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-socket.c
new file mode 100644
index 0000000..d417828
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-datagram-socket.c
@@ -0,0 +1,53 @@
+/* Example from glibc manual (16.10.3). */
+/* { dg-require-effective-target sockets } */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include "fd-glibc-make_named_socket.h"
+
+#define SERVER "/tmp/serversocket"
+#define MAXMSG 512
+
+int
+main (void)
+{
+ int sock;
+ char message[MAXMSG];
+ struct sockaddr_un name;
+ socklen_t size;
+ int nbytes;
+
+ /* Remove the filename first, it’s ok if the call fails */
+ unlink (SERVER);
+
+ /* Make the socket, then loop endlessly. */
+ sock = make_named_socket (SERVER);
+ while (1)
+ {
+ /* Wait for a datagram. */
+ size = sizeof (name);
+ nbytes = recvfrom (sock, message, MAXMSG, 0,
+ (struct sockaddr *) & name, &size);
+ if (nbytes < 0)
+ {
+ perror ("recfrom (server)");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Give a diagnostic message. */
+ fprintf (stderr, "Server: got message: %s\n", message);
+
+ /* Bounce the message back to the sender. */
+ nbytes = sendto (sock, message, nbytes, 0,
+ (struct sockaddr *) & name, size);
+ if (nbytes < 0)
+ {
+ perror ("sendto (server)");
+ exit (EXIT_FAILURE);
+ }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-glibc-make_named_socket.h b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-make_named_socket.h
new file mode 100644
index 0000000..bdb6de0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-glibc-make_named_socket.h
@@ -0,0 +1,47 @@
+/* Example of Local-Namespace Sockets from the glibc manual (16.5.3). */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+int
+make_named_socket (const char *filename)
+{
+ struct sockaddr_un name;
+ int sock;
+ size_t size;
+
+ /* Create the socket. */
+ sock = socket (PF_LOCAL, SOCK_DGRAM, 0);
+ if (sock < 0)
+ {
+ perror ("socket");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Bind a name to the socket. */
+ name.sun_family = AF_LOCAL;
+ strncpy (name.sun_path, filename, sizeof (name.sun_path));
+ name.sun_path[sizeof (name.sun_path) - 1] = '\0';
+
+ /* The size of the address is
+ the offset of the start of the filename,
+ plus its length (not including the terminating null byte).
+ Alternatively you can just do:
+ size = SUN_LEN (&name);
+ */
+ size = (offsetof (struct sockaddr_un, sun_path)
+ + strlen (name.sun_path));
+
+ if (bind (sock, (struct sockaddr *) &name, size) < 0)
+ {
+ perror ("bind");
+ exit (EXIT_FAILURE);
+ }
+
+ return sock;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-listen.c b/gcc/testsuite/gcc.dg/analyzer/fd-listen.c
new file mode 100644
index 0000000..a241113
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-listen.c
@@ -0,0 +1,70 @@
+/* { dg-require-effective-target sockets } */
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include "analyzer-decls.h"
+
+int test_listen (int fd, int backlog)
+{
+ return listen (fd, backlog);
+}
+
+/* Some systems seem to allow repeated calls to listen. */
+
+void test_double_listen (int fd, int backlog)
+{
+ listen (fd, backlog);
+ listen (fd, backlog);
+}
+
+void test_listen_before_bind (int fd, const char *sockname)
+{
+ if (listen (fd, 5) == -1) /* { dg-message "stream socket marked as passive here via 'listen'" } */
+ return;
+
+ struct sockaddr_un addr;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-warning "'bind' on file descriptor 'fd' in wrong phase" "warning" } */
+ /* { dg-message "'bind' expects a new socket file descriptor but 'fd' is already listening" "final event" { target *-*-* } .-1 } */
+}
+
+void test_listen_on_unchecked_bind (int fd, const char *sockname)
+{
+ struct sockaddr_un addr;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-message "when 'bind' fails" } */
+ listen (fd, 5); /* { dg-warning "'listen' on file descriptor 'fd' in wrong phase" "warning" } */
+ /* { dg-message "'listen' expects a bound stream socket file descriptor but 'fd' has not yet been bound" "final event" { target *-*-* } .-1 } */
+ close (fd);
+}
+
+void test_listen_on_new_datagram_socket (void)
+{
+ int fd = socket (AF_UNIX, SOCK_DGRAM, 0);
+ if (fd == -1)
+ return;
+ listen (fd, 5); /* { dg-message "'listen' on datagram socket file descriptor 'fd' \\\[-Wanalyzer-fd-type-mismatch\\\]" "warning" } */
+ /* { dg-message "'listen' expects a stream socket file descriptor but 'fd' is a datagram socket" "final event" { target *-*-* } .-1 } */
+ close (fd);
+}
+
+void test_listen_on_connected_socket (int fd)
+{
+ int afd = accept (fd, NULL, 0);
+ if (afd == -1)
+ return;
+ listen (afd, 5); /* { dg-warning "'listen' on file descriptor 'afd' in wrong phase" "warning" } */
+ /* { dg-message "'listen' expects a bound stream socket file descriptor but 'afd' is connected" "final event" { target *-*-* } .-1 } */
+ close (afd);
+}
+
+int test_listen_on_constant ()
+{
+ return listen (0, 10);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-manpage-getaddrinfo-client.c b/gcc/testsuite/gcc.dg/analyzer/fd-manpage-getaddrinfo-client.c
new file mode 100644
index 0000000..ee627de
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-manpage-getaddrinfo-client.c
@@ -0,0 +1,123 @@
+/* Example from getaddrinfo.3 manpage, which has this license:
+
+Copyright (c) 2007, 2008 Michael Kerrisk <mtk.manpages@gmail.com>
+and Copyright (c) 2006 Ulrich Drepper <drepper@redhat.com>
+A few pieces of an earlier version remain:
+Copyright 2000, Sam Varshavchik <mrsam@courier-mta.com>
+
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Since the Linux kernel and libraries are constantly changing, this
+manual page may be incorrect or out-of-date. The author(s) assume no
+responsibility for errors or omissions, or for damages resulting from
+the use of the information contained herein. The author(s) may not
+have taken the same level of care in the production of this manual,
+which is licensed free of charge, as they might when working
+professionally.
+
+Formatted or processed versions of this manual, if unaccompanied by
+the source, must acknowledge the copyright and authors of this work.
+*/
+
+/* { dg-require-effective-target sockets } */
+/* { dg-additional-options "-Wno-analyzer-too-complex" } */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#define BUF_SIZE 500
+
+int
+main(int argc, char *argv[])
+{
+ struct addrinfo hints;
+ struct addrinfo *result, *rp;
+ int sfd, s;
+ size_t len;
+ ssize_t nread;
+ char buf[BUF_SIZE];
+
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s host port msg...\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ /* Obtain address(es) matching host/port. */
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
+ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
+ hints.ai_flags = 0;
+ hints.ai_protocol = 0; /* Any protocol */
+
+ s = getaddrinfo(argv[1], argv[2], &hints, &result);
+ if (s != 0) {
+ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
+ exit(EXIT_FAILURE);
+ }
+
+ /* getaddrinfo() returns a list of address structures.
+ Try each address until we successfully connect(2).
+ If socket(2) (or connect(2)) fails, we (close the socket
+ and) try the next address. */
+
+ for (rp = result; rp != NULL; rp = rp->ai_next) {
+ sfd = socket(rp->ai_family, rp->ai_socktype,
+ rp->ai_protocol);
+ if (sfd == -1)
+ continue;
+
+ if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
+ break; /* Success */
+
+ close(sfd);
+ }
+
+ freeaddrinfo(result); /* No longer needed */
+
+ if (rp == NULL) { /* No address succeeded */
+ fprintf(stderr, "Could not connect\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Send remaining command-line arguments as separate
+ datagrams, and read responses from server. */
+
+ for (int j = 3; j < argc; j++) {
+ len = strlen(argv[j]) + 1;
+ /* +1 for terminating null byte */
+
+ if (len > BUF_SIZE) {
+ fprintf(stderr,
+ "Ignoring long message in argument %d\n", j);
+ continue;
+ }
+
+ if (write(sfd, argv[j], len) != len) {
+ fprintf(stderr, "partial/failed write\n");
+ exit(EXIT_FAILURE);
+ }
+
+ nread = read(sfd, buf, BUF_SIZE);
+ if (nread == -1) {
+ perror("read");
+ exit(EXIT_FAILURE);
+ }
+
+ printf("Received %zd bytes: %s\n", nread, buf);
+ }
+
+ exit(EXIT_SUCCESS);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-mappage-getaddrinfo-server.c b/gcc/testsuite/gcc.dg/analyzer/fd-mappage-getaddrinfo-server.c
new file mode 100644
index 0000000..d2e39eb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-mappage-getaddrinfo-server.c
@@ -0,0 +1,121 @@
+/* Example from getaddrinfo.3 manpage, which has this license:
+
+Copyright (c) 2007, 2008 Michael Kerrisk <mtk.manpages@gmail.com>
+and Copyright (c) 2006 Ulrich Drepper <drepper@redhat.com>
+A few pieces of an earlier version remain:
+Copyright 2000, Sam Varshavchik <mrsam@courier-mta.com>
+
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Since the Linux kernel and libraries are constantly changing, this
+manual page may be incorrect or out-of-date. The author(s) assume no
+responsibility for errors or omissions, or for damages resulting from
+the use of the information contained herein. The author(s) may not
+have taken the same level of care in the production of this manual,
+which is licensed free of charge, as they might when working
+professionally.
+
+Formatted or processed versions of this manual, if unaccompanied by
+the source, must acknowledge the copyright and authors of this work.
+*/
+
+/* { dg-require-effective-target sockets } */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+#define BUF_SIZE 500
+
+int
+main(int argc, char *argv[])
+{
+ struct addrinfo hints;
+ struct addrinfo *result, *rp;
+ int sfd, s;
+ struct sockaddr_storage peer_addr;
+ socklen_t peer_addr_len;
+ ssize_t nread;
+ char buf[BUF_SIZE];
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s port\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
+ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
+ hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
+ hints.ai_protocol = 0; /* Any protocol */
+ hints.ai_canonname = NULL;
+ hints.ai_addr = NULL;
+ hints.ai_next = NULL;
+
+ s = getaddrinfo(NULL, argv[1], &hints, &result);
+ if (s != 0) {
+ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
+ exit(EXIT_FAILURE);
+ }
+
+ /* getaddrinfo() returns a list of address structures.
+ Try each address until we successfully bind(2).
+ If socket(2) (or bind(2)) fails, we (close the socket
+ and) try the next address. */
+
+ for (rp = result; rp != NULL; rp = rp->ai_next) {
+ sfd = socket(rp->ai_family, rp->ai_socktype,
+ rp->ai_protocol);
+ if (sfd == -1)
+ continue;
+
+ if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
+ break; /* Success */
+
+ close(sfd);
+ }
+
+ freeaddrinfo(result); /* No longer needed */
+
+ if (rp == NULL) { /* No address succeeded */
+ fprintf(stderr, "Could not bind\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Read datagrams and echo them back to sender. */
+
+ for (;;) {
+ peer_addr_len = sizeof(peer_addr);
+ nread = recvfrom(sfd, buf, BUF_SIZE, 0,
+ (struct sockaddr *) &peer_addr, &peer_addr_len);
+ if (nread == -1)
+ continue; /* Ignore failed request */
+
+ char host[NI_MAXHOST], service[NI_MAXSERV];
+
+ s = getnameinfo((struct sockaddr *) &peer_addr,
+ peer_addr_len, host, NI_MAXHOST,
+ service, NI_MAXSERV, NI_NUMERICSERV);
+ if (s == 0)
+ printf("Received %zd bytes from %s:%s\n",
+ nread, host, service);
+ else
+ fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s));
+
+ if (sendto(sfd, buf, nread, 0,
+ (struct sockaddr *) &peer_addr,
+ peer_addr_len) != nread)
+ fprintf(stderr, "Error sending response\n");
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-socket-meaning.c b/gcc/testsuite/gcc.dg/analyzer/fd-socket-meaning.c
new file mode 100644
index 0000000..82a199f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-socket-meaning.c
@@ -0,0 +1,22 @@
+/* { dg-require-effective-target sockets } */
+/* { dg-additional-options "-fanalyzer-verbose-state-changes" } */
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+
+void test_leak_unchecked_stream_socket (void)
+{
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0); /* { dg-message "meaning: \\{verb: 'acquire', noun: 'resource'\\}" } */
+} /* { dg-warning "leak of file descriptor 'fd'" } */
+
+void test_leak_unchecked_datagram_socket (void)
+{
+ int fd = socket (AF_UNIX, SOCK_DGRAM, 0); /* { dg-message "meaning: \\{verb: 'acquire', noun: 'resource'\\}" } */
+} /* { dg-warning "leak of file descriptor 'fd'" } */
+
+void test_leak_unchecked_socket (int type)
+{
+ int fd = socket (AF_UNIX, type, 0); /* { dg-message "meaning: \\{verb: 'acquire', noun: 'resource'\\}" } */
+} /* { dg-warning "leak of file descriptor 'fd'" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-socket-misuse.c b/gcc/testsuite/gcc.dg/analyzer/fd-socket-misuse.c
new file mode 100644
index 0000000..628f5e4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-socket-misuse.c
@@ -0,0 +1,100 @@
+/* Various operations done on sockets in the wrong phase. */
+
+/* { dg-require-effective-target sockets } */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include "analyzer-decls.h"
+
+void test_read_on_new_socket (void *buf)
+{
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0); /* { dg-message "stream socket created here" } */
+ if (fd == -1)
+ return;
+ read (fd, buf, 1); /* { dg-warning "'read' on file descriptor 'fd' in wrong phase \\\[-Wanalyzer-fd-phase-mismatch\\\]" "warning" } */
+ /* { dg-message "'read' expects a stream socket to be connected via 'accept' but 'fd' has not yet been bound" "final event" { target *-*-* } .-1 } */
+ close (fd);
+}
+
+void test_read_on_bound_socket (int fd, const char *sockname, void *buf)
+{
+ struct sockaddr_un addr;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ if (bind (fd, (struct sockaddr *)&addr, sizeof (addr)) == -1)
+ return;
+ /* This could be a datagram socket, so we shouldn't complain here. */
+ read (fd, buf, 1);
+}
+
+void test_read_on_listening_socket (int fd, void *buf)
+{
+ if (listen (fd, 5) == -1) /* { dg-message "stream socket marked as passive here via 'listen'" } */
+ return;
+ read (fd, buf, 1); /* { dg-message "'read' on file descriptor 'fd' in wrong phase" "warning" } */
+ /* { dg-message "'read' expects a stream socket to be connected via the return value of 'accept' but 'fd' is listening; wrong file descriptor\\\?" "final event" { target *-*-* } .-1 } */
+}
+
+void test_bind_on_non_socket (const char *filename, const char *sockname)
+{
+ int fd = open (filename, O_RDONLY);
+ if (fd == -1)
+ return;
+
+ struct sockaddr_un addr;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ int result = bind (fd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-warning "'bind' on non-socket file descriptor 'fd' \\\[-Wanalyzer-fd-type-mismatch\\\]" "warning" } */
+ /* { dg-message "'bind' expects a socket file descriptor but 'fd' is not a socket" "final event" { target *-*-* } .-1 } */
+ __analyzer_eval (result == -1); /* { dg-warning "TRUE" } */
+
+ close (fd);
+}
+
+void test_passive_open_read_on_wrong_socket (int sfd)
+{
+ int cfd = accept (sfd, NULL, NULL);
+ write (sfd, "hello", 6); /* { dg-warning "'write' on file descriptor 'sfd' in wrong phase" "warning" } */
+ /* { dg-message "'write' expects a stream socket to be connected via the return value of 'accept' but 'sfd' is listening; wrong file descriptor\\\?" "final event" { target *-*-* } .-1 } */
+ close (cfd);
+}
+
+void test_listen_on_new_stream_socket (void)
+{
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ return;
+ listen (fd, 5); /* { dg-message "'listen' on file descriptor 'fd' in wrong phase" "warning" } */
+ /* { dg-message "'listen' expects a bound stream socket file descriptor but 'fd' has not yet been bound" "final event" { target *-*-* } .-1 } */
+ close (fd);
+}
+
+void test_accept_on_new_stream_socket (void)
+{
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ return;
+ accept (fd, NULL, NULL); /* { dg-message "'accept' on file descriptor 'fd' in wrong phase" "warning" } */
+ /* { dg-message "'accept' expects a listening stream socket file descriptor but 'fd' has not yet been bound" "final event" { target *-*-* } .-1 } */
+ close (fd);
+}
+
+void test_listen_before_bind (int fd, const char *sockname)
+{
+ if (listen (fd, 5) == -1) /* { dg-message "stream socket marked as passive here via 'listen'" } */
+ return;
+
+ struct sockaddr_un addr;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-warning "'bind' on file descriptor 'fd' in wrong phase" "warning" } */
+ /* { dg-message "'bind' expects a new socket file descriptor but 'fd' is already listening" "final event" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-active-open.c b/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-active-open.c
new file mode 100644
index 0000000..89ea82e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-active-open.c
@@ -0,0 +1,107 @@
+/* { dg-require-effective-target sockets } */
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include "analyzer-decls.h"
+
+void test_active_open_from_scratch (const char *sockname, void *buf)
+{
+ errno = 0;
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-invalid'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-new-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+
+ struct sockaddr_un addr;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+
+ errno = 0;
+ if (connect (fd, (struct sockaddr *)&addr, sizeof (addr)) == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-new-stream-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-connected-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+
+ write (fd, "hello", 6);
+ read (fd, buf, 100);
+
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+}
+
+void test_active_open_from_connect (int fd, const char *sockname, void *buf)
+{
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'start'" } */
+
+ struct sockaddr_un addr;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+
+ errno = 0;
+ if (connect (fd, (struct sockaddr *)&addr, sizeof (addr)) == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-new-unknown-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-stop'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+
+ write (fd, "hello", 6);
+ read (fd, buf, 100);
+
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-stop'" } */
+}
+
+void test_active_open_from_connect_constant (const char *sockname, void *buf)
+{
+ const int fd = 42;
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-constant'" } */
+
+ struct sockaddr_un addr;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+
+ errno = 0;
+ if (connect (fd, (struct sockaddr *)&addr, sizeof (addr)) == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-constant'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-stop'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+
+ write (fd, "hello", 6);
+ read (fd, buf, 100);
+
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-stop'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-passive-open.c b/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-passive-open.c
new file mode 100644
index 0000000..8af5290
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-passive-open.c
@@ -0,0 +1,297 @@
+/* Verify the various states when performing a passive open,
+ either from scratch, or when various phases are assumed to already
+ be done. */
+
+/* { dg-require-effective-target sockets } */
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include "analyzer-decls.h"
+
+void test_passive_open_from_scratch (const char *sockname, void *buf)
+{
+ struct sockaddr_un addr;
+ int afd;
+ errno = 0;
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-invalid'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-new-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ errno = 0;
+ if (bind (fd, (struct sockaddr *)&addr, sizeof (addr)) == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-new-stream-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-bound-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ if (listen (fd, 5) == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-bound-stream-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ afd = accept (fd, NULL, NULL);
+ if (afd == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-connected-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (afd >= 0); /* { dg-warning "TRUE" } */
+
+ write (afd, "hello", 6);
+ read (afd, buf, 100);
+
+ close (afd);
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-closed'" } */
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+}
+
+void test_passive_open_from_bind (int fd, const char *sockname, void *buf)
+{
+ struct sockaddr_un addr;
+ int afd;
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'start'" } */
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ errno = 0;
+ if (bind (fd, (struct sockaddr *)&addr, sizeof (addr)) == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-new-unknown-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-bound-unknown-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ if (listen (fd, 5) == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-bound-unknown-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ afd = accept (fd, NULL, NULL);
+ if (afd == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-connected-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (afd >= 0); /* { dg-warning "TRUE" } */
+
+ write (afd, "hello", 6);
+ read (afd, buf, 100);
+
+ close (afd);
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-closed'" } */
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+}
+
+void test_passive_open_from_bind_constant (const char *sockname, void *buf)
+{
+ const int fd = 42;
+ struct sockaddr_un addr;
+ int afd;
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-constant'" } */
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ errno = 0;
+ if (bind (fd, (struct sockaddr *)&addr, sizeof (addr)) == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-constant'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-bound-unknown-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ if (listen (fd, 5) == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-bound-unknown-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ afd = accept (fd, NULL, NULL);
+ if (afd == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-connected-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (afd >= 0); /* { dg-warning "TRUE" } */
+
+ write (afd, "hello", 6);
+ read (afd, buf, 100);
+
+ close (afd);
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-closed'" } */
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+}
+
+void test_passive_open_from_listen (int fd, void *buf)
+{
+ int afd;
+ errno = 0;
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'start'" } */
+ if (listen (fd, 5) == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-bound-stream-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ afd = accept (fd, NULL, NULL);
+ if (afd == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-connected-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (afd >= 0); /* { dg-warning "TRUE" } */
+
+ write (afd, "hello", 6);
+ read (afd, buf, 100);
+
+ close (afd);
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-closed'" } */
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+}
+
+
+void test_passive_open_from_listen_constant (void *buf)
+{
+ const int fd = 42;
+ int afd;
+ errno = 0;
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-constant'" } */
+ if (listen (fd, 5) == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-constant'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ afd = accept (fd, NULL, NULL);
+ if (afd == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-connected-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (afd >= 0); /* { dg-warning "TRUE" } */
+
+ write (afd, "hello", 6);
+ read (afd, buf, 100);
+
+ close (afd);
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-closed'" } */
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+}
+
+void test_passive_open_from_accept (int fd, void *buf)
+{
+ int afd;
+ errno = 0;
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'start'" } */
+ afd = accept (fd, NULL, NULL);
+ if (afd == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-connected-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (afd >= 0); /* { dg-warning "TRUE" } */
+
+ write (afd, "hello", 6);
+ read (afd, buf, 100);
+
+ close (afd);
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-closed'" } */
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket.c b/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket.c
new file mode 100644
index 0000000..e51f0f0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket.c
@@ -0,0 +1,100 @@
+/* { dg-require-effective-target sockets } */
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include "analyzer-decls.h"
+
+void test_leak_socket (void)
+{
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0); /* { dg-message "stream socket created here" } */
+} /* { dg-warning "leak of file descriptor 'fd'" } */
+
+void test_leak_socket_no_lhs (void)
+{
+ socket (AF_UNIX, SOCK_STREAM, 0); /* { dg-warning "leak of file descriptor" } */
+}
+
+void test_close_unchecked_socket (void)
+{
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ close (fd);
+}
+
+void test_close_checked_socket (void)
+{
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ return;
+ close (fd);
+}
+
+void test_leak_checked_socket (void)
+{
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0); /* { dg-message "stream socket created here" } */
+ if (fd == -1) /* { dg-warning "leak of file descriptor 'fd'" } */
+ return;
+ // TODO: strange location for leak message
+}
+
+void test_bind_on_checked_socket (const char *sockname)
+{
+ struct sockaddr_un addr;
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ return;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr));
+ close (fd);
+}
+
+void test_bind_on_unchecked_socket (const char *sockname)
+{
+ struct sockaddr_un addr;
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0); /* { dg-message "when 'socket' fails" } */
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-warning "'bind' on possibly invalid file descriptor 'fd'" } */
+ close (fd);
+}
+
+void test_leak_of_bound_socket (const char *sockname)
+{
+ struct sockaddr_un addr;
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0); /* { dg-message "stream socket created here" } */
+ if (fd == -1)
+ return;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-warning "leak of file descriptor 'fd'" } */
+}
+
+void test_listen_without_bind (void)
+{
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0); /* { dg-message "stream socket created here" } */
+ if (fd == -1)
+ return;
+ listen (fd, 5); /* { dg-warning "'listen' on file descriptor 'fd' in wrong phase" "warning" } */
+ /* { dg-message "'listen' expects a bound stream socket file descriptor but 'fd' has not yet been bound" "final event" { target *-*-* } .-1 } */
+ close (fd);
+}
+
+void test_listen_on_unchecked_bind (const char *sockname)
+{
+ struct sockaddr_un addr;
+ int fd = socket (AF_UNIX, SOCK_STREAM, 0); /* { dg-message "stream socket created here" } */
+ if (fd == -1)
+ return;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-message "when 'bind' fails" } */
+ listen (fd, 5); /* { dg-warning "'listen' on file descriptor 'fd' in wrong phase" "warning" } */
+ /* { dg-message "'listen' expects a bound stream socket file descriptor but 'fd' has not yet been bound" "final event" { target *-*-* } .-1 } */
+ close (fd);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-symbolic-socket.c b/gcc/testsuite/gcc.dg/analyzer/fd-symbolic-socket.c
new file mode 100644
index 0000000..ad1f989
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-symbolic-socket.c
@@ -0,0 +1,100 @@
+/* { dg-require-effective-target sockets } */
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include "analyzer-decls.h"
+
+void test_leak_socket (int type)
+{
+ int fd = socket (AF_UNIX, type, 0); /* { dg-message "socket created here" } */
+} /* { dg-warning "leak of file descriptor 'fd'" } */
+
+void test_leak_socket_no_lhs (int type)
+{
+ socket (AF_UNIX, type, 0); /* { dg-warning "leak of file descriptor" } */
+}
+
+void test_close_unchecked_socket (int type)
+{
+ int fd = socket (AF_UNIX, type, 0);
+ close (fd);
+}
+
+void test_close_checked_socket (int type)
+{
+ int fd = socket (AF_UNIX, type, 0);
+ if (fd == -1)
+ return;
+ close (fd);
+}
+
+void test_leak_checked_socket (int type)
+{
+ int fd = socket (AF_UNIX, type, 0); /* { dg-message "socket created here" } */
+ if (fd == -1) /* { dg-warning "leak of file descriptor 'fd'" } */
+ return;
+ // TODO: strange location for leak message
+}
+
+void test_bind_on_checked_socket (int type, const char *sockname)
+{
+ struct sockaddr_un addr;
+ int fd = socket (AF_UNIX, type, 0);
+ if (fd == -1)
+ return;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr));
+ close (fd);
+}
+
+void test_bind_on_unchecked_socket (int type, const char *sockname)
+{
+ struct sockaddr_un addr;
+ int fd = socket (AF_UNIX, type, 0); /* { dg-message "when 'socket' fails" } */
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-warning "'bind' on possibly invalid file descriptor 'fd'" } */
+ close (fd);
+}
+
+void test_leak_of_bound_socket (int type, const char *sockname)
+{
+ struct sockaddr_un addr;
+ int fd = socket (AF_UNIX, type, 0); /* { dg-message "socket created here" } */
+ if (fd == -1)
+ return;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-warning "leak of file descriptor 'fd'" } */
+}
+
+void test_listen_without_bind (int type)
+{
+ int fd = socket (AF_UNIX, type, 0);
+ if (fd == -1)
+ return;
+ listen (fd, 5); /* { dg-warning "'listen' on file descriptor 'fd' in wrong phase" } */
+ /* { dg-message "'listen' expects a bound stream socket file descriptor but 'fd' has not yet been bound" "msg" { target *-*-* } .-1 } */
+ close (fd);
+}
+
+void test_listen_on_unchecked_bind (int type, const char *sockname)
+{
+ struct sockaddr_un addr;
+ int fd = socket (AF_UNIX, type, 0);
+ if (fd == -1)
+ return;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-message "when 'bind' fails" } */
+ listen (fd, 5); /* { dg-warning "'listen' on file descriptor 'fd' in wrong phase" "warning" } */
+ /* { dg-message "'listen' expects a bound stream socket file descriptor but 'fd' has not yet been bound" "msg" { target *-*-* } .-1 } */
+ close (fd);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fdump-analyzer-1.c b/gcc/testsuite/gcc.dg/analyzer/fdump-analyzer-1.c
new file mode 100644
index 0000000..8962adb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fdump-analyzer-1.c
@@ -0,0 +1,14 @@
+/* { dg-additional-options "-fdump-analyzer" } */
+
+void test (void)
+{
+}
+
+/* Verify that we log the named constants that we look up in the TU
+ (before the analysis pass runs).
+ { dg-final { scan-file fdump-analyzer-1.c.analyzer.txt "maybe_stash_named_constant: name: 'O_ACCMODE'" } }
+
+ Verify that we log the main part of the analysis (part of the
+ analysis pass):
+ { dg-final { scan-file fdump-analyzer-1.c.analyzer.txt "ana::run_checkers" } }
+ */
diff --git a/gcc/testsuite/gcc.dg/analyzer/feasibility-4.c b/gcc/testsuite/gcc.dg/analyzer/feasibility-4.c
new file mode 100644
index 0000000..1a11280
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/feasibility-4.c
@@ -0,0 +1,42 @@
+#include "analyzer-decls.h"
+
+extern int rand (void);
+
+void test_1 (void)
+{
+ int ret = 0;
+ while (ret != 42)
+ ret = rand() % 1000;
+
+ if (ret != 42)
+ __analyzer_dump_path (); /* { dg-bogus "path" } */
+}
+
+static void empty_local_fn (void) {}
+extern void external_fn (void);
+
+void test_2 (void)
+{
+ void (*callback) () = empty_local_fn;
+ int ret = 0;
+ while (ret != 42)
+ ret = rand() % 1000;
+
+ (*callback) ();
+
+ if (ret != 42)
+ __analyzer_dump_path (); /* { dg-bogus "path" } */
+}
+
+void test_3 (void)
+{
+ void (*callback) () = external_fn;
+ int ret = 0;
+ while (ret != 42)
+ ret = rand() % 1000;
+
+ (*callback) ();
+
+ if (ret != 42)
+ __analyzer_dump_path (); /* { dg-bogus "path" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/feasibility-pr107582-1.c b/gcc/testsuite/gcc.dg/analyzer/feasibility-pr107582-1.c
new file mode 100644
index 0000000..15799d0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/feasibility-pr107582-1.c
@@ -0,0 +1,43 @@
+/* { dg-require-effective-target pthread } */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "analyzer-decls.h"
+
+int z;
+
+static void func(void * o)
+{
+ (void) o;
+}
+
+int main(int argc,
+ int ** argv)
+{
+ struct timespec now;
+
+ int * x;
+ int ret = 0;
+
+ pthread_cleanup_push(func, NULL);
+
+ while (ret != ETIMEDOUT)
+ ret = rand() % 1000;
+
+ if (ret != ETIMEDOUT)
+ x = &z;
+
+ pthread_cleanup_pop(1);
+
+ if (ret == ETIMEDOUT)
+ return 0;
+
+ __analyzer_dump_path (); /* { dg-bogus "path" } */
+ printf("x = %d\n", *x); /* { dg-bogus "use of uninitialized value 'x'" } */
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/feasibility-pr107582-2.c b/gcc/testsuite/gcc.dg/analyzer/feasibility-pr107582-2.c
new file mode 100644
index 0000000..b86ffd8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/feasibility-pr107582-2.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "analyzer-decls.h"
+
+int z;
+
+static void func(void)
+{
+}
+
+int main(int argc,
+ int ** argv)
+{
+ int * x;
+ int ret = 0;
+ void (*callback) () = func;
+
+ while (ret != 110)
+ ret = rand() % 1000;
+
+ if (ret != 110)
+ x = &z;
+
+ (*callback) ();
+
+ if (ret == 110)
+ return 0;
+
+ __analyzer_dump_path (); /* { dg-bogus "path" } */
+ printf("x = %d\n", *x); /* { dg-bogus "use of uninitialized value 'x'" } */
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/feasibility-pr107948.c b/gcc/testsuite/gcc.dg/analyzer/feasibility-pr107948.c
new file mode 100644
index 0000000..5eb8b0a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/feasibility-pr107948.c
@@ -0,0 +1,49 @@
+#include "analyzer-decls.h"
+
+void foo(int width) {
+ int i = 0;
+ int base;
+ if (width > 0){
+ __analyzer_eval(i == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval(width > 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval(width - i > 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval(i - width <= 0); /* { dg-warning "TRUE" } */
+ if (i - width <= 0) {
+ base = 512;
+ }
+ else {
+ __analyzer_dump_path (); /* { dg-bogus "path" } */
+ }
+ base+=1; /* { dg-bogus "uninit" } */
+ }
+}
+
+void test_ge_zero (int x)
+{
+ if (x >= 0)
+ {
+ __analyzer_eval(x >= 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval(x > 0); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval(x <= 0); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval(x < 0); /* { dg-warning "FALSE" } */
+ __analyzer_eval(-x <= 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval(-x < 0); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval(-x >= 0); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval(-x > 0); /* { dg-warning "FALSE" } */
+ }
+}
+
+void test_gt_zero (int x)
+{
+ if (x > 0)
+ {
+ __analyzer_eval(x >= 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval(x > 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval(x <= 0); /* { dg-warning "FALSE" } */
+ __analyzer_eval(x < 0); /* { dg-warning "FALSE" } */
+ __analyzer_eval(-x <= 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval(-x < 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval(-x >= 0); /* { dg-warning "FALSE" } */
+ __analyzer_eval(-x > 0); /* { dg-warning "FALSE" } */
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/ferror-1.c b/gcc/testsuite/gcc.dg/analyzer/ferror-1.c
new file mode 100644
index 0000000..2570f08
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/ferror-1.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int test_pass_through (FILE *stream)
+{
+ return ferror (stream);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/file-CWE-1341-example.c b/gcc/testsuite/gcc.dg/analyzer/file-CWE-1341-example.c
new file mode 100644
index 0000000..2add3cb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/file-CWE-1341-example.c
@@ -0,0 +1,41 @@
+/* Example adapted from https://cwe.mitre.org/data/definitions/1341.html
+ which states "Copyright © 2006–2022, The MITRE Corporation. CWE, CWSS, CWRAF, and the CWE logo are trademarks of The MITRE Corporation."
+ and which has this on:
+ https://cwe.mitre.org/about/termsofuse.html
+
+ Terms of Use
+
+ CWE™ is free to use by any organization or individual for any research, development, and/or commercial purposes, per these CWE Terms of Use. The MITRE Corporation ("MITRE") has copyrighted the CWE List, Top 25, CWSS, and CWRAF for the benefit of the community in order to ensure each remains a free and open standard, as well as to legally protect the ongoing use of it and any resulting content by government, vendors, and/or users. CWE is a trademark of MITRE. Please contact cwe@mitre.org if you require further clarification on this issue.
+
+ LICENSE
+
+ CWE Submissions: By submitting materials to The MITRE Corporation’s ("MITRE") Common Weakness Enumeration Program (CWE™), you hereby grant to MITRE a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to use, reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute your submitted materials and derivative works. Unless otherwise required by applicable law or agreed to in writing, it is understood that you are providing such materials on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
+
+ CWE Usage: MITRE hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy.
+
+ DISCLAIMERS
+
+ ALL DOCUMENTS AND THE INFORMATION CONTAINED IN THE CWE ARE PROVIDED ON AN "AS IS" BASIS AND THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE MITRE CORPORATION, ITS BOARD OF TRUSTEES, OFFICERS, AGENTS, AND EMPLOYEES, DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION THEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+
+ IN NO EVENT SHALL THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE MITRE CORPORATION, ITS BOARD OF TRUSTEES, OFFICERS, AGENTS, AND EMPLOYEES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE INFORMATION OR THE USE OR OTHER DEALINGS IN THE CWE. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void example_1 (void)
+{
+ char b[2000];
+ FILE *f = fopen("dbl_cls.c", "r"); /* { dg-message "opened here" } */
+ if (f)
+ {
+ b[0] = 0;
+ fread(b, 1, sizeof(b) - 1, f);
+ printf("%s\n'", b);
+ int r1 = fclose(f); /* { dg-message "first 'fclose' here" } */
+ printf("\n-----------------\n1 close done '%d'\n", r1);
+
+ int r2 = fclose(f); /* { dg-warning "double 'fclose' of FILE 'f'" } */
+ printf("2 close done '%d'\n", r2);
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fileno-1.c b/gcc/testsuite/gcc.dg/analyzer/fileno-1.c
new file mode 100644
index 0000000..d34e51a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fileno-1.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int test_pass_through (FILE *stream)
+{
+ return fileno (stream);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/flex-with-call-summaries.c b/gcc/testsuite/gcc.dg/analyzer/flex-with-call-summaries.c
new file mode 100644
index 0000000..5e85809
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/flex-with-call-summaries.c
@@ -0,0 +1,1683 @@
+/* Integration test for compiling the output of a minimal "flex"
+ script. */
+
+/* { dg-additional-options "-fanalyzer-call-summaries" } */
+
+/* { dg-additional-options "-Wno-analyzer-too-complex" } */
+
+/* A lexical scanner generated by flex */
+
+#define YY_INT_ALIGNED short int
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+/* begin standard C++ headers. */
+
+/* TODO: this is always defined, so inline it */
+#define yyconst const
+
+#define yynoreturn __attribute__((__noreturn__))
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an
+ * integer in range [0..255] for use as an array index.
+ */
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern int yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+ #define YY_LINENO_REWIND_TO(ptr)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ int yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = NULL;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart ( FILE *input_file );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size );
+void yy_delete_buffer ( YY_BUFFER_STATE b );
+void yy_flush_buffer ( YY_BUFFER_STATE b );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state ( void );
+
+static void yyensure_buffer_stack ( void );
+static void yy_load_buffer_state ( void );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len );
+
+void *yyalloc ( yy_size_t );
+void *yyrealloc ( void *, yy_size_t );
+void yyfree ( void * );
+
+#define yy_new_buffer yy_create_buffer
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+typedef flex_uint8_t YY_CHAR;
+
+FILE *yyin = NULL, *yyout = NULL;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+int yylineno = 1;
+
+extern char *yytext;
+#ifdef yytext_ptr
+#undef yytext_ptr
+#endif
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state ( void );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state );
+static int yy_get_next_buffer ( void );
+static void yynoreturn yy_fatal_error ( const char* msg );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+#define YY_NUM_RULES 1
+#define YY_END_OF_BUFFER 2
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static const flex_int16_t yy_accept[6] =
+ { 0,
+ 0, 0, 2, 1, 0
+ } ;
+
+static const YY_CHAR yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static const YY_CHAR yy_meta[2] =
+ { 0,
+ 1
+ } ;
+
+static const flex_int16_t yy_base[7] =
+ { 0,
+ 0, 0, 2, 3, 3, 0
+ } ;
+
+static const flex_int16_t yy_def[7] =
+ { 0,
+ 6, 6, 5, 5, 0, 5
+ } ;
+
+static const flex_int16_t yy_nxt[5] =
+ { 0,
+ 4, 5, 3, 5
+ } ;
+
+static const flex_int16_t yy_chk[5] =
+ { 0,
+ 6, 3, 5, 5
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals ( void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy ( void );
+
+int yyget_debug ( void );
+
+void yyset_debug ( int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra ( void );
+
+void yyset_extra ( YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in ( void );
+
+void yyset_in ( FILE * _in_str );
+
+FILE *yyget_out ( void );
+
+void yyset_out ( FILE * _out_str );
+
+ int yyget_leng ( void );
+
+char *yyget_text ( void );
+
+int yyget_lineno ( void );
+
+void yyset_lineno ( int _line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap ( void );
+#else
+extern int yywrap ( void );
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+
+ static void yyunput ( int c, char *buf_ptr );
+
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy ( char *, const char *, int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen ( const char * );
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput ( void );
+#else
+static int input ( void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ int n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK /*LINTED*/break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+ }
+
+ yy_load_buffer_state( );
+ }
+
+ {
+
+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of yytext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+yy_match:
+ do
+ {
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 6 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 3 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+ECHO;
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( yywrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of user's declarations */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = (yytext_ptr);
+ int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *) /* { dg-warning "leak" } */
+ /* Include room in for 2 EOB chars. */
+ yyrealloc( (void *) b->yy_ch_buf,
+ (yy_size_t) (b->yy_buf_size + 2) );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = NULL; /* { dg-bogus "leak" "" { xfail *-*-* } } */
+ /* TODO: leak false positive: PR analyzer/103546. */
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );/* { dg-bogus "leak" "" { xfail *-*-* } } */
+ /* TODO: leak false positive: PR analyzer/103546. */
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+ (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ yy_state_type yy_current_state;
+ char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 6 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ int yy_is_jam;
+ char *yy_cp = (yy_c_buf_p);
+
+ YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 6 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ yy_is_jam = (yy_current_state == 5);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+
+ static void yyunput (int c, char * yy_bp )
+{
+ char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up yytext */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ int number_to_move = (yy_n_chars) + 2;
+ char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (int) ((yy_c_buf_p) - (yytext_ptr));
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( ) )
+ return 0;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input(); /* { dg-bogus "infinite recursion" "" { xfail *-*-* } } */
+ /* TODO: infinite recursion positive: PR analyzer/103546. */
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve yytext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+
+void yyrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE );
+ }
+
+ yy_init_buffer( YY_CURRENT_BUFFER, input_file );
+ yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+
+YY_BUFFER_STATE
+yy_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file ); /* { dg-bogus "leak" "" { xfail *-*-* } } */
+ /* TODO: leak false positive: PR analyzer/103546. */
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+
+void yy_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree( (void *) b->yy_ch_buf );
+
+ yyfree( (void *) b );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+
+static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
+{
+ int oerrno = errno;
+
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+void yy_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void yypop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+ yy_size_t num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ yy_size_t grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return NULL;
+
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = NULL;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (const char * yystr )
+{
+
+ return yy_scan_bytes( yystr, (int) strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = (yy_size_t) (_yybytes_len + 2);
+ buf = (char *) yyalloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b; /* { dg-bogus "leak" "" { xfail *-*-* } } */
+ /* TODO: leak false positive: PR analyzer/103546. */
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yynoreturn yy_fatal_error (const char* msg )
+{
+ fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int yyget_leng (void)
+{
+ return yyleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *yyget_text (void)
+{
+ return yytext;
+}
+
+/** Set the current line number.
+ * @param _line_number line number
+ *
+ */
+void yyset_lineno (int _line_number )
+{
+
+ yylineno = _line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param _in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * _in_str )
+{
+ yyin = _in_str ;
+}
+
+void yyset_out (FILE * _out_str )
+{
+ yyout = _out_str ;
+}
+
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
+
+void yyset_debug (int _bdebug )
+{
+ yy_flex_debug = _bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = NULL;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = NULL;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = NULL;
+ yyout = NULL;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer( YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, const char * s2, int n )
+{
+
+ int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (const char * s )
+{
+ int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size )
+{
+ return malloc(size);
+}
+
+void *yyrealloc (void * ptr, yy_size_t size )
+{
+
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return realloc(ptr, size);
+}
+
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
diff --git a/gcc/testsuite/gcc.dg/analyzer/flex-without-call-summaries.c b/gcc/testsuite/gcc.dg/analyzer/flex-without-call-summaries.c
new file mode 100644
index 0000000..5b4a986
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/flex-without-call-summaries.c
@@ -0,0 +1,1680 @@
+/* Integration test for compiling the output of a minimal "flex"
+ script. */
+
+/* { dg-additional-options "-fno-analyzer-call-summaries" } */
+
+/* { dg-additional-options "-Wno-analyzer-too-complex" } */
+
+
+/* A lexical scanner generated by flex */
+
+#define YY_INT_ALIGNED short int
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+/* begin standard C++ headers. */
+
+/* TODO: this is always defined, so inline it */
+#define yyconst const
+
+#define yynoreturn __attribute__((__noreturn__))
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an
+ * integer in range [0..255] for use as an array index.
+ */
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern int yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+ #define YY_LINENO_REWIND_TO(ptr)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ int yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = NULL;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart ( FILE *input_file );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size );
+void yy_delete_buffer ( YY_BUFFER_STATE b );
+void yy_flush_buffer ( YY_BUFFER_STATE b );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state ( void );
+
+static void yyensure_buffer_stack ( void );
+static void yy_load_buffer_state ( void );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len );
+
+void *yyalloc ( yy_size_t );
+void *yyrealloc ( void *, yy_size_t );
+void yyfree ( void * );
+
+#define yy_new_buffer yy_create_buffer
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+typedef flex_uint8_t YY_CHAR;
+
+FILE *yyin = NULL, *yyout = NULL;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+int yylineno = 1;
+
+extern char *yytext;
+#ifdef yytext_ptr
+#undef yytext_ptr
+#endif
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state ( void );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state );
+static int yy_get_next_buffer ( void );
+static void yynoreturn yy_fatal_error ( const char* msg );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+#define YY_NUM_RULES 1
+#define YY_END_OF_BUFFER 2
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static const flex_int16_t yy_accept[6] =
+ { 0,
+ 0, 0, 2, 1, 0
+ } ;
+
+static const YY_CHAR yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static const YY_CHAR yy_meta[2] =
+ { 0,
+ 1
+ } ;
+
+static const flex_int16_t yy_base[7] =
+ { 0,
+ 0, 0, 2, 3, 3, 0
+ } ;
+
+static const flex_int16_t yy_def[7] =
+ { 0,
+ 6, 6, 5, 5, 0, 5
+ } ;
+
+static const flex_int16_t yy_nxt[5] =
+ { 0,
+ 4, 5, 3, 5
+ } ;
+
+static const flex_int16_t yy_chk[5] =
+ { 0,
+ 6, 3, 5, 5
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals ( void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy ( void );
+
+int yyget_debug ( void );
+
+void yyset_debug ( int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra ( void );
+
+void yyset_extra ( YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in ( void );
+
+void yyset_in ( FILE * _in_str );
+
+FILE *yyget_out ( void );
+
+void yyset_out ( FILE * _out_str );
+
+ int yyget_leng ( void );
+
+char *yyget_text ( void );
+
+int yyget_lineno ( void );
+
+void yyset_lineno ( int _line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap ( void );
+#else
+extern int yywrap ( void );
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+
+ static void yyunput ( int c, char *buf_ptr );
+
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy ( char *, const char *, int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen ( const char * );
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput ( void );
+#else
+static int input ( void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ int n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK /*LINTED*/break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+ }
+
+ yy_load_buffer_state( );
+ }
+
+ {
+
+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of yytext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+yy_match:
+ do
+ {
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 6 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 3 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+ECHO;
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( yywrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of user's declarations */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = (yytext_ptr);
+ int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *) /* { dg-warning "leak of '\\*b.yy_ch_buf'" } */
+ /* Include room in for 2 EOB chars. */
+ yyrealloc( (void *) b->yy_ch_buf,
+ (yy_size_t) (b->yy_buf_size + 2) );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = NULL; /* { dg-bogus "leak" "" { xfail *-*-* } } */
+ /* TODO: leak false positive: PR analyzer/103546. */
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+ (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ yy_state_type yy_current_state;
+ char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 6 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ int yy_is_jam;
+ char *yy_cp = (yy_c_buf_p);
+
+ YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 6 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ yy_is_jam = (yy_current_state == 5);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+
+ static void yyunput (int c, char * yy_bp )
+{
+ char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up yytext */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ int number_to_move = (yy_n_chars) + 2;
+ char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (int) ((yy_c_buf_p) - (yytext_ptr));
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( ) )
+ return 0;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve yytext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+
+void yyrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE );
+ }
+
+ yy_init_buffer( YY_CURRENT_BUFFER, input_file );
+ yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+
+YY_BUFFER_STATE
+yy_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+
+void yy_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree( (void *) b->yy_ch_buf );
+
+ yyfree( (void *) b );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+
+static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
+{
+ int oerrno = errno;
+
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+void yy_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void yypop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+ yy_size_t num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ yy_size_t grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return NULL;
+
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = NULL;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (const char * yystr )
+{
+
+ return yy_scan_bytes( yystr, (int) strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = (yy_size_t) (_yybytes_len + 2);
+ buf = (char *) yyalloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yynoreturn yy_fatal_error (const char* msg )
+{
+ fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int yyget_leng (void)
+{
+ return yyleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *yyget_text (void)
+{
+ return yytext;
+}
+
+/** Set the current line number.
+ * @param _line_number line number
+ *
+ */
+void yyset_lineno (int _line_number )
+{
+
+ yylineno = _line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param _in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * _in_str )
+{
+ yyin = _in_str ;
+}
+
+void yyset_out (FILE * _out_str )
+{
+ yyout = _out_str ;
+}
+
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
+
+void yyset_debug (int _bdebug )
+{
+ yy_flex_debug = _bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = NULL;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = NULL;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = NULL;
+ yyout = NULL;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer( YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, const char * s2, int n )
+{
+
+ int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (const char * s )
+{
+ int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size )
+{
+ return malloc(size);
+}
+
+void *yyrealloc (void * ptr, yy_size_t size )
+{
+
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return realloc(ptr, size);
+}
+
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
diff --git a/gcc/testsuite/gcc.dg/analyzer/getc-1.c b/gcc/testsuite/gcc.dg/analyzer/getc-1.c
new file mode 100644
index 0000000..04896ce
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/getc-1.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int test_pass_through (FILE *stream)
+{
+ return getc (stream);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-2.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-2.c
new file mode 100644
index 0000000..f0ab130
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-2.c
@@ -0,0 +1,109 @@
+void test_direct (void)
+{
+ test_direct (); /* { dg-warning "infinite recursion" } */
+}
+
+void test_guarded (int flag)
+{
+ if (flag)
+ test_guarded (flag); /* { dg-warning "infinite recursion" } */
+}
+
+void test_flipped_guard (int flag)
+{
+ if (flag)
+ test_guarded (!flag); /* { dg-bogus "infinite recursion" } */
+}
+
+void test_param_variant (int depth)
+{
+ if (depth > 0)
+ test_param_variant (depth - 1); /* { dg-bogus "infinite recursion" } */
+}
+
+void test_unguarded_param_variant (int depth)
+{
+ /* We fail to report this: we see that depth is being decremented,
+ but don't notice that every path through the function is
+ recursing. */
+ test_unguarded_param_variant (depth - 1); /* { dg-warning "infinite recursion" "TODO" { xfail *-*-* } } */
+}
+
+int g;
+
+void test_global_variant ()
+{
+ if (g-- > 0)
+ test_global_variant (); /* { dg-bogus "infinite recursion" } */
+}
+
+/* This is a bounded recursion, as "n" is decremented before recursing... */
+
+int test_while_do_predecrement_param (int n)
+{
+ int x = 0;
+ while (n)
+ x += test_while_do_predecrement_param (--n); /* { dg-bogus "infinite recursion" } */
+ return x;
+}
+
+/* ...whereas this one is unbounded, as "n" is decremented *after* the
+ recursive call, and so is repeatedly called with the same value. */
+
+int test_while_do_postdecrement_param (int n)
+{
+ int x = 0;
+ while (n)
+ x += test_while_do_postdecrement_param (n--); /* { dg-warning "infinite recursion" } */
+ return x;
+}
+/* This is a bounded recursion, as "n" is decremented before recursing... */
+
+int test_do_while_predecrement_param (int n)
+{
+ int x = 0;
+ do
+ x += test_do_while_predecrement_param (--n); /* { dg-bogus "infinite recursion" } */
+ while (--n);
+ return x;
+}
+
+/* ...whereas this one is unbounded, as "n" is decremented *after* the
+ recursive call, and so is repeatedly called with the same value. */
+
+int test_do_while_postdecrement_param (int n)
+{
+ int x = 0;
+ do
+ x += test_do_while_postdecrement_param (n--); /* { dg-warning "infinite recursion" } */
+ while (--n);
+ return x;
+}
+
+/* Various cases of decrementing "n" as the recursion proceeds where
+ not every path recurses, but we're not actually checking "n", so
+ if "flag" is true it's an infinite recursion. */
+
+void test_partially_guarded_postdecrement (int flag, int n)
+{
+ /* We catch this; the "n--" means we recurse with the
+ same value for the 2nd param. */
+ if (flag) /* { dg-message "when 'flag != 0'" } */
+ test_partially_guarded_postdecrement (flag, n--); /* { dg-warning "infinite recursion" } */
+}
+
+void test_partially_guarded_predecrement (int flag, int n)
+{
+ /* We fail to report this; we see that "n" is changing,
+ though it isn't relevant to whether we recurse. */
+ if (flag)
+ test_partially_guarded_predecrement (flag, --n); /* { dg-warning "infinite recursion" "TODO" { xfail *-*-* } } */
+}
+
+void test_partially_guarded_subtract (int flag, int n)
+{
+ /* We fail to report this; we see that "n" is changing,
+ though it isn't relevant to whether we recurse. */
+ if (flag)
+ test_partially_guarded_subtract (flag, n - 1); /* { dg-warning "infinite recursion" "TODO" { xfail *-*-* } } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-3.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-3.c
new file mode 100644
index 0000000..68c4fa3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-3.c
@@ -0,0 +1,18 @@
+/* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex" } */
+
+struct node
+{
+ struct node *left;
+ struct node *right;
+ int val;
+};
+
+int sum (struct node *n)
+{
+ int result = 0;
+ if (n->left)
+ result += sum (n->left); /* { dg-bogus "infinite recursion" } */
+ if (n->right)
+ result += sum (n->right); /* { dg-bogus "infinite recursion" } */
+ return result;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-limited-buggy.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-limited-buggy.c
new file mode 100644
index 0000000..a71b902
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-limited-buggy.c
@@ -0,0 +1,25 @@
+/* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex" } */
+
+/* A two-deep mutual recursion, and failing to walk a list,
+ but with a depth limit, thus not an infinite recursion (assuming a
+ suitable depth limit). */
+
+struct node
+{
+ struct node *child;
+};
+
+void foo (struct node *f, int depth);
+
+void bar (struct node *b, int depth)
+{
+ foo (b, depth); /* { dg-bogus "infinite recursion" } */
+}
+
+void foo (struct node *f, int depth)
+{
+ if (f->child && depth > 0)
+ /* Bug: should have recursed to f->child, not to f,
+ but we assume that the depth limit should save us. */
+ bar (f, depth - 1); /* { dg-bogus "infinite recursion" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-limited.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-limited.c
new file mode 100644
index 0000000..55326d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-limited.c
@@ -0,0 +1,22 @@
+/* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex" } */
+
+/* A two-deep mutual recursion, walking a singly-linked list,
+ with a depth limit. */
+
+struct node
+{
+ struct node *child;
+};
+
+void foo (struct node *f, int depth);
+
+void bar (struct node *b, int depth)
+{
+ foo (b, depth); /* { dg-bogus "infinite recursion" } */
+}
+
+void foo (struct node *f, int depth)
+{
+ if (f->child && depth > 0)
+ bar (f->child, depth - 1); /* { dg-bogus "infinite recursion" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-unlimited-buggy.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-unlimited-buggy.c
new file mode 100644
index 0000000..7ed1a2b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-unlimited-buggy.c
@@ -0,0 +1,23 @@
+/* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex" } */
+
+/* A two-deep mutual recursion, with no limit, and
+ failing to walk the list, thus leading to an infinite recursion. */
+
+struct node
+{
+ struct node *child;
+};
+
+void foo (struct node *f);
+
+void bar (struct node *b)
+{
+ foo (b); /* { dg-warning "infinite recursion" } */
+}
+
+void foo (struct node *f)
+{
+ if (f->child)
+ /* Bug: should have recursed to f->child, not to f. */
+ bar (f); /* { dg-warning "infinite recursion" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-unlimited.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-unlimited.c
new file mode 100644
index 0000000..bdb54a3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-unlimited.c
@@ -0,0 +1,22 @@
+/* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex" } */
+
+/* A two-deep mutual recursion, walking a linked list (and thus presumably
+ terminating), with no explicit depth limit. */
+
+struct node
+{
+ struct node *child;
+};
+
+void foo (struct node *f);
+
+void bar (struct node *b)
+{
+ foo (b); /* { dg-bogus "infinite recursion" } */
+}
+
+void foo (struct node *f)
+{
+ if (f->child)
+ bar (f->child); /* { dg-bogus "infinite recursion" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-5.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-5.c
new file mode 100644
index 0000000..bf20639
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-5.c
@@ -0,0 +1,221 @@
+/* Adapted from gcc.dg/Winfinite-recursion.c. */
+
+#define NORETURN __attribute__ ((noreturn))
+
+typedef __SIZE_TYPE__ size_t;
+
+extern void abort (void);
+extern void exit (int);
+
+extern int ei;
+int (*pfi_v)(void);
+
+
+/* Make sure the warning doesn't assume every call has a DECL. */
+
+int nowarn_pfi_v (void)
+{
+ return pfi_v ();
+}
+
+
+int warn_fi_v (void)
+{
+ return warn_fi_v (); // { dg-warning "-Wanalyzer-infinite-recursion" }
+}
+
+/* Verify #pragma suppression works. */
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wanalyzer-infinite-recursion"
+
+int suppress_warn_fi_v (void)
+{
+ return suppress_warn_fi_v ();
+}
+
+#pragma GCC diagnostic pop
+
+
+int nowarn_fi_v (void)
+{
+ if (ei++ == 0)
+ return nowarn_fi_v ();
+ return 0;
+}
+
+/* -Winfinite-recursion warns for this, but
+ -Wanalyzer-infinite-recursion doesn't. */
+
+int warn_if_i (int i)
+{
+ if (i > 0)
+ return warn_if_i (--i);
+ else if (i < 0)
+ return warn_if_i (-i);
+ else
+ return warn_if_i (7);
+}
+
+
+int nowarn_if_i (int i)
+{
+ if (i > 0)
+ return nowarn_if_i (--i);
+ else if (i < 0)
+ return nowarn_if_i (-i);
+ else
+ return -1;
+}
+
+int nowarn_switch (int i, int a[])
+{
+ switch (i)
+ {
+ case 0: return nowarn_switch (a[3], a + 1);
+ case 1: return nowarn_switch (a[5], a + 2);
+ case 2: return nowarn_switch (a[7], a + 3);
+ case 3: return nowarn_switch (a[9], a + 4);
+ }
+ return 77;
+}
+
+/* -Winfinite-recursion warns for this, but
+ -Wanalyzer-infinite-recursion doesn't. */
+
+int warn_switch (int i, int a[])
+{
+ switch (i)
+ {
+ case 0: return warn_switch (a[3], a + 1);
+ case 1: return warn_switch (a[5], a + 2);
+ case 2: return warn_switch (a[7], a + 3);
+ case 3: return warn_switch (a[9], a + 4);
+ default: return warn_switch (a[1], a + 5);
+ }
+}
+
+NORETURN void fnoreturn (void);
+
+/* Verify there's no warning for a function that doesn't return. */
+int nowarn_call_noret (void)
+{
+ fnoreturn ();
+}
+
+int warn_call_noret_r (void)
+{
+ warn_call_noret_r (); // { dg-warning "-Wanalyzer-infinite-recursion" }
+ fnoreturn ();
+}
+
+/* -Winfinite-recursion warns for this, but
+ -Wanalyzer-infinite-recursion doesn't. */
+
+int
+warn_noret_call_abort_r (char *s, int n)
+{
+ if (!s)
+ abort ();
+
+ if (n > 7)
+ abort ();
+
+ return n + warn_noret_call_abort_r (s, n - 1);
+}
+
+NORETURN void nowarn_noret_call_abort_r (int n)
+{
+ if (n > 7)
+ abort ();
+
+ nowarn_noret_call_abort_r (n - 1);
+}
+
+/* -Winfinite-recursion warns for this, but
+ -Wanalyzer-infinite-recursion doesn't. */
+
+int warn_call_abort_r (int n)
+{
+ n += warn_call_abort_r (n - 1);
+ if (n > 7) // unreachable
+ abort ();
+ return n;
+}
+
+
+/* -Winfinite-recursion warns for this, but
+ -Wanalyzer-infinite-recursion doesn't. */
+
+int warn_call_exit_r (int n)
+{
+ n += warn_call_exit_r (n - 1);
+ if (n > 7)
+ exit (0);
+ return n;
+}
+
+struct __jmp_buf_tag { };
+typedef struct __jmp_buf_tag jmp_buf[1];
+
+extern jmp_buf jmpbuf;
+
+/* A call to longjmp() breaks infinite recursion. Verify it suppresses
+ the warning. */
+
+int nowarn_call_longjmp_r (int n)
+{
+ if (n > 7)
+ __builtin_longjmp (jmpbuf, 1);
+ return n + nowarn_call_longjmp_r (n - 1);
+}
+
+/* -Winfinite-recursion warns for this, but
+ -Wanalyzer-infinite-recursion doesn't. */
+
+int warn_call_longjmp_r (int n)
+{
+ n += warn_call_longjmp_r (n - 1);
+ if (n > 7)
+ __builtin_longjmp (jmpbuf, 1);
+ return n;
+}
+
+
+struct __sigjmp_buf_tag { };
+typedef struct __sigjmp_buf_tag sigjmp_buf[1];
+
+extern sigjmp_buf sigjmpbuf;
+
+/* GCC has no __builtin_siglongjmp(). */
+extern void siglongjmp (sigjmp_buf, int);
+
+/* A call to longjmp() breaks infinite recursion. Verify it suppresses
+ the warning. */
+
+int nowarn_call_siglongjmp_r (int n)
+{
+ if (n > 7)
+ siglongjmp (sigjmpbuf, 1);
+ return n + nowarn_call_siglongjmp_r (n - 1);
+}
+
+/* -Winfinite-recursion doesn't warn for this unbounded recursion, but
+ -Wanalyzer-infinite-recursion does. */
+
+int nowarn_while_do_call_r (int n)
+{
+ int z = 0;
+ while (n)
+ z += nowarn_while_do_call_r (n--); // { dg-warning "-Wanalyzer-infinite-recursion" }
+ return z;
+}
+
+int warn_do_while_call_r (int n)
+{
+ int z = 0;
+ do
+ z += warn_do_while_call_r (n); // { dg-warning "-Wanalyzer-infinite-recursion" }
+ while (--n);
+ return z;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-alloca.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-alloca.c
new file mode 100644
index 0000000..8c50631
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-alloca.c
@@ -0,0 +1,27 @@
+typedef __SIZE_TYPE__ size_t;
+
+int test_alloca_1 (void)
+{
+ void *buf = __builtin_alloca (1024);
+ return test_alloca_1 (); /* { dg-warning "-Wanalyzer-infinite-recursion" } */
+}
+
+int test_alloca_2 (size_t n)
+{
+ void *buf = __builtin_alloca (n);
+ return test_alloca_2 (n); /* { dg-warning "-Wanalyzer-infinite-recursion" } */
+}
+
+int test_alloca_3 (size_t n)
+{
+ void *buf = __builtin_alloca (n);
+ return test_alloca_2 (n - 1);
+}
+
+int test_alloca_4 (size_t n)
+{
+ void *buf = __builtin_alloca (n);
+ if (n > 0)
+ return test_alloca_2 (n - 1);
+ return 42;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-inlining.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-inlining.c
new file mode 100644
index 0000000..c885c92
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-inlining.c
@@ -0,0 +1,116 @@
+/* A copy of infinite-recursion-2.c, to see what inlining does to the IR
+ when we see it.
+
+ Many cases get converted by the optimizer into iteration, and
+ into infinite loops, sometimes trivial ones.
+
+ Right now this is a documented limitation of the warning, but perhaps
+ could be readdressed by moving the analyzer earlier. */
+
+/* { dg-additional-options "-O3" } */
+
+void test_direct (void)
+{
+ test_direct (); /* Ideally would warn here, but it becomes an infinite loop. */
+}
+
+void test_guarded (int flag)
+{
+ if (flag)
+ test_guarded (flag); /* Ideally would warn here, but it becomes an infinite loop. */
+}
+
+void test_flipped_guard (int flag)
+{
+ if (flag)
+ test_guarded (!flag);
+}
+
+void test_param_variant (int depth)
+{
+ if (depth > 0)
+ test_param_variant (depth - 1);
+}
+
+void test_unguarded_param_variant (int depth)
+{
+ test_unguarded_param_variant (depth - 1); /* Ideally would warn here, but it becomes an infinite loop. */
+}
+
+int g;
+
+void test_global_variant ()
+{
+ if (g-- > 0)
+ test_global_variant ();
+}
+
+/* This is a bounded recursion, as "n" is decremented before recursing... */
+
+int test_while_do_predecrement_param (int n)
+{
+ int x = 0;
+ while (n)
+ x += test_while_do_predecrement_param (--n);
+ return x;
+}
+
+/* ...whereas this one is unbounded, as "n" is decremented *after* the
+ recursive call, and so is repeatedly called with the same value. */
+
+int test_while_do_postdecrement_param (int n)
+{
+ int x = 0;
+ while (n)
+ x += test_while_do_postdecrement_param (n--); /* { dg-warning "infinite recursion" } */
+ return x;
+}
+/* This is a bounded recursion, as "n" is decremented before recursing... */
+
+int test_do_while_predecrement_param (int n)
+{
+ int x = 0;
+ do
+ x += test_do_while_predecrement_param (--n);
+ while (--n);
+ return x;
+}
+
+/* ...whereas this one is unbounded, as "n" is decremented *after* the
+ recursive call, and so is repeatedly called with the same value. */
+
+int test_do_while_postdecrement_param (int n)
+{
+ int x = 0;
+ do
+ x += test_do_while_postdecrement_param (n--); /* { dg-warning "infinite recursion" } */
+ while (--n);
+ return x;
+}
+
+/* Various cases of decrementing "n" as the recursion proceeds where
+ not every path recurses, but we're not actually checking "n", so
+ if "flag" is true it's an infinite recursion. */
+
+void test_partially_guarded_postdecrement (int flag, int n)
+{
+ /* Ideally we'd catch this, but it becomes an infinite loop. */
+ if (flag)
+ test_partially_guarded_postdecrement (flag, n--);
+}
+
+void test_partially_guarded_predecrement (int flag, int n)
+{
+ /* We fail to report this; we see that "n" is changing,
+ though it isn't relevant to whether we recurse. */
+ if (flag)
+ test_partially_guarded_predecrement (flag, --n); /* { dg-warning "infinite recursion" "TODO" { xfail *-*-* } } */
+}
+
+void test_partially_guarded_subtract (int flag, int n)
+{
+ /* We fail to report this; we see that "n" is changing,
+ though it isn't relevant to whether we recurse. */
+ if (flag)
+ test_partially_guarded_subtract (flag, n - 1); /* { dg-warning "infinite recursion" "TODO" { xfail *-*-* } } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-multiline-1.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-multiline-1.c
new file mode 100644
index 0000000..e236dd4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-multiline-1.c
@@ -0,0 +1,41 @@
+/* Integration test of how the execution path looks for
+ -Wanalyzer-infinite-recursion. */
+
+/* { dg-additional-options "-fdiagnostics-show-path-depths" } */
+/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
+
+void foo (int flag)
+{
+ if (flag)
+ foo (flag); /* { dg-warning "infinite recursion" } */
+}
+
+/* { dg-begin-multiline-output "" }
+ foo (flag);
+ ^~~~~~~~~~
+ 'foo': events 1-4 (depth 1)
+ |
+ | void foo (int flag)
+ | ^~~
+ | |
+ | (1) initial entry to 'foo'
+ |
+ | if (flag)
+ | ~
+ | |
+ | (2) following 'true' branch (when 'flag != 0')...
+ | foo (flag);
+ | ~~~~~~~~~~
+ | |
+ | (3) ...to here
+ | (4) calling 'foo' from 'foo'
+ |
+ +--> 'foo': events 5-6 (depth 2)
+ |
+ | void foo (int flag)
+ | ^~~
+ | |
+ | (5) recursive entry to 'foo'; previously entered at (1)
+ | (6) apparently infinite recursion
+ |
+ { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-multiline-2.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-multiline-2.c
new file mode 100644
index 0000000..2c69dd5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-multiline-2.c
@@ -0,0 +1,93 @@
+/* Integration test of how the execution path looks for
+ -Wanalyzer-infinite-recursion. */
+
+/* { dg-additional-options "-fdiagnostics-show-path-depths" } */
+/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
+
+void mutual_2 (void);
+
+void mutual_1 (void)
+{
+ mutual_2 (); /* { dg-warning "infinite recursion" } */
+}
+
+void mutual_2 (void)
+{
+ mutual_1 (); /* { dg-warning "infinite recursion" } */
+}
+
+
+/* { dg-begin-multiline-output "" }
+ mutual_2 ();
+ ^~~~~~~~~~~
+ 'mutual_2': events 1-2 (depth 1)
+ |
+ | void mutual_2 (void)
+ | ^~~~~~~~
+ | |
+ | (1) initial entry to 'mutual_2'
+ |
+ | mutual_1 ();
+ | ~~~~~~~~~~~
+ | |
+ | (2) calling 'mutual_1' from 'mutual_2'
+ |
+ +--> 'mutual_1': events 3-4 (depth 2)
+ |
+ | void mutual_1 (void)
+ | ^~~~~~~~
+ | |
+ | (3) entry to 'mutual_1'
+ |
+ | mutual_2 ();
+ | ~~~~~~~~~~~
+ | |
+ | (4) calling 'mutual_2' from 'mutual_1'
+ |
+ +--> 'mutual_2': events 5-6 (depth 3)
+ |
+ | void mutual_2 (void)
+ | ^~~~~~~~
+ | |
+ | (5) recursive entry to 'mutual_2'; previously entered at (1)
+ | (6) apparently infinite chain of mutually-recursive function calls, consuming 2 stack frames per recursion
+ |
+ { dg-end-multiline-output "" } */
+
+
+/* { dg-begin-multiline-output "" }
+ mutual_1 ();
+ ^~~~~~~~~~~
+ 'mutual_1': events 1-2 (depth 1)
+ |
+ | void mutual_1 (void)
+ | ^~~~~~~~
+ | |
+ | (1) initial entry to 'mutual_1'
+ |
+ | mutual_2 ();
+ | ~~~~~~~~~~~
+ | |
+ | (2) calling 'mutual_2' from 'mutual_1'
+ |
+ +--> 'mutual_2': events 3-4 (depth 2)
+ |
+ | void mutual_2 (void)
+ | ^~~~~~~~
+ | |
+ | (3) entry to 'mutual_2'
+ |
+ | mutual_1 ();
+ | ~~~~~~~~~~~
+ | |
+ | (4) calling 'mutual_1' from 'mutual_2'
+ |
+ +--> 'mutual_1': events 5-6 (depth 3)
+ |
+ | void mutual_1 (void)
+ | ^~~~~~~~
+ | |
+ | (5) recursive entry to 'mutual_1'; previously entered at (1)
+ | (6) apparently infinite chain of mutually-recursive function calls, consuming 2 stack frames per recursion
+ |
+ { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-variadic.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-variadic.c
new file mode 100644
index 0000000..eafbeba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-variadic.c
@@ -0,0 +1,34 @@
+int test_variadic_1 (int n, ...)
+{
+ __builtin_va_list args;
+ int total =0;
+ int i;
+
+ __builtin_va_start(args, n);
+
+ for (i = 0; i < n; i++)
+ total += __builtin_va_arg(args, int);
+
+ __builtin_va_end(args);
+
+ return total;
+}
+
+int test_variadic_2 (int n, ...)
+{
+ return test_variadic_2 (n, 42); /* { dg-warning "-Wanalyzer-infinite-recursion" } */
+}
+
+int test_variadic_3 (int n, ...)
+{
+ if (n > 0) /* { dg-message "when 'n > 0'" } */
+ return test_variadic_3 (n, 42); /* { dg-warning "-Wanalyzer-infinite-recursion" } */
+ return 0;
+}
+
+int test_variadic_4 (int n, ...)
+{
+ if (n > 0)
+ return test_variadic_4 (n - 1, 42);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion.c
index b770e12..6b7d25c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion.c
+++ b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion.c
@@ -11,7 +11,7 @@ void test(int flag)
marker_B();
/* Recurse, infinitely, as it happens: */
- test(flag);
+ test(flag); /* { dg-warning "infinite recursion" } */
marker_C();
}
@@ -30,26 +30,26 @@ void mutual_test_1 (int flag)
{
marker_A ();
if (flag)
- mutual_test_2 (flag);
+ mutual_test_2 (flag); /* { dg-warning "infinite recursion" } */
}
void mutual_test_2 (int flag)
{
marker_B ();
if (flag)
- mutual_test_3 (flag);
+ mutual_test_3 (flag); /* { dg-warning "infinite recursion" } */
}
void mutual_test_3 (int flag)
{
marker_C ();
if (flag)
- mutual_test_4 (flag);
+ mutual_test_4 (flag); /* { dg-warning "infinite recursion" } */
}
void mutual_test_4 (int flag)
{
marker_D ();
if (flag)
- mutual_test_1 (flag);
+ mutual_test_1 (flag); /* { dg-warning "infinite recursion" } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/isatty-1.c b/gcc/testsuite/gcc.dg/analyzer/isatty-1.c
new file mode 100644
index 0000000..bea97fd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/isatty-1.c
@@ -0,0 +1,56 @@
+#include <errno.h>
+#include "analyzer-decls.h"
+
+extern int isatty(int fd);
+extern int close(int fd);
+
+int test_pass_through (int fd)
+{
+ return isatty (fd);
+}
+
+void test_merging (int fd)
+{
+ isatty (fd);
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
+
+int test_outcomes (int fd)
+{
+ errno = 0;
+ int result = isatty (fd);
+ switch (result)
+ {
+ default:
+ __analyzer_dump_path (); /* { dg-bogus "path" } */
+ break;
+ case 0:
+ __analyzer_dump_path (); /* { dg-message "path" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ break;
+ case 1:
+ __analyzer_dump_path (); /* { dg-message "path" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ break;
+ }
+ return result;
+}
+
+int test_isatty_on_invalid_fd (void)
+{
+ errno = 0;
+ int result = isatty (-1);
+ __analyzer_eval (result == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ return result;
+}
+
+int test_isatty_on_closed_fd (int fd)
+{
+ close (fd);
+ errno = 0;
+ int result = isatty (fd);
+ __analyzer_eval (result == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ return result;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
index d69a605..6b5590a 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
@@ -625,5 +625,14 @@ void test_50c (void)
free (&&my_label); /* { dg-warning "'free' of '&my_label' which points to memory not on the heap \\\[CWE-590\\\]" } */
}
+/* Double free after unconditional dereference. */
+
+int test_51 (int *p)
+{
+ int result = *p;
+ free (p); /* { dg-message "first 'free' here" } */
+ free (p); /* { dg-warning "double-'free' of 'p'" } */
+ return result;
+}
/* { dg-prune-output "\\\[-Wfree-nonheap-object" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-401-example.c b/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-401-example.c
new file mode 100644
index 0000000..cfb5e86
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-401-example.c
@@ -0,0 +1,37 @@
+/* Example adapted from https://cwe.mitre.org/data/definitions/401.html
+ which states "Copyright © 2006–2022, The MITRE Corporation. CWE, CWSS, CWRAF, and the CWE logo are trademarks of The MITRE Corporation."
+ and which has this on:
+ https://cwe.mitre.org/about/termsofuse.html
+
+ Terms of Use
+
+ CWE™ is free to use by any organization or individual for any research, development, and/or commercial purposes, per these CWE Terms of Use. The MITRE Corporation ("MITRE") has copyrighted the CWE List, Top 25, CWSS, and CWRAF for the benefit of the community in order to ensure each remains a free and open standard, as well as to legally protect the ongoing use of it and any resulting content by government, vendors, and/or users. CWE is a trademark of MITRE. Please contact cwe@mitre.org if you require further clarification on this issue.
+
+ LICENSE
+
+ CWE Submissions: By submitting materials to The MITRE Corporation’s ("MITRE") Common Weakness Enumeration Program (CWE™), you hereby grant to MITRE a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to use, reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute your submitted materials and derivative works. Unless otherwise required by applicable law or agreed to in writing, it is understood that you are providing such materials on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
+
+ CWE Usage: MITRE hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy.
+
+ DISCLAIMERS
+
+ ALL DOCUMENTS AND THE INFORMATION CONTAINED IN THE CWE ARE PROVIDED ON AN "AS IS" BASIS AND THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE MITRE CORPORATION, ITS BOARD OF TRUSTEES, OFFICERS, AGENTS, AND EMPLOYEES, DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION THEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+
+ IN NO EVENT SHALL THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE MITRE CORPORATION, ITS BOARD OF TRUSTEES, OFFICERS, AGENTS, AND EMPLOYEES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE INFORMATION OR THE USE OR OTHER DEALINGS IN THE CWE. */
+
+#define BLOCK_SIZE 4096
+
+#include <stdlib.h>
+#include <unistd.h>
+
+char* getBlock(int fd) {
+ char* buf = (char*) malloc(BLOCK_SIZE);
+ if (!buf) {
+ return NULL;
+ }
+ if (read(fd, buf, BLOCK_SIZE) != BLOCK_SIZE) {
+
+ return NULL; /* TODO: should complain that "buf" is leaked on this path. */
+ }
+ return buf;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-415-examples.c b/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-415-examples.c
new file mode 100644
index 0000000..51d878a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-415-examples.c
@@ -0,0 +1,53 @@
+/* Example adapted from https://cwe.mitre.org/data/definitions/415.html
+ which states "Copyright © 2006–2022, The MITRE Corporation. CWE, CWSS, CWRAF, and the CWE logo are trademarks of The MITRE Corporation."
+ and which has this on:
+ https://cwe.mitre.org/about/termsofuse.html
+
+ Terms of Use
+
+ CWE™ is free to use by any organization or individual for any research, development, and/or commercial purposes, per these CWE Terms of Use. The MITRE Corporation ("MITRE") has copyrighted the CWE List, Top 25, CWSS, and CWRAF for the benefit of the community in order to ensure each remains a free and open standard, as well as to legally protect the ongoing use of it and any resulting content by government, vendors, and/or users. CWE is a trademark of MITRE. Please contact cwe@mitre.org if you require further clarification on this issue.
+
+ LICENSE
+
+ CWE Submissions: By submitting materials to The MITRE Corporation’s ("MITRE") Common Weakness Enumeration Program (CWE™), you hereby grant to MITRE a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to use, reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute your submitted materials and derivative works. Unless otherwise required by applicable law or agreed to in writing, it is understood that you are providing such materials on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
+
+ CWE Usage: MITRE hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy.
+
+ DISCLAIMERS
+
+ ALL DOCUMENTS AND THE INFORMATION CONTAINED IN THE CWE ARE PROVIDED ON AN "AS IS" BASIS AND THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE MITRE CORPORATION, ITS BOARD OF TRUSTEES, OFFICERS, AGENTS, AND EMPLOYEES, DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION THEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+
+ IN NO EVENT SHALL THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE MITRE CORPORATION, ITS BOARD OF TRUSTEES, OFFICERS, AGENTS, AND EMPLOYEES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE INFORMATION OR THE USE OR OTHER DEALINGS IN THE CWE. */
+
+#include <stdlib.h>
+#include <string.h>
+
+#define SIZE 1024
+
+void example_1 (int abrt)
+{
+ char* ptr = (char*)malloc (SIZE);
+ /* ... */
+ if (abrt) {
+ free(ptr);
+ }
+ /* ... */
+ free(ptr); /* { dg-warning "double-'free' of 'ptr'" } */
+}
+
+#define BUFSIZE1 512
+#define BUFSIZE2 ((BUFSIZE1/2) - 8)
+
+int main(int argc, char **argv) {
+ char *buf1R1;
+ char *buf2R1;
+ char *buf1R2;
+ buf1R1 = (char *) malloc(BUFSIZE2);
+ buf2R1 = (char *) malloc(BUFSIZE2);
+ free(buf1R1);
+ free(buf2R1);
+ buf1R2 = (char *) malloc(BUFSIZE1);
+ strncpy(buf1R2, argv[1], BUFSIZE1-1); /* { dg-warning "use of possibly-NULL 'buf1R2'" } */
+ free(buf2R1); /* { dg-warning "double-'free' of 'buf2R1'" } */
+ free(buf1R2);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-416-examples.c b/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-416-examples.c
new file mode 100644
index 0000000..3f5e5e2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-416-examples.c
@@ -0,0 +1,60 @@
+/* Examples adapted from https://cwe.mitre.org/data/definitions/416.html
+ which states "Copyright © 2006–2022, The MITRE Corporation. CWE, CWSS, CWRAF, and the CWE logo are trademarks of The MITRE Corporation."
+ and which has this on:
+ https://cwe.mitre.org/about/termsofuse.html
+
+ Terms of Use
+
+ CWE™ is free to use by any organization or individual for any research, development, and/or commercial purposes, per these CWE Terms of Use. The MITRE Corporation ("MITRE") has copyrighted the CWE List, Top 25, CWSS, and CWRAF for the benefit of the community in order to ensure each remains a free and open standard, as well as to legally protect the ongoing use of it and any resulting content by government, vendors, and/or users. CWE is a trademark of MITRE. Please contact cwe@mitre.org if you require further clarification on this issue.
+
+ LICENSE
+
+ CWE Submissions: By submitting materials to The MITRE Corporation’s ("MITRE") Common Weakness Enumeration Program (CWE™), you hereby grant to MITRE a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to use, reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute your submitted materials and derivative works. Unless otherwise required by applicable law or agreed to in writing, it is understood that you are providing such materials on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
+
+ CWE Usage: MITRE hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy.
+
+ DISCLAIMERS
+
+ ALL DOCUMENTS AND THE INFORMATION CONTAINED IN THE CWE ARE PROVIDED ON AN "AS IS" BASIS AND THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE MITRE CORPORATION, ITS BOARD OF TRUSTEES, OFFICERS, AGENTS, AND EMPLOYEES, DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION THEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+
+ IN NO EVENT SHALL THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE MITRE CORPORATION, ITS BOARD OF TRUSTEES, OFFICERS, AGENTS, AND EMPLOYEES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE INFORMATION OR THE USE OR OTHER DEALINGS IN THE CWE. */
+
+#include <stdlib.h>
+#include <string.h>
+
+#define BUFSIZER1 512
+#define BUFSIZER2 ((BUFSIZER1/2) - 8)
+
+int main(int argc, char **argv) {
+ char *buf1R1;
+ char *buf2R1;
+ char *buf2R2;
+ char *buf3R2;
+ buf1R1 = (char *) malloc(BUFSIZER1);
+ buf2R1 = (char *) malloc(BUFSIZER1);
+ free(buf2R1);
+ buf2R2 = (char *) malloc(BUFSIZER2);
+ buf3R2 = (char *) malloc(BUFSIZER2);
+ strncpy(buf2R1, argv[1], BUFSIZER1-1); /* TODO: should complain about use-after-free here. */
+ free(buf1R1);
+ free(buf2R2);
+ free(buf3R2);
+}
+
+#define SIZE 1024
+extern void logError(const char *, const char *);
+
+void example_2 (int err)
+{
+ int abrt = 0;
+
+ char* ptr = (char*)malloc (SIZE);
+ if (err) {
+ abrt = 1;
+ free(ptr);
+ }
+ /* ... */
+ if (abrt) {
+ logError("operation aborted before commit", ptr); /* TODO: arguably should complain about use-after-free of ptr here. */
+ }
+} /* { dg-warning "leak of 'ptr'" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-590-examples.c b/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-590-examples.c
new file mode 100644
index 0000000..036f888
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-590-examples.c
@@ -0,0 +1,44 @@
+/* { dg-additional-options "-Wno-free-nonheap-object" } */
+
+/* Examples adapted from https://cwe.mitre.org/data/definitions/590.html
+ which states "Copyright © 2006–2022, The MITRE Corporation. CWE, CWSS, CWRAF, and the CWE logo are trademarks of The MITRE Corporation."
+ and which has this on:
+ https://cwe.mitre.org/about/termsofuse.html
+
+ Terms of Use
+
+ CWE™ is free to use by any organization or individual for any research, development, and/or commercial purposes, per these CWE Terms of Use. The MITRE Corporation ("MITRE") has copyrighted the CWE List, Top 25, CWSS, and CWRAF for the benefit of the community in order to ensure each remains a free and open standard, as well as to legally protect the ongoing use of it and any resulting content by government, vendors, and/or users. CWE is a trademark of MITRE. Please contact cwe@mitre.org if you require further clarification on this issue.
+
+ LICENSE
+
+ CWE Submissions: By submitting materials to The MITRE Corporation’s ("MITRE") Common Weakness Enumeration Program (CWE™), you hereby grant to MITRE a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to use, reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute your submitted materials and derivative works. Unless otherwise required by applicable law or agreed to in writing, it is understood that you are providing such materials on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
+
+ CWE Usage: MITRE hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy.
+
+ DISCLAIMERS
+
+ ALL DOCUMENTS AND THE INFORMATION CONTAINED IN THE CWE ARE PROVIDED ON AN "AS IS" BASIS AND THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE MITRE CORPORATION, ITS BOARD OF TRUSTEES, OFFICERS, AGENTS, AND EMPLOYEES, DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION THEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+
+ IN NO EVENT SHALL THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE MITRE CORPORATION, ITS BOARD OF TRUSTEES, OFFICERS, AGENTS, AND EMPLOYEES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE INFORMATION OR THE USE OR OTHER DEALINGS IN THE CWE. */
+
+#include <stdlib.h>
+
+typedef struct record_t { char placeholder[1024]; } record_t;
+#define MAX_SIZE 100
+
+void foo_1(){
+ record_t bar[MAX_SIZE];
+
+ /* do something interesting with bar */
+
+ /* ... */
+ free(bar); /* { dg-warning "'free' of '&bar' which points to memory on the stack" } */
+}
+
+record_t bar[MAX_SIZE]; //Global var
+void foo_2(){
+
+ /* do something interesting with bar */
+ /* ... */
+ free(bar); /* { dg-warning "'free' of '&bar' which points to memory not on the heap" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-12.c b/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-12.c
index fce5437..3813c9a 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-12.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-12.c
@@ -3,5 +3,5 @@
void recursive_free (void *ptr)
{
free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */
- recursive_free (ptr);
+ recursive_free (ptr); /* { dg-warning "infinite recursion" } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-reuse.c b/gcc/testsuite/gcc.dg/analyzer/malloc-reuse.c
new file mode 100644
index 0000000..4575ff5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-reuse.c
@@ -0,0 +1,58 @@
+/* { dg-require-effective-target alloca } */
+
+#include <stdlib.h>
+#include "analyzer-decls.h"
+
+/* Multiple calls to malloc (without a free) should return non-equal pointers. */
+
+void test_1 (void)
+{
+ void *p, *q;
+ p = malloc (1024);
+ if (!p)
+ return;
+ q = malloc (1024);
+ __analyzer_eval (p == q); /* { dg-warning "FALSE" } */
+ free (p);
+ free (q);
+}
+
+/* Multiple calls to malloc with a free might or might not
+ return the same pointer. */
+
+void test_2 (void)
+{
+ void *p, *q;
+ p = malloc (1024);
+ if (!p)
+ return;
+ free (p);
+
+ q = malloc (1024);
+ __analyzer_eval (p == q); /* { dg-warning "UNKNOWN" "ideal" { xfail *-*-* } } */
+ /* { dg-bogus "FALSE" "status quo" { xfail *-*-* } .-1 } */
+ // TODO: ideally this should be UNKNOWN
+ free (q);
+}
+
+void test_two_malloc_sites_same_size (int flag)
+{
+ void *p;
+ if (flag)
+ p = malloc (1024);
+ else
+ p = malloc (1024);
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+ free (p);
+}
+
+void test_two_malloc_sites_different_sizes (int flag)
+{
+ void *p;
+ if (flag)
+ p = malloc (4096);
+ else
+ p = malloc (1024);
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+ free (p);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/memcpy-1.c b/gcc/testsuite/gcc.dg/analyzer/memcpy-1.c
index a9368d3..b1ffed0 100644
--- a/gcc/testsuite/gcc.dg/analyzer/memcpy-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/memcpy-1.c
@@ -166,3 +166,17 @@ void test_7b (void *src, size_t sz)
{
memcpy ((void *)"hello world", src, sz); /* { dg-warning "write to string literal" } */
}
+
+/* memcpy from uninitialized buffer. */
+
+void test_8a (void *dst)
+{
+ char src[16];
+ memcpy (dst, src, 16); /* { dg-warning "use of uninitialized value" } */
+}
+
+void test_8b (void *dst, size_t n)
+{
+ char src[16];
+ memcpy (dst, src, n); /* { dg-warning "use of uninitialized value" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/memcpy-pr107882.c b/gcc/testsuite/gcc.dg/analyzer/memcpy-pr107882.c
new file mode 100644
index 0000000..4ecb0fd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/memcpy-pr107882.c
@@ -0,0 +1,8 @@
+void
+foo (int *x, int y)
+{
+ int *a = x, *b = (int *) &a;
+
+ __builtin_memcpy (b + 1, x, y);
+ foo (a, 0);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/memmove-1.c b/gcc/testsuite/gcc.dg/analyzer/memmove-1.c
new file mode 100644
index 0000000..06627ed
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/memmove-1.c
@@ -0,0 +1,182 @@
+#include <string.h>
+#include "analyzer-decls.h"
+
+/* Function for thwarting expansion of memmove by optimizer. */
+
+typedef void * (*memmove_t) (void *dst, const void *src, size_t n);
+
+static memmove_t __attribute__((noinline))
+get_memmove (void)
+{
+ return memmove;
+}
+
+void *test_1 (void *dst, void *src, size_t n)
+{
+ void *result = memmove (dst, src, n);
+ __analyzer_eval (result == dst); /* { dg-warning "TRUE" } */
+ return result;
+}
+
+void *test_1a (void *dst, void *src, size_t n)
+{
+ void *result = __memmove_chk (dst, src, n, -1);
+ __analyzer_eval (result == dst); /* { dg-warning "TRUE" } */
+ return result;
+}
+
+void *test_1b (void *dst, void *src, size_t n)
+{
+ memmove_t fn = get_memmove ();
+ void *result = fn (dst, src, n);
+ __analyzer_eval (result == dst); /* { dg-warning "TRUE" } */
+ return result;
+}
+
+void test_2 (int i)
+{
+ int j;
+ memmove (&j, &i, sizeof (int));
+ __analyzer_eval (i == j); /* { dg-warning "TRUE" } */
+}
+
+void test_2a (int i)
+{
+ int j;
+ __memmove_chk (&j, &i, sizeof (int), sizeof (int));
+ __analyzer_eval (i == j); /* { dg-warning "TRUE" } */
+}
+
+void test_2b (int i)
+{
+ int j;
+ memmove_t fn = get_memmove ();
+ fn (&j, &i, sizeof (int));
+ __analyzer_eval (i == j); /* { dg-warning "TRUE" } */
+}
+
+void test_3 (void *src, size_t n)
+{
+ char buf[40], other[40];
+ buf[0] = 'a';
+ other[0] = 'b';
+ __analyzer_eval (buf[0] == 'a'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (other[0] == 'b'); /* { dg-warning "TRUE" } */
+
+ memmove (buf, src, n);
+ __analyzer_eval (buf[0] == 'a'); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (other[0] == 'b'); /* { dg-warning "TRUE" } */
+}
+
+void test_3b (void *src, size_t n)
+{
+ char buf[40], other[40];
+ memmove_t fn = get_memmove ();
+ buf[0] = 'a';
+ other[0] = 'b';
+ __analyzer_eval (buf[0] == 'a'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (other[0] == 'b'); /* { dg-warning "TRUE" } */
+
+ fn (buf, src, n);
+ __analyzer_eval (buf[0] == 'a'); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (other[0] == 'b'); /* { dg-warning "TRUE" } */
+}
+
+/* Overwriting a zeroed buffer, then memmove of the result. */
+
+void test_4 (int a, int b)
+{
+ int src[1024];
+ int dst[1024];
+ memset (src, 0, sizeof (src));
+ src[42] = a;
+ src[100] = b;
+ __analyzer_eval (src[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (src[42] == a); /* { dg-warning "TRUE" } */
+ __analyzer_eval (src[100] == b); /* { dg-warning "TRUE" } */
+ __analyzer_eval (src[1023] == 0); /* { dg-warning "TRUE" } */
+
+ memmove (dst, src, sizeof (src));
+ __analyzer_eval (dst[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (dst[42] == a); /* { dg-warning "TRUE" } */
+ __analyzer_eval (dst[100] == b); /* { dg-warning "TRUE" } */
+ __analyzer_eval (dst[1023] == 0); /* { dg-warning "TRUE" } */
+}
+
+void test_4b (int a, int b)
+{
+ int src[1024];
+ int dst[1024];
+ memmove_t fn = get_memmove ();
+ memset (src, 0, sizeof (src));
+ src[42] = a;
+ src[100] = b;
+ __analyzer_eval (src[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (src[42] == a); /* { dg-warning "TRUE" } */
+ __analyzer_eval (src[100] == b); /* { dg-warning "TRUE" } */
+ __analyzer_eval (src[1023] == 0); /* { dg-warning "TRUE" } */
+
+ fn (dst, src, sizeof (src));
+ __analyzer_eval (dst[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (dst[42] == a); /* { dg-warning "TRUE" } */
+ __analyzer_eval (dst[100] == b); /* { dg-warning "TRUE" } */
+ __analyzer_eval (dst[1023] == 0); /* { dg-warning "TRUE" } */
+}
+
+/* Populating a buffer from an unknown buffer. */
+
+void test_5 (void *src, size_t sz)
+{
+ char dst[1024];
+ memmove (dst, src, sizeof (dst));
+ __analyzer_eval (dst[0] == 0); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (dst[1023] == 0); /* { dg-warning "UNKNOWN" } */
+}
+
+void test_5b (void *src, size_t sz)
+{
+ char dst[1024];
+ memmove_t fn = get_memmove ();
+ fn (dst, src, sizeof (dst));
+ __analyzer_eval (dst[0] == 0); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (dst[1023] == 0); /* { dg-warning "UNKNOWN" } */
+}
+
+/* Zero-sized memmove. */
+
+void test_6 (void *dst, void *src)
+{
+ memmove (dst, src, 0);
+}
+
+void test_6b (void *dst, void *src)
+{
+ memmove_t fn = get_memmove ();
+ fn (dst, src, 0);
+}
+
+/* memmove to string literal. */
+
+void test_7 (void *src, size_t sz)
+{
+ memmove ((void *)"hello world", src, sz); /* { dg-warning "write to string literal" } */
+}
+
+void test_7b (void *src, size_t sz)
+{
+ memmove ((void *)"hello world", src, sz); /* { dg-warning "write to string literal" } */
+}
+
+/* memcpy from uninitialized buffer. */
+
+void test_8a (void *dst)
+{
+ char src[16];
+ memmove (dst, src, 16); /* { dg-warning "use of uninitialized value" } */
+}
+
+void test_8b (void *dst, size_t n)
+{
+ char src[16];
+ memmove (dst, src, n); /* { dg-warning "use of uninitialized value" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/named-constants-Wunused-macros.c b/gcc/testsuite/gcc.dg/analyzer/named-constants-Wunused-macros.c
new file mode 100644
index 0000000..0b31cc4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/named-constants-Wunused-macros.c
@@ -0,0 +1,19 @@
+/* Regression test for interaction of named constants in -fanalyzer with
+ -Wunused-macros (PR analyzer/107711). */
+
+/* { dg-additional-options "-Wunused-macros" } */
+
+#include "analyzer-decls.h"
+
+/* Various constants used by the fd state machine. */
+
+#define O_ACCMODE 42 /* { dg-warning "-: macro \"O_ACCMODE\" is not used" } */
+#define O_RDONLY 0x1 /* { dg-warning "-: macro \"O_RDONLY\" is not used" } */
+#define O_WRONLY 010 /* { dg-warning "-: macro \"O_WRONLY\" is not used" } */
+
+void test_sm_fd_constants (void)
+{
+ __analyzer_dump_named_constant ("O_ACCMODE"); /* { dg-warning "named constant 'O_ACCMODE' has value '42'" } */
+ __analyzer_dump_named_constant ("O_RDONLY"); /* { dg-warning "named constant 'O_RDONLY' has value '1'" } */
+ __analyzer_dump_named_constant ("O_WRONLY"); /* { dg-warning "named constant 'O_WRONLY' has value '8'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/named-constants-via-command-line.c b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-command-line.c
new file mode 100644
index 0000000..4a3dd16
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-command-line.c
@@ -0,0 +1,10 @@
+/* { dg-additional-options "-DO_ACCMODE=42 -DO_RDONLY=0x1 -DO_WRONLY=010" } */
+
+#include "analyzer-decls.h"
+
+void test_sm_fd_constants (void)
+{
+ __analyzer_dump_named_constant ("O_ACCMODE"); /* { dg-warning "named constant 'O_ACCMODE' has value '42'" } */
+ __analyzer_dump_named_constant ("O_RDONLY"); /* { dg-warning "named constant 'O_RDONLY' has value '1'" } */
+ __analyzer_dump_named_constant ("O_WRONLY"); /* { dg-warning "named constant 'O_WRONLY' has value '8'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/named-constants-via-enum-and-macro.c b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-enum-and-macro.c
new file mode 100644
index 0000000..9e6cbee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-enum-and-macro.c
@@ -0,0 +1,12 @@
+#include "analyzer-decls.h"
+
+enum __foo {
+ O_ACCMODE = 1,
+
+#define O_ACCMODE O_ACCMODE
+};
+
+void test_sm_fd_constants (void)
+{
+ __analyzer_dump_named_constant ("O_ACCMODE"); /* { dg-warning "named constant 'O_ACCMODE' has value '1'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/named-constants-via-enum.c b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-enum.c
new file mode 100644
index 0000000..e6b77b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-enum.c
@@ -0,0 +1,20 @@
+#include "analyzer-decls.h"
+
+/* Various constants used by the fd state machine. */
+enum {
+ O_ACCMODE = 42,
+ O_RDONLY = 0x1,
+ O_WRONLY = 010
+};
+
+void test_sm_fd_constants (void)
+{
+ __analyzer_dump_named_constant ("O_ACCMODE"); /* { dg-warning "named constant 'O_ACCMODE' has value '42'" } */
+ __analyzer_dump_named_constant ("O_RDONLY"); /* { dg-warning "named constant 'O_RDONLY' has value '1'" } */
+ __analyzer_dump_named_constant ("O_WRONLY"); /* { dg-warning "named constant 'O_WRONLY' has value '8'" } */
+}
+
+void test_unknown (void)
+{
+ __analyzer_dump_named_constant ("UNKNOWN"); /* { dg-warning "named constant 'UNKNOWN' has unknown value" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-2.c b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-2.c
new file mode 100644
index 0000000..9c019e7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-2.c
@@ -0,0 +1,15 @@
+#include "analyzer-decls.h"
+
+/* Various constants used by the fd state machine, as macros
+ that can't be handled. */
+
+#define O_ACCMODE (
+#define O_RDONLY "foo"
+#define O_WRONLY int
+
+void test_sm_fd_constants (void)
+{
+ __analyzer_dump_named_constant ("O_ACCMODE"); /* { dg-warning "named constant 'O_ACCMODE' has unknown value" } */
+ __analyzer_dump_named_constant ("O_RDONLY"); /* { dg-warning "named constant 'O_RDONLY' has unknown value" } */
+ __analyzer_dump_named_constant ("O_WRONLY"); /* { dg-warning "named constant 'O_WRONLY' has unknown value" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-3.c b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-3.c
new file mode 100644
index 0000000..2a3f2b0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-3.c
@@ -0,0 +1,15 @@
+#include "analyzer-decls.h"
+
+/* Various constants used by the fd state machine, as macros
+ that can't be handled. */
+
+#define O_RDONLY (1 << 0)
+#define O_WRONLY (1 << 1)
+#define O_ACCMODE (O_RDONLY | O_WRONLY)
+
+void test_sm_fd_constants (void)
+{
+ __analyzer_dump_named_constant ("O_ACCMODE"); /* { dg-warning "named constant 'O_ACCMODE' has unknown value" } */
+ __analyzer_dump_named_constant ("O_RDONLY"); /* { dg-warning "named constant 'O_RDONLY' has unknown value" } */
+ __analyzer_dump_named_constant ("O_WRONLY"); /* { dg-warning "named constant 'O_WRONLY' has unknown value" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-4.c b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-4.c
new file mode 100644
index 0000000..16eef96
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-4.c
@@ -0,0 +1,15 @@
+#include "analyzer-decls.h"
+
+/* Various constants used by the fd state machine, as macros
+ that can't be handled. */
+
+#define O_ACCMODE(X) 42
+#define O_RDONLY(X) 0x1
+#define O_WRONLY(X) 010
+
+void test_sm_fd_constants (void)
+{
+ __analyzer_dump_named_constant ("O_ACCMODE"); /* { dg-warning "named constant 'O_ACCMODE' has unknown value" } */
+ __analyzer_dump_named_constant ("O_RDONLY"); /* { dg-warning "named constant 'O_RDONLY' has unknown value" } */
+ __analyzer_dump_named_constant ("O_WRONLY"); /* { dg-warning "named constant 'O_WRONLY' has unknown value" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-empty.c b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-empty.c
new file mode 100644
index 0000000..3d347e2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-empty.c
@@ -0,0 +1,14 @@
+#include "analyzer-decls.h"
+
+/* Various constants used by the fd state machine. */
+
+#define O_ACCMODE
+#define O_RDONLY
+#define O_WRONLY
+
+void test_sm_fd_constants (void)
+{
+ __analyzer_dump_named_constant ("O_ACCMODE"); /* { dg-warning "named constant 'O_ACCMODE' has unknown value" } */
+ __analyzer_dump_named_constant ("O_RDONLY"); /* { dg-warning "named constant 'O_RDONLY' has unknown value" } */
+ __analyzer_dump_named_constant ("O_WRONLY"); /* { dg-warning "named constant 'O_WRONLY' has unknown value" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-gc.c b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-gc.c
new file mode 100644
index 0000000..e7b12f3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-gc.c
@@ -0,0 +1,21 @@
+/* { dg-additional-options "--param ggc-min-expand=0 --param ggc-min-heapsize=0" } */
+
+#include "analyzer-decls.h"
+
+/* Various constants used by the fd state machine. */
+
+#define O_ACCMODE 42
+#define O_RDONLY 0x1
+#define O_WRONLY 010
+
+void test_sm_fd_constants (void)
+{
+ __analyzer_dump_named_constant ("O_ACCMODE"); /* { dg-warning "named constant 'O_ACCMODE' has value '42'" } */
+ __analyzer_dump_named_constant ("O_RDONLY"); /* { dg-warning "named constant 'O_RDONLY' has value '1'" } */
+ __analyzer_dump_named_constant ("O_WRONLY"); /* { dg-warning "named constant 'O_WRONLY' has value '8'" } */
+}
+
+void test_unknown (void)
+{
+ __analyzer_dump_named_constant ("UNKNOWN"); /* { dg-warning "named constant 'UNKNOWN' has unknown value" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-traditional.c b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-traditional.c
new file mode 100644
index 0000000..64acaad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-traditional.c
@@ -0,0 +1,16 @@
+/* { dg-additional-options "-traditional-cpp" } */
+
+#include "analyzer-decls.h"
+
+/* Various constants used by the fd state machine. */
+
+#define O_ACCMODE 42
+#define O_RDONLY 0x1
+#define O_WRONLY 010
+
+void test_sm_fd_constants (void)
+{
+ __analyzer_dump_named_constant ("O_ACCMODE"); /* { dg-warning "named constant 'O_ACCMODE' has unknown value" } */
+ __analyzer_dump_named_constant ("O_RDONLY"); /* { dg-warning "named constant 'O_RDONLY' has unknown value" } */
+ __analyzer_dump_named_constant ("O_WRONLY"); /* { dg-warning "named constant 'O_WRONLY' has unknown value" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-undef.c b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-undef.c
new file mode 100644
index 0000000..46c0322
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-undef.c
@@ -0,0 +1,18 @@
+#include "analyzer-decls.h"
+
+/* Various constants used by the fd state machine. */
+
+#define O_ACCMODE 42
+#define O_RDONLY 0x1
+#define O_WRONLY 010
+
+#undef O_ACCMODE
+#undef O_RDONLY
+#undef O_WRONLY
+
+void test_sm_fd_constants (void)
+{
+ __analyzer_dump_named_constant ("O_ACCMODE"); /* { dg-warning "named constant 'O_ACCMODE' has unknown value" } */
+ __analyzer_dump_named_constant ("O_RDONLY"); /* { dg-warning "named constant 'O_RDONLY' has unknown value" } */
+ __analyzer_dump_named_constant ("O_WRONLY"); /* { dg-warning "named constant 'O_WRONLY' has unknown value" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros.c b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros.c
new file mode 100644
index 0000000..2022f98
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros.c
@@ -0,0 +1,19 @@
+#include "analyzer-decls.h"
+
+/* Various constants used by the fd state machine. */
+
+#define O_ACCMODE 42
+#define O_RDONLY 0x1
+#define O_WRONLY 010
+
+void test_sm_fd_constants (void)
+{
+ __analyzer_dump_named_constant ("O_ACCMODE"); /* { dg-warning "named constant 'O_ACCMODE' has value '42'" } */
+ __analyzer_dump_named_constant ("O_RDONLY"); /* { dg-warning "named constant 'O_RDONLY' has value '1'" } */
+ __analyzer_dump_named_constant ("O_WRONLY"); /* { dg-warning "named constant 'O_WRONLY' has value '8'" } */
+}
+
+void test_unknown (void)
+{
+ __analyzer_dump_named_constant ("UNKNOWN"); /* { dg-warning "named constant 'UNKNOWN' has unknown value" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-1.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-1.c
index 9f3cda6..93b379c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-1.c
@@ -25,8 +25,9 @@ void test1 (void)
id_sequence[2] = 345;
id_sequence[3] = 456; /* { dg-line test1 } */
- /* { dg-warning "overflow" "warning" { target *-*-* } test1 } */
- /* { dg-message "" "note" { target *-*-* } test1 } */
+ /* { dg-warning "stack-based buffer overflow" "warning" { target *-*-* } test1 } */
+ /* { dg-message "write of 4 bytes to beyond the end of 'id_sequence'" "num bad bytes note" { target *-*-* } test1 } */
+ /* { dg-message "valid subscripts for 'id_sequence' are '\\\[0\\\]' to '\\\[2\\\]'" "valid subscript note" { target *-*-* } test1 } */
}
void test2 (void)
@@ -46,8 +47,9 @@ void test3 (void)
for (int i = n; i >= 0; i--)
arr[i] = i; /* { dg-line test3 } */
- /* { dg-warning "overflow" "warning" { target *-*-* } test3 } */
- /* { dg-message "" "note" { target *-*-* } test3 } */
+ /* { dg-warning "stack-based buffer overflow" "warning" { target *-*-* } test3 } */
+ /* { dg-message "write of 4 bytes to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } test3 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[3\\\]'" "valid subscript note" { target *-*-* } test3 } */
}
void test4 (void)
@@ -72,7 +74,7 @@ void test5 (void)
*last_el = 4; /* { dg-line test5 } */
free (arr);
- /* { dg-warning "overflow" "warning" { target *-*-* } test5 } */
+ /* { dg-warning "heap-based buffer overflow" "warning" { target *-*-* } test5 } */
/* { dg-message "" "note" { target *-*-* } test5 } */
}
@@ -89,9 +91,9 @@ void test6 (void)
printf ("x=%d y=%d *p=%d *q=%d\n" , x, y, *p, *q); /* { dg-line test6c } */
}
- /* { dg-warning "overflow" "warning" { target *-*-* } test6b } */
+ /* { dg-warning "buffer overflow" "warning" { target *-*-* } test6b } */
/* { dg-message "" "note" { target *-*-* } test6b } */
- /* { dg-warning "overread" "warning" { target *-*-* } test6c } */
+ /* { dg-warning "buffer over-read" "warning" { target *-*-* } test6c } */
/* { dg-message "" "note" { target *-*-* } test6c } */
}
@@ -114,7 +116,7 @@ void test7 (void)
fn (destBuf, srcBuf, returnChunkSize (destBuf)); /* { dg-line test7 } */
// TODO: Should we handle widening_svalues as a follow-up?
- /* { dg-warning "overread" "warning" { xfail *-*-* } test7 } */
+ /* { dg-warning "over-read" "warning" { xfail *-*-* } test7 } */
+ /* { dg-warning "use of uninitialized value" "uninit warning" { target *-*-* } test7 } */
/* { dg-warning "overflow" "warning" { xfail *-*-* } test7 } */
- /* { dg-message "" "note" { xfail *-*-* } test7 } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-2.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-2.c
index 0df9364..1330090 100644
--- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-2.c
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-2.c
@@ -3,7 +3,7 @@
#include <stdio.h>
#include <stdint.h>
-/* Wanalyzer-out-of-bounds tests for buffer overreads. */
+/* Wanalyzer-out-of-bounds tests for buffer over-reads. */
/* Avoid folding of memcpy. */
typedef void * (*memcpy_t) (void *dst, const void *src, size_t n);
@@ -21,8 +21,9 @@ void test1 (void)
memset (id_sequence, 0, 3 * sizeof(int));
printf ("%i", id_sequence[3]); /* { dg-line test1 } */
- /* { dg-warning "overread" "warning" { target *-*-* } test1 } */
- /* { dg-message "" "note" { target *-*-* } test1 } */
+ /* { dg-warning "stack-based buffer over-read" "warning" { target *-*-* } test1 } */
+ /* { dg-message "read of 4 bytes from after the end of 'id_sequence'" "num bad bytes note" { target *-*-* } test1 } */
+ /* { dg-message "valid subscripts for 'id_sequence' are '\\\[0\\\]' to '\\\[2\\\]'" "valid subscript note" { target *-*-* } test1 } */
}
void test2 (void)
@@ -46,7 +47,7 @@ void test3 (void)
for (int i = n; i > 0; i--)
sum += arr[i]; /* { dg-line test3 } */
- /* { dg-warning "overread" "warning" { target *-*-* } test3 } */
+ /* { dg-warning "stack-based buffer over-read" "warning" { target *-*-* } test3 } */
/* { dg-message "" "note" { target *-*-* } test3 } */
}
@@ -78,6 +79,8 @@ void test5 (void)
sum += *(arr + i); /* { dg-line test5 } */
free (arr);
- /* { dg-warning "overread" "warning" { target *-*-* } test5 } */
- /* { dg-message "" "note" { target *-*-* } test5 } */
+ /* { dg-warning "heap-based buffer over-read" "bounds warning" { target *-*-* } test5 } */
+ /* { dg-message "read of 4 bytes from after the end of the region" "num bad bytes note" { target *-*-* } test5 } */
+
+ /* { dg-warning "use of uninitialized value" "uninit warning" { target *-*-* } test5 } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-3.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-3.c
index 7446b18..5fd9cc3 100644
--- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-3.c
@@ -2,7 +2,7 @@
#include <string.h>
#include <stdint.h>
-/* Wanalyzer-out-of-bounds tests for buffer underreads and writes. */
+/* Wanalyzer-out-of-bounds tests for buffer under-reads and underwrites. */
/* Avoid folding of memcpy. */
typedef void * (*memcpy_t) (void *dst, const void *src, size_t n);
@@ -19,8 +19,9 @@ void test1 (void)
int *e = buf - 1;
*e = 42; /* { dg-line test1 } */
- /* { dg-warning "underflow" "warning" { target *-*-* } test1 } */
- /* { dg-message "" "note" { target *-*-* } test1 } */
+ /* { dg-warning "stack-based buffer underwrite" "warning" { target *-*-* } test1 } */
+ /* { dg-message "out-of-bounds write from byte -4 till byte -1 but 'buf' starts at byte 0" "final event" { target *-*-* } test1 } */
+ /* { dg-message "valid subscripts for 'buf' are '\\\[0\\\]' to '\\\[3\\\]'" "valid subscript note" { target *-*-* } test1 } */
}
void test2 (void)
@@ -38,8 +39,9 @@ void test3 (void)
*e = 123;
*(e - 2) = 321; /* { dg-line test3 } */
- /* { dg-warning "underflow" "warning" { target *-*-* } test3 } */
- /* { dg-message "" "note" { target *-*-* } test3 } */
+ /* { dg-warning "stack-based buffer underwrite" "warning" { target *-*-* } test3 } */
+ /* { dg-message "out-of-bounds write from byte -4 till byte -1 but 'buf' starts at byte 0" "final event" { target *-*-* } test3 } */
+ /* { dg-message "valid subscripts for 'buf' are '\\\[0\\\]' to '\\\[3\\\]'" "valid subscript note" { target *-*-* } test3 } */
}
void test4 (void)
@@ -50,8 +52,9 @@ void test4 (void)
int n = -4;
fn (&(buf[n]), buf, sizeof (int)); /* { dg-line test4 } */
- /* { dg-warning "underflow" "warning" { target *-*-* } test4 } */
- /* { dg-message "" "note" { target *-*-* } test4 } */
+ /* { dg-warning "stack-based buffer underwrite" "warning" { target *-*-* } test4 } */
+ /* { dg-message "out-of-bounds write from byte -16 till byte -13 but 'buf' starts at byte 0" "final event" { target *-*-* } test4 } */
+ /* { dg-message "valid subscripts for 'buf' are '\\\[0\\\]' to '\\\[3\\\]'" "valid subscript note" { target *-*-* } test4 } */
}
void test5 (void)
@@ -63,8 +66,9 @@ void test5 (void)
for (int i = 4; i >= 0; i++)
sum += *(buf - i); /* { dg-line test5 } */
- /* { dg-warning "underread" "warning" { target *-*-* } test5 } */
- /* { dg-message "" "note" { target *-*-* } test5 } */
+ /* { dg-warning "stack-based buffer under-read" "warning" { target *-*-* } test5 } */
+ /* { dg-message "out-of-bounds read from byte -16 till byte -13 but 'buf' starts at byte 0" "final event" { target *-*-* } test5 } */
+ /* { dg-message "valid subscripts for 'buf' are '\\\[0\\\]' to '\\\[3\\\]'" "valid subscript note" { target *-*-* } test5 } */
}
void test6 (void)
@@ -86,6 +90,7 @@ void test8 (void)
int n = -4;
fn (buf, &(buf[n]), sizeof (int)); /* { dg-line test8 } */
- /* { dg-warning "underread" "warning" { target *-*-* } test8 } */
- /* { dg-message "" "note" { target *-*-* } test8 } */
+ /* { dg-warning "stack-based buffer under-read" "warning" { target *-*-* } test8 } */
+ /* { dg-message "out-of-bounds read from byte -16 till byte -13 but 'buf' starts at byte 0" "note" { target *-*-* } test8 } */
+ /* { dg-message "valid subscripts for 'buf' are '\\\[0\\\]' to '\\\[3\\\]'" "valid subscript note" { target *-*-* } test8 } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-4.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-4.c
index 46f600d..9cd8bda 100644
--- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-4.c
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-4.c
@@ -11,8 +11,9 @@ void test1 (void)
char dst[5];
strcpy (dst, "Hello"); /* { dg-line test1 } */
- /* { dg-warning "overflow" "warning" { target *-*-* } test1 } */
- /* { dg-message "dst" "note" { target *-*-* } test1 } */
+ /* { dg-warning "stack-based buffer overflow" "warning" { target *-*-* } test1 } */
+ /* { dg-message "write of 1 byte to beyond the end of 'dst'" "num bad bytes note" { target *-*-* } test1 } */
+ /* { dg-message "valid subscripts for 'dst' are '\\\[0\\\]' to '\\\[4\\\]'" "valid subscript note" { target *-*-* } test1 } */
}
void test2 (void)
@@ -27,8 +28,9 @@ void test3 (void)
char dst[5];
strcpy (dst, src); /* { dg-line test3 } */
- /* { dg-warning "overflow" "warning" { target *-*-* } test3 } */
- /* { dg-message "dst" "note" { target *-*-* } test3 } */
+ /* { dg-warning "stack-based buffer overflow" "warning" { target *-*-* } test3 } */
+ /* { dg-message "write of 1 byte to beyond the end of 'dst'" "num bad bytes note" { target *-*-* } test3 } */
+ /* { dg-message "valid subscripts for 'dst' are '\\\[0\\\]' to '\\\[4\\\]'" "valid subscript note" { target *-*-* } test3 } */
}
void test4 (void)
@@ -51,8 +53,9 @@ void test5 (void)
char dst[5];
strcpy (dst, str); /* { dg-line test5 } */
- /* { dg-warning "overflow" "warning" { target *-*-* } test5 } */
- /* { dg-message "dst" "note" { target *-*-* } test5 } */
+ /* { dg-warning "stack-based buffer overflow" "warning" { target *-*-* } test5 } */
+ /* { dg-message "write of 1 byte to beyond the end of 'dst'" "num bad bytes note" { target *-*-* } test5 } */
+ /* { dg-message "valid subscripts for 'dst' are '\\\[0\\\]' to '\\\[4\\\]'" "valid subscript note" { target *-*-* } test5 } */
}
void test6 (void)
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-5.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-5.c
index 7dc0bc5..eb6aae0 100644
--- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-5.c
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-5.c
@@ -13,7 +13,7 @@ void test1 (size_t size)
char *buf = __builtin_malloc (size);
if (!buf) return;
- buf[size] = '\0'; /* { dg-warning "overflow" } */
+ buf[size] = '\0'; /* { dg-warning "heap-based buffer overflow" } */
free (buf);
}
@@ -22,7 +22,7 @@ void test2 (size_t size)
char *buf = __builtin_malloc (size);
if (!buf) return;
- buf[size + 1] = '\0'; /* { dg-warning "overflow" } */
+ buf[size + 1] = '\0'; /* { dg-warning "heap-based buffer overflow" } */
free (buf);
}
@@ -31,33 +31,33 @@ void test3 (size_t size, size_t op)
char *buf = __builtin_malloc (size);
if (!buf) return;
- buf[size + op] = '\0'; /* { dg-warning "overflow" } */
+ buf[size + op] = '\0'; /* { dg-warning "heap-based buffer overflow" } */
free (buf);
}
void test4 (size_t size, unsigned short s)
{
char *buf = __builtin_alloca (size);
- buf[size + s] = '\0'; /* { dg-warning "overflow" } */
+ buf[size + s] = '\0'; /* { dg-warning "stack-based buffer overflow" } */
}
void test5 (size_t size)
{
int32_t *buf = __builtin_alloca (4 * size);
- buf[size] = 42; /* { dg-warning "overflow" } */
+ buf[size] = 42; /* { dg-warning "stack-based buffer overflow" } */
}
void test6 (size_t size)
{
int32_t *buf = __builtin_alloca (4 * size);
memset (buf, 0, 4 * size);
- int32_t last = *(buf + 4 * size); /* { dg-warning "overread" } */
+ int32_t last = *(buf + 4 * size); /* { dg-warning "stack-based buffer over-read" } */
}
void test7 (size_t size)
{
int32_t *buf = __builtin_alloca (4 * size + 3); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */
- buf[size] = 42; /* { dg-warning "overflow" } */
+ buf[size] = 42; /* { dg-warning "stack-based buffer overflow" } */
}
/* Test where the offset itself is not out-of-bounds
@@ -68,7 +68,8 @@ void test8 (size_t size, size_t offset)
char src[size];
char dst[size];
memcpy (dst, src, size + offset); /* { dg-line test8 } */
- /* { dg-warning "overread" "warning" { target *-*-* } test8 } */
+ /* { dg-warning "over-read" "warning" { target *-*-* } test8 } */
+ /* { dg-warning "use of uninitialized value" "warning" { target *-*-* } test8 } */
/* { dg-warning "overflow" "warning" { target *-*-* } test8 } */
}
@@ -77,7 +78,8 @@ void test9 (size_t size, size_t offset)
int32_t src[size];
int32_t dst[size];
memcpy (dst, src, 4 * size + 1); /* { dg-line test9 } */
- /* { dg-warning "overread" "warning" { target *-*-* } test9 } */
+ /* { dg-warning "over-read" "warning" { target *-*-* } test9 } */
+ /* { dg-warning "use of uninitialized value" "warning" { target *-*-* } test9 } */
/* { dg-warning "overflow" "warning" { target *-*-* } test9 } */
}
@@ -151,6 +153,6 @@ char *test99 (const char *x, const char *y)
__builtin_memcpy (result, x, len_x);
__builtin_memcpy (result + len_x, y, len_y);
/* BUG (symptom): off-by-one out-of-bounds write to heap. */
- result[len_x + len_y] = '\0'; /* { dg-warning "overflow" } */
+ result[len_x + len_y] = '\0'; /* { dg-warning "heap-based buffer overflow" } */
return result;
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-container_of.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-container_of.c
index 172ec47..ef460f4 100644
--- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-container_of.c
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-container_of.c
@@ -44,8 +44,8 @@ int test (struct outer *outer_p, struct inner *inner_p)
sum += o->i; /* { dg-line testB } */
return sum;
- /* { dg-warning "underread" "warning" { target *-*-* } testA } */
+ /* { dg-warning "stack-based buffer under-read" "warning" { target *-*-* } testA } */
/* { dg-message "" "note" { target *-*-* } testA } */
- /* { dg-warning "underread" "warning" { target *-*-* } testB } */
+ /* { dg-warning "stack-based buffer under-read" "warning" { target *-*-* } testB } */
/* { dg-message "" "note" { target *-*-* } testB } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-multiline-1.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-multiline-1.c
new file mode 100644
index 0000000..ca5022d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-multiline-1.c
@@ -0,0 +1,37 @@
+/* Integration test of how the execution path looks for
+ -Wanalyzer-out-of-bounds. */
+
+/* { dg-additional-options "-fdiagnostics-show-path-depths" } */
+/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
+
+
+#include <stdint.h>
+
+int32_t arr[10];
+
+void int_arr_write_element_after_end_off_by_one(int32_t x)
+{
+ arr[10] = x; /* { dg-line line } */
+}
+/* { dg-warning "buffer overflow" "warning" { target *-*-* } line } */
+/* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } line } */
+
+
+/* { dg-begin-multiline-output "" }
+ arr[10] = x;
+ ~~~~~~~~^~~
+ event 1 (depth 0)
+ |
+ | int32_t arr[10];
+ | ^~~
+ | |
+ | (1) capacity: 40 bytes
+ |
+ +--> 'int_arr_write_element_after_end_off_by_one': event 2 (depth 1)
+ |
+ | arr[10] = x;
+ | ~~~~~~~~^~~
+ | |
+ | (2) out-of-bounds write from byte 40 till byte 43 but 'arr' ends at byte 40
+ |
+ { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-multiline-2.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-multiline-2.c
new file mode 100644
index 0000000..660901a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-multiline-2.c
@@ -0,0 +1,32 @@
+/* Integration test of how the execution path looks for
+ -Wanalyzer-out-of-bounds with a symbolic size. */
+
+/* { dg-additional-options "-fdiagnostics-show-path-depths" } */
+/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+void int_vla_write_element_after_end_off_by_one(int32_t x, size_t n)
+{
+ int32_t arr[n];
+
+ arr[n] = x; /* { dg-warning "stack-based buffer overflow" } */
+}
+
+/* { dg-begin-multiline-output "" }
+ arr[n] = x;
+ ~~~~~~~^~~
+ 'int_vla_write_element_after_end_off_by_one': events 1-2 (depth 1)
+ |
+ | int32_t arr[n];
+ | ^~~
+ | |
+ | (1) capacity: 'n * 4' bytes
+ |
+ | arr[n] = x;
+ | ~~~~~~~~~~
+ | |
+ | (2) write of 4 bytes at offset 'n * 4' exceeds the buffer
+ |
+ { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-char-arr.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-char-arr.c
index 61cbfc7..fa4b613 100644
--- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-char-arr.c
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-char-arr.c
@@ -1,55 +1,56 @@
-char arr[10]; /* { dg-message "capacity is 10 bytes" } */
+char arr[10]; /* { dg-message "capacity: 10 bytes" } */
-char int_arr_read_element_before_start_far(void)
+char char_arr_read_element_before_start_far(void)
{
- return arr[-100]; /* { dg-warning "buffer underread" "warning" } */
+ return arr[-100]; /* { dg-warning "buffer under-read" "warning" } */
/* { dg-message "out-of-bounds read at byte -100 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
}
-char int_arr_read_element_before_start_near(void)
+char char_arr_read_element_before_start_near(void)
{
- return arr[-2]; /* { dg-warning "buffer underread" "warning" } */
+ return arr[-2]; /* { dg-warning "buffer under-read" "warning" } */
/* { dg-message "out-of-bounds read at byte -2 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
}
-char int_arr_read_element_before_start_off_by_one(void)
+char char_arr_read_element_before_start_off_by_one(void)
{
- return arr[-1]; /* { dg-warning "buffer underread" "warning" } */
+ return arr[-1]; /* { dg-warning "buffer under-read" "warning" } */
/* { dg-message "out-of-bounds read at byte -1 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
}
-char int_arr_read_element_at_start(void)
+char char_arr_read_element_at_start(void)
{
return arr[0];
}
-char int_arr_read_element_at_end(void)
+char char_arr_read_element_at_end(void)
{
return arr[9];
}
-char int_arr_read_element_after_end_off_by_one(void)
+char char_arr_read_element_after_end_off_by_one(void)
{
- return arr[10]; /* { dg-warning "buffer overread" "warning" } */
+ return arr[10]; /* { dg-warning "buffer over-read" "warning" } */
/* { dg-message "out-of-bounds read at byte 10 but 'arr' ends at byte 10" "final event" { target *-*-* } .-1 } */
- /* { dg-message "read is 1 bytes past the end of 'arr'" "note" { target *-*-* } .-2 } */
- // FIXME(PR 106626): "1 bytes"
+ /* { dg-message "read of 1 byte from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
-char int_arr_read_element_after_end_near(void)
+char char_arr_read_element_after_end_near(void)
{
- return arr[11]; /* { dg-warning "buffer overread" "warning" } */
+ return arr[11]; /* { dg-warning "buffer over-read" "warning" } */
/* { dg-message "out-of-bounds read at byte 11 but 'arr' ends at byte 10" "final event" { target *-*-* } .-1 } */
- /* { dg-message "read is 1 bytes past the end of 'arr'" "note" { target *-*-* } .-2 } */
- // FIXME(PR 106626): is the note correct?
- // FIXME(PR 106626): "1 bytes"
+ /* { dg-message "read of 1 byte from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
-char int_arr_read_element_after_end_far(void)
+char char_arr_read_element_after_end_far(void)
{
- return arr[100]; /* { dg-warning "buffer overread" "warning" } */
+ return arr[100]; /* { dg-warning "buffer over-read" "warning" } */
/* { dg-message "out-of-bounds read at byte 100 but 'arr' ends at byte 10" "final event" { target *-*-* } .-1 } */
- /* { dg-message "read is 1 bytes past the end of 'arr'" "note" { target *-*-* } .-2 } */
- // FIXME(PR 106626): the note seems incorrect (size of access is 1 byte, but magnitude beyond boundary is 90)
- // FIXME(PR 106626): "1 bytes"
+ /* { dg-message "read of 1 byte from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-int-arr.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-int-arr.c
index 0bb30d2..c04cc19 100644
--- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-int-arr.c
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-int-arr.c
@@ -1,23 +1,26 @@
#include <stdint.h>
-int32_t arr[10]; /* { dg-message "capacity is 40 bytes" } */
+int32_t arr[10]; /* { dg-message "capacity: 40 bytes" } */
int32_t int_arr_read_element_before_start_far(void)
{
- return arr[-100]; /* { dg-warning "buffer underread" "warning" } */
+ return arr[-100]; /* { dg-warning "buffer under-read" "warning" } */
/* { dg-message "out-of-bounds read from byte -400 till byte -397 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
}
int32_t int_arr_read_element_before_start_near(void)
{
- return arr[-2]; /* { dg-warning "buffer underread" "warning" } */
+ return arr[-2]; /* { dg-warning "buffer under-read" "warning" } */
/* { dg-message "out-of-bounds read from byte -8 till byte -5 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
}
int32_t int_arr_read_element_before_start_off_by_one(void)
{
- return arr[-1]; /* { dg-warning "buffer underread" "warning" } */
+ return arr[-1]; /* { dg-warning "buffer under-read" "warning" } */
/* { dg-message "out-of-bounds read from byte -4 till byte -1 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
}
int32_t int_arr_read_element_at_start(void)
@@ -32,23 +35,24 @@ int32_t int_arr_read_element_at_end(void)
int32_t int_arr_read_element_after_end_off_by_one(void)
{
- return arr[10]; /* { dg-warning "buffer overread" "warning" } */
+ return arr[10]; /* { dg-warning "buffer over-read" "warning" } */
/* { dg-message "out-of-bounds read from byte 40 till byte 43 but 'arr' ends at byte 40" "final event" { target *-*-* } .-1 } */
- /* { dg-message "read is 4 bytes past the end of 'arr'" "note" { target *-*-* } .-2 } */
+ /* { dg-message "read of 4 bytes from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
int32_t int_arr_read_element_after_end_near(void)
{
- return arr[11]; /* { dg-warning "buffer overread" "warning" } */
+ return arr[11]; /* { dg-warning "buffer over-read" "warning" } */
/* { dg-message "out-of-bounds read from byte 44 till byte 47 but 'arr' ends at byte 40" "final event" { target *-*-* } .-1 } */
- /* { dg-message "read is 4 bytes past the end of 'arr'" "note" { target *-*-* } .-2 } */
- // FIXME(PR 106626): is the note correct?
+ /* { dg-message "read of 4 bytes from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
int32_t int_arr_read_element_after_end_far(void)
{
- return arr[100]; /* { dg-warning "buffer overread" "warning" } */
+ return arr[100]; /* { dg-warning "buffer over-read" "warning" } */
/* { dg-message "out-of-bounds read from byte 400 till byte 403 but 'arr' ends at byte 40" "final event" { target *-*-* } .-1 } */
- /* { dg-message "read is 4 bytes past the end of 'arr'" "note" { target *-*-* } .-2 } */
- // FIXME(PR 106626): the note seems incorrect (size of access is 4 bytes, but magnitude beyond boundary is 390-393)
+ /* { dg-message "read of 4 bytes from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-struct-arr.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-struct-arr.c
new file mode 100644
index 0000000..0f50bb9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-struct-arr.c
@@ -0,0 +1,65 @@
+#include <stdint.h>
+
+struct st
+{
+ char buf[16];
+ int32_t x;
+ int32_t y;
+};
+
+struct st arr[10];
+
+int32_t struct_arr_read_x_element_before_start_far(void)
+{
+ return arr[-100].x; /* { dg-warning "buffer under-read" "warning" } */
+ /* { dg-message "out-of-bounds read from byte -2384 till byte -2381 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
+}
+
+int32_t struct_arr_read_x_element_before_start_near(void)
+{
+ return arr[-2].x; /* { dg-warning "buffer under-read" "warning" } */
+ /* { dg-message "out-of-bounds read from byte -32 till byte -29 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
+}
+
+int32_t struct_arr_read_x_element_before_start_off_by_one(void)
+{
+ return arr[-1].x; /* { dg-warning "buffer under-read" "warning" } */
+ /* { dg-message "out-of-bounds read from byte -8 till byte -5 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
+}
+
+int32_t struct_arr_read_x_element_at_start(void)
+{
+ return arr[0].x;
+}
+
+int32_t struct_arr_read_x_element_at_end(void)
+{
+ return arr[9].x;
+}
+
+int32_t struct_arr_read_x_element_after_end_off_by_one(void)
+{
+ return arr[10].x; /* { dg-warning "buffer over-read" "warning" } */
+ /* { dg-message "out-of-bounds read from byte 256 till byte 259 but 'arr' ends at byte 240" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "read of 4 bytes from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
+}
+
+int32_t struct_arr_read_x_element_after_end_near(void)
+{
+ return arr[11].x; /* { dg-warning "buffer over-read" "warning" } */
+ /* { dg-message "out-of-bounds read from byte 280 till byte 283 but 'arr' ends at byte 240" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "read of 4 bytes from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
+}
+
+int32_t struct_arr_read_x_element_after_end_far(void)
+{
+ return arr[100].x; /* { dg-warning "buffer over-read" "warning" } */
+ /* { dg-message "out-of-bounds read from byte 2416 till byte 2419 but 'arr' ends at byte 240" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "read of 4 bytes from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-char-arr.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-char-arr.c
index 47fbc52..2bc707c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-char-arr.c
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-char-arr.c
@@ -1,55 +1,56 @@
-char arr[10]; /* { dg-message "capacity is 10 bytes" } */
+char arr[10]; /* { dg-message "capacity: 10 bytes" } */
-void int_arr_write_element_before_start_far(char x)
+void char_arr_write_element_before_start_far(char x)
{
- arr[-100] = x; /* { dg-warning "buffer underflow" "warning" } */
+ arr[-100] = x; /* { dg-warning "buffer underwrite" "warning" } */
/* { dg-message "out-of-bounds write at byte -100 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
}
-void int_arr_write_element_before_start_near(char x)
+void char_arr_write_element_before_start_near(char x)
{
- arr[-2] = x; /* { dg-warning "buffer underflow" "warning" } */
+ arr[-2] = x; /* { dg-warning "buffer underwrite" "warning" } */
/* { dg-message "out-of-bounds write at byte -2 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
}
-void int_arr_write_element_before_start_off_by_one(char x)
+void char_arr_write_element_before_start_off_by_one(char x)
{
- arr[-1] = x; /* { dg-warning "buffer underflow" "warning" } */
+ arr[-1] = x; /* { dg-warning "buffer underwrite" "warning" } */
/* { dg-message "out-of-bounds write at byte -1 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
}
-void int_arr_write_element_at_start(char x)
+void char_arr_write_element_at_start(char x)
{
arr[0] = x;
}
-void int_arr_write_element_at_end(char x)
+void char_arr_write_element_at_end(char x)
{
arr[9] = x;
}
-void int_arr_write_element_after_end_off_by_one(char x)
+void char_arr_write_element_after_end_off_by_one(char x)
{
arr[10] = x; /* { dg-warning "buffer overflow" "warning" } */
/* { dg-message "out-of-bounds write at byte 10 but 'arr' ends at byte 10" "final event" { target *-*-* } .-1 } */
- /* { dg-message "write is 1 bytes past the end of 'arr'" "note" { target *-*-* } .-2 } */
- // FIXME(PR 106626): "1 bytes"
+ /* { dg-message "write of 1 byte to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
-void int_arr_write_element_after_end_near(char x)
+void char_arr_write_element_after_end_near(char x)
{
arr[11] = x; /* { dg-warning "buffer overflow" "warning" } */
/* { dg-message "out-of-bounds write at byte 11 but 'arr' ends at byte 10" "final event" { target *-*-* } .-1 } */
- /* { dg-message "write is 1 bytes past the end of 'arr'" "note" { target *-*-* } .-2 } */
- // FIXME(PR 106626): is the note correct?
- // FIXME(PR 106626): "1 bytes"
+ /* { dg-message "write of 1 byte to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
-void int_arr_write_element_after_end_far(char x)
+void char_arr_write_element_after_end_far(char x)
{
arr[100] = x; /* { dg-warning "buffer overflow" "warning" } */
/* { dg-message "out-of-bounds write at byte 100 but 'arr' ends at byte 10" "final event" { target *-*-* } .-1 } */
- /* { dg-message "write is 1 bytes past the end of 'arr'" "note" { target *-*-* } .-2 } */
- // FIXME(PR 106626): the note seems incorrect (size of access is 1 byte, but magnitude beyond boundary is 90)
- // FIXME(PR 106626): "1 bytes"
+ /* { dg-message "write of 1 byte to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-int-arr.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-int-arr.c
index bf9760e..c6c0435 100644
--- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-int-arr.c
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-int-arr.c
@@ -1,23 +1,26 @@
#include <stdint.h>
-int32_t arr[10]; /* { dg-message "capacity is 40 bytes" } */
+int32_t arr[10]; /* { dg-message "capacity: 40 bytes" } */
void int_arr_write_element_before_start_far(int32_t x)
{
- arr[-100] = x; /* { dg-warning "buffer underflow" "warning" } */
+ arr[-100] = x; /* { dg-warning "buffer underwrite" "warning" } */
/* { dg-message "out-of-bounds write from byte -400 till byte -397 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
}
void int_arr_write_element_before_start_near(int32_t x)
{
- arr[-2] = x; /* { dg-warning "buffer underflow" "warning" } */
+ arr[-2] = x; /* { dg-warning "buffer underwrite" "warning" } */
/* { dg-message "out-of-bounds write from byte -8 till byte -5 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
}
void int_arr_write_element_before_start_off_by_one(int32_t x)
{
- arr[-1] = x; /* { dg-warning "buffer underflow" "warning" } */
+ arr[-1] = x; /* { dg-warning "buffer underwrite" "warning" } */
/* { dg-message "out-of-bounds write from byte -4 till byte -1 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
}
void int_arr_write_element_at_start(int32_t x)
@@ -34,21 +37,22 @@ void int_arr_write_element_after_end_off_by_one(int32_t x)
{
arr[10] = x; /* { dg-warning "buffer overflow" "warning" } */
/* { dg-message "out-of-bounds write from byte 40 till byte 43 but 'arr' ends at byte 40" "final event" { target *-*-* } .-1 } */
- /* { dg-message "write is 4 bytes past the end of 'arr'" "note" { target *-*-* } .-2 } */
+ /* { dg-message "write of 4 bytes to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
void int_arr_write_element_after_end_near(int32_t x)
{
arr[11] = x; /* { dg-warning "buffer overflow" "warning" } */
/* { dg-message "out-of-bounds write from byte 44 till byte 47 but 'arr' ends at byte 40" "final event" { target *-*-* } .-1 } */
- /* { dg-message "write is 4 bytes past the end of 'arr'" "note" { target *-*-* } .-2 } */
- // FIXME(PR 106626): is the note correct?
+ /* { dg-message "write of 4 bytes to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
void int_arr_write_element_after_end_far(int32_t x)
{
arr[100] = x; /* { dg-warning "buffer overflow" "warning" } */
/* { dg-message "out-of-bounds write from byte 400 till byte 403 but 'arr' ends at byte 40" "final event" { target *-*-* } .-1 } */
- /* { dg-message "write is 4 bytes past the end of 'arr'" "note" { target *-*-* } .-2 } */
- // FIXME(PR 106626): the note seems incorrect (size of access is 4 bytes, but magnitude beyond boundary is 390-393)
+ /* { dg-message "write of 4 bytes to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-struct-arr.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-struct-arr.c
new file mode 100644
index 0000000..cf6b458
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-struct-arr.c
@@ -0,0 +1,65 @@
+#include <stdint.h>
+
+struct st
+{
+ char buf[16];
+ int32_t x;
+ int32_t y;
+};
+
+struct st arr[10];
+
+void struct_arr_write_x_element_before_start_far(int32_t x)
+{
+ arr[-100].x = x; /* { dg-warning "buffer underwrite" "warning" } */
+ /* { dg-message "out-of-bounds write from byte -2384 till byte -2381 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
+}
+
+void struct_arr_write_x_element_before_start_near(int32_t x)
+{
+ arr[-2].x = x; /* { dg-warning "buffer underwrite" "warning" } */
+ /* { dg-message "out-of-bounds write from byte -32 till byte -29 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
+}
+
+void struct_arr_write_x_element_before_start_off_by_one(int32_t x)
+{
+ arr[-1].x = x; /* { dg-warning "buffer underwrite" "warning" } */
+ /* { dg-message "out-of-bounds write from byte -8 till byte -5 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */
+}
+
+void struct_arr_write_x_element_at_start(int32_t x)
+{
+ arr[0].x = x;
+}
+
+void struct_arr_write_x_element_at_end(int32_t x)
+{
+ arr[9].x = x;
+}
+
+void struct_arr_write_x_element_after_end_off_by_one(int32_t x)
+{
+ arr[10].x = x; /* { dg-warning "buffer overflow" "warning" } */
+ /* { dg-message "out-of-bounds write from byte 256 till byte 259 but 'arr' ends at byte 240" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "write of 4 bytes to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
+}
+
+void struct_arr_write_x_element_after_end_near(int32_t x)
+{
+ arr[11].x = x; /* { dg-warning "buffer overflow" "warning" } */
+ /* { dg-message "out-of-bounds write from byte 280 till byte 283 but 'arr' ends at byte 240" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "write of 4 bytes to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
+}
+
+void struct_arr_write_x_element_after_end_far(int32_t x)
+{
+ arr[100].x = x; /* { dg-warning "buffer overflow" "warning" } */
+ /* { dg-message "out-of-bounds write from byte 2416 till byte 2419 but 'arr' ends at byte 240" "final event" { target *-*-* } .-1 } */
+ /* { dg-message "write of 4 bytes to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */
+ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pipe-pr107486.c b/gcc/testsuite/gcc.dg/analyzer/pipe-pr107486.c
new file mode 100644
index 0000000..e9fc7fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pipe-pr107486.c
@@ -0,0 +1,5 @@
+void pipe(int);
+
+void f1(void) {
+ pipe(1);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pipe-void-return.c b/gcc/testsuite/gcc.dg/analyzer/pipe-void-return.c
new file mode 100644
index 0000000..0de6763
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pipe-void-return.c
@@ -0,0 +1,11 @@
+extern void pipe(int pipefd[2]);
+extern int close(int fd);
+
+void
+test_unchecked (void)
+{
+ int fds[2];
+ pipe (fds); /* { dg-message "when 'pipe' fails" } */
+ close (fds[0]); /* { dg-warning "use of uninitialized value 'fds\\\[0\\\]'" } */
+ close (fds[1]); /* { dg-warning "use of uninitialized value 'fds\\\[1\\\]'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101962.c b/gcc/testsuite/gcc.dg/analyzer/pr101962.c
index cf0041b..08c0aba 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr101962.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr101962.c
@@ -25,7 +25,7 @@ test_1 (void)
return *a; /* { dg-line test_1 } */
/* { dg-warning "use of uninitialized value '\\*a'" "warning" { target *-*-* } test_1 } */
- /* { dg-warning "overread" "warning" { target *-*-* } test_1 } */
+ /* { dg-warning "stack-based buffer over-read" "warning" { target *-*-* } test_1 } */
}
static const char * __attribute__((noinline))
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104308.c b/gcc/testsuite/gcc.dg/analyzer/pr104308.c
index a3a0cbb..e6a2c88 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr104308.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr104308.c
@@ -6,7 +6,7 @@
int test_memmove_within_uninit (void)
{
- char s[5]; /* { dg-message "region created on stack here" } */
+ char s[5]; /* { dg-message "region created on stack here" "" { xfail riscv*-*-* } } */
memmove(s, s + 1, 2); /* { dg-warning "use of uninitialized value" } */
return 0;
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104369-1.c b/gcc/testsuite/gcc.dg/analyzer/pr104369-1.c
index d3b3241..c05137b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr104369-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr104369-1.c
@@ -1,5 +1,5 @@
-/* { dg-additional-options "--param analyzer-max-enodes-per-program-point=10" } */
-// TODO: remove need for this option
+/* { dg-additional-options "-Wno-analyzer-too-complex -Wno-analyzer-fd-leak" } */
+// TODO: remove need for these options
typedef __SIZE_TYPE__ size_t;
#define NULL ((void *)0)
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104369-2.c b/gcc/testsuite/gcc.dg/analyzer/pr104369-2.c
index 57dc9ca..93d9987 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr104369-2.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr104369-2.c
@@ -1,3 +1,6 @@
+/* { dg-additional-options "-Wno-analyzer-fd-leak" } */
+// TODO: remove need for this option
+
typedef __SIZE_TYPE__ size_t;
#define NULL ((void *)0)
#define POLLIN 0x001
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr105365.c b/gcc/testsuite/gcc.dg/analyzer/pr105365.c
index aa576d0..c2e6b2e 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr105365.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr105365.c
@@ -13,5 +13,5 @@ foo(_Float32 k) {
f /= (_Complex char)__builtin_llround(g);
k /= (cf32)__builtin_copysignf(0, i);
bar(f + k);
- foo(0);
+ foo(0); /* { dg-warning "infinite recursion" } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr105366.c b/gcc/testsuite/gcc.dg/analyzer/pr105366.c
index 3dba870..af8a2c4 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr105366.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr105366.c
@@ -15,5 +15,5 @@ foo(u32 u, __int128 i) {
u /= (_Complex short)s;
u32 r = u + c;
bar(r);
- foo(0, 0);
+ foo(0, 0); /* { dg-warning "infinite recursion" } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr97029.c b/gcc/testsuite/gcc.dg/analyzer/pr97029.c
index e3b4531..2ab2d41 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr97029.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr97029.c
@@ -5,5 +5,5 @@ struct vj {
void
setjmp (struct vj pl)
{
- setjmp (pl);
+ setjmp (pl); /* { dg-warning "infinite recursion" } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-5.c b/gcc/testsuite/gcc.dg/analyzer/realloc-5.c
index 2efe337..75f0b70 100644
--- a/gcc/testsuite/gcc.dg/analyzer/realloc-5.c
+++ b/gcc/testsuite/gcc.dg/analyzer/realloc-5.c
@@ -37,7 +37,7 @@ void test_1 ()
__analyzer_eval (q[8] == 1); /* { dg-line eval } */
/* { dg-warning "UNKNOWN" "warning" { target *-*-* } eval } */
- /* { dg-warning "overread" "warning" { target *-*-* } eval } */
+ /* { dg-warning "heap-based buffer over-read" "warning" { target *-*-* } eval } */
/* { dg-warning "use of uninitialized value" "warning" { target *-*-* } eval } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/strchr-1.c b/gcc/testsuite/gcc.dg/analyzer/strchr-1.c
index dfe1bc9..bfa4891 100644
--- a/gcc/testsuite/gcc.dg/analyzer/strchr-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/strchr-1.c
@@ -3,12 +3,13 @@
const char* test_literal (int x)
{
- char *p = __builtin_strchr ("123", x);
+ char *p = __builtin_strchr ("123", x); /* { dg-message "when '__builtin_strchr' returns non-NULL" } */
if (p)
{
__analyzer_eval (*p == x); /* { dg-message "UNKNOWN" } */
/* TODO: this ought to be TRUE, but it's unclear that it's
worth stashing this constraint. */
+ *p = 'A'; /* { dg-warning "write to string literal" } */
}
return p;
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/string-ops-concat-pair.c b/gcc/testsuite/gcc.dg/analyzer/string-ops-concat-pair.c
new file mode 100644
index 0000000..f5bcd67
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/string-ops-concat-pair.c
@@ -0,0 +1,67 @@
+typedef __SIZE_TYPE__ size_t;
+#define NULL ((void *)0)
+
+/* Concatenating a pair of strings. */
+
+/* Correct but poor implementation with repeated __builtin_strlen calls. */
+
+char *
+alloc_dup_of_concatenated_pair_1_correct (const char *x, const char *y)
+{
+ size_t sz = __builtin_strlen (x) + __builtin_strlen (y) + 1;
+ char *result = __builtin_malloc (sz);
+ if (!result)
+ return NULL;
+ __builtin_memcpy (result, x, __builtin_strlen (x));
+ __builtin_memcpy (result + __builtin_strlen (x), y, __builtin_strlen (y));
+ result[__builtin_strlen(x) + __builtin_strlen (y)] = '\0';
+ return result;
+}
+
+/* Incorrect version: forgetting to add space for terminator. */
+
+char *
+alloc_dup_of_concatenated_pair_1_incorrect (const char *x, const char *y)
+{
+ /* Forgetting to add space for the terminator here. */
+ size_t sz = __builtin_strlen (x) + __builtin_strlen (y);
+ char *result = __builtin_malloc (sz);
+ if (!result)
+ return NULL;
+ __builtin_memcpy (result, x, __builtin_strlen (x));
+ __builtin_memcpy (result + __builtin_strlen (x), y, __builtin_strlen (y));
+ result[__builtin_strlen(x) + __builtin_strlen (y)] = '\0'; /* { dg-warning "heap-based buffer overflow" "PR analyzer/105899" { xfail *-*-* } } */
+ return result;
+}
+
+/* As above, but only calling __builtin_strlen once on each input. */
+
+char *
+alloc_dup_of_concatenated_pair_2_correct (const char *x, const char *y)
+{
+ size_t len_x = __builtin_strlen (x);
+ size_t len_y = __builtin_strlen (y);
+ size_t sz = len_x + len_y + 1;
+ char *result = __builtin_malloc (sz);
+ if (!result)
+ return NULL;
+ __builtin_memcpy (result, x, len_x);
+ __builtin_memcpy (result + len_x, y, len_y);
+ result[len_x + len_y] = '\0';
+ return result;
+}
+
+char *
+alloc_dup_of_concatenated_pair_2_incorrect (const char *x, const char *y)
+{
+ size_t len_x = __builtin_strlen (x);
+ size_t len_y = __builtin_strlen (y);
+ size_t sz = len_x + len_y; /* Forgetting to add space for the terminator. */
+ char *result = __builtin_malloc (sz); /* { dg-message "capacity: 'len_x \\+ len_y' bytes" } */
+ if (!result)
+ return NULL;
+ __builtin_memcpy (result, x, len_x);
+ __builtin_memcpy (result + len_x, y, len_y);
+ result[len_x + len_y] = '\0'; /* { dg-warning "heap-based buffer overflow" } */
+ return result;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c b/gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c
new file mode 100644
index 0000000..44c4e9d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c
@@ -0,0 +1,61 @@
+typedef __SIZE_TYPE__ size_t;
+#define NULL ((void *)0)
+
+/* Duplicating a string. */
+
+/* Correct but poor implementation with repeated __builtin_strlen calls. */
+
+char *
+alloc_dup_1_correct (const char *x)
+{
+ size_t sz = __builtin_strlen (x) + 1;
+ char *result = __builtin_malloc (sz);
+ if (!result)
+ return NULL;
+ __builtin_memcpy (result, x, __builtin_strlen (x));
+ result[__builtin_strlen(x)] = '\0';
+ return result;
+}
+
+/* Incorrect version: forgetting to add space for terminator. */
+
+char *
+alloc_dup_1_incorrect (const char *x, const char *y)
+{
+ /* Forgetting to add space for the terminator here. */
+ size_t sz = __builtin_strlen (x) + 1;
+ char *result = __builtin_malloc (sz);
+ if (!result)
+ return NULL;
+ __builtin_memcpy (result, x, __builtin_strlen (x));
+ result[__builtin_strlen(x)] = '\0'; /* { dg-warning "heap-based buffer overflow" "PR analyzer/105899" { xfail *-*-* } } */
+ return result;
+}
+
+/* As above, but only calling __builtin_strlen once. */
+
+char *
+alloc_dup_2_correct (const char *x)
+{
+ size_t len_x = __builtin_strlen (x);
+ size_t sz = len_x + 1;
+ char *result = __builtin_malloc (sz);
+ if (!result)
+ return NULL;
+ __builtin_memcpy (result, x, len_x);
+ result[len_x] = '\0';
+ return result;
+}
+
+char *
+alloc_dup_of_concatenated_pair_2_incorrect (const char *x, const char *y)
+{
+ size_t len_x = __builtin_strlen (x);
+ size_t sz = len_x; /* Forgetting to add space for the terminator. */
+ char *result = __builtin_malloc (sz); /* { dg-message "capacity: 'len_x' bytes" } */
+ if (!result)
+ return NULL;
+ __builtin_memcpy (result, x, len_x);
+ result[len_x] = '\0'; /* { dg-warning "heap-based buffer overflow" } */
+ return result;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/taint-assert-BUG_ON.c b/gcc/testsuite/gcc.dg/analyzer/taint-assert-BUG_ON.c
new file mode 100644
index 0000000..8aef0a4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/taint-assert-BUG_ON.c
@@ -0,0 +1,76 @@
+// TODO: remove need for this option
+/* { dg-additional-options "-fanalyzer-checker=taint" } */
+
+/* We need this, otherwise the warnings are emitted inside the macros, which
+ makes it hard to write the DejaGnu directives. */
+/* { dg-additional-options " -ftrack-macro-expansion=0" } */
+
+/* Adapted from code in the Linux kernel, which has this: */
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#define __noreturn __attribute__ ((__noreturn__))
+
+void panic(const char *fmt, ...) __noreturn;
+
+int _printk(const char *fmt, ...);
+#define __printk_index_emit(...) do {} while (0)
+#define printk_index_wrap(_p_func, _fmt, ...) \
+ ({ \
+ __printk_index_emit(_fmt, NULL, NULL); \
+ _p_func(_fmt, ##__VA_ARGS__); \
+ })
+#define printk(fmt, ...) printk_index_wrap(_printk, fmt, ##__VA_ARGS__)
+#define barrier_before_unreachable() do { } while (0)
+
+#define BUG() do { \
+ printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
+ barrier_before_unreachable(); \
+ panic("BUG!"); \
+} while (0)
+
+#define BUG_ON(condition) do { if (condition) BUG(); } while (0)
+
+void __attribute__((tainted_args))
+test_BUG(int n)
+{
+ if (n > 100) /* { dg-message "use of attacker-controlled value for control flow" } */
+ BUG(); /* { dg-warning "-Wanalyzer-tainted-assertion" "warning" } */
+ /* { dg-message "treating 'panic' as an assertion failure handler due to '__attribute__\\(\\(__noreturn__\\)\\)'" "final event" { target *-*-* } .-1 } */
+}
+
+void __attribute__((tainted_args))
+test_BUG_ON(int n)
+{
+ BUG_ON(n > 100); /* { dg-warning "-Wanalyzer-tainted-assertion" "warning" } */
+ /* { dg-message "treating 'panic' as an assertion failure handler due to '__attribute__\\(\\(__noreturn__\\)\\)'" "final event" { target *-*-* } .-1 } */
+}
+
+int __attribute__((tainted_args))
+test_switch_BUG_1(int n)
+{
+ switch (n) { /* { dg-message "use of attacker-controlled value for control flow" } */
+ default:
+ case 0:
+ return 5;
+ case 1:
+ return 22;
+ case 2:
+ return -1;
+ case 42:
+ BUG (); /* { dg-warning "-Wanalyzer-tainted-assertion" } */
+ }
+}
+
+int __attribute__((tainted_args))
+test_switch_BUG(int n)
+{
+ switch (n) { /* { dg-message "use of attacker-controlled value for control flow" } */
+ case 0:
+ return 5;
+ case 1:
+ return 22;
+ case 2:
+ return -1;
+ }
+ BUG (); /* { dg-warning "-Wanalyzer-tainted-assertion" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/taint-assert-macro-expansion.c b/gcc/testsuite/gcc.dg/analyzer/taint-assert-macro-expansion.c
new file mode 100644
index 0000000..24b175a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/taint-assert-macro-expansion.c
@@ -0,0 +1,96 @@
+/* Integration test of how the execution path looks for
+ -Wanalyzer-tainted-assertion with macro-tracking enabled
+ (the default). */
+
+// TODO: remove need for this option
+/* { dg-additional-options "-fanalyzer-checker=taint" } */
+
+/* { dg-additional-options "-fdiagnostics-show-path-depths" } */
+/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
+
+/* An assertion macro that has a call to a __noreturn__ function. */
+
+extern void my_assert_fail (const char *expr, const char *file, int line)
+ __attribute__ ((__noreturn__));
+
+#define MY_ASSERT_1(EXPR) \
+ do { if (!(EXPR)) my_assert_fail (#EXPR, __FILE__, __LINE__); } while (0) /* { dg-warning "use of attacked-controlled value in condition for assertion \\\[CWE-617\\\] \\\[-Wanalyzer-tainted-assertion\\\]" } */
+
+int __attribute__((tainted_args))
+test_tainted_MY_ASSERT_1 (int n)
+{
+ MY_ASSERT_1 (n > 0);
+ return n * n;
+}
+
+/* { dg-begin-multiline-output "" }
+ do { if (!(EXPR)) my_assert_fail (#EXPR, __FILE__, __LINE__); } while (0)
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ { dg-end-multiline-output "" } */
+// note: in expansion of macro 'MY_ASSERT_1'
+/* { dg-begin-multiline-output "" }
+ MY_ASSERT_1 (n > 0);
+ ^~~~~~~~~~~
+ 'test_tainted_MY_ASSERT_1': event 1 (depth 0)
+ |
+ | test_tainted_MY_ASSERT_1 (int n)
+ | ^~~~~~~~~~~~~~~~~~~~~~~~
+ | |
+ | (1) function 'test_tainted_MY_ASSERT_1' marked with '__attribute__((tainted_args))'
+ |
+ +--> 'test_tainted_MY_ASSERT_1': event 2 (depth 1)
+ |
+ | test_tainted_MY_ASSERT_1 (int n)
+ | ^~~~~~~~~~~~~~~~~~~~~~~~
+ | |
+ | (2) entry to 'test_tainted_MY_ASSERT_1'
+ |
+ 'test_tainted_MY_ASSERT_1': event 3 (depth 1)
+ |
+ | do { if (!(EXPR)) my_assert_fail (#EXPR, __FILE__, __LINE__); } while (0)
+ | ^
+ | |
+ | (3) use of attacker-controlled value for control flow
+ { dg-end-multiline-output "" } */
+// note: in expansion of macro 'MY_ASSERT_1'
+/* { dg-begin-multiline-output "" }
+ | MY_ASSERT_1 (n > 0);
+ | ^~~~~~~~~~~
+ |
+ 'test_tainted_MY_ASSERT_1': event 4 (depth 1)
+ |
+ | do { if (!(EXPR)) my_assert_fail (#EXPR, __FILE__, __LINE__); } while (0)
+ | ^
+ | |
+ | (4) following 'true' branch (when 'n <= 0')...
+ { dg-end-multiline-output "" } */
+// note: in expansion of macro 'MY_ASSERT_1'
+/* { dg-begin-multiline-output "" }
+ | MY_ASSERT_1 (n > 0);
+ | ^~~~~~~~~~~
+ |
+ 'test_tainted_MY_ASSERT_1': event 5 (depth 1)
+ |
+ | do { if (!(EXPR)) my_assert_fail (#EXPR, __FILE__, __LINE__); } while (0)
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | |
+ | (5) ...to here
+ { dg-end-multiline-output "" } */
+// note: in expansion of macro 'MY_ASSERT_1'
+/* { dg-begin-multiline-output "" }
+ | MY_ASSERT_1 (n > 0);
+ | ^~~~~~~~~~~
+ |
+ 'test_tainted_MY_ASSERT_1': event 6 (depth 1)
+ |
+ | do { if (!(EXPR)) my_assert_fail (#EXPR, __FILE__, __LINE__); } while (0)
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | |
+ | (6) treating 'my_assert_fail' as an assertion failure handler due to '__attribute__((__noreturn__))'
+ { dg-end-multiline-output "" } */
+// note: in expansion of macro 'MY_ASSERT_1'
+/* { dg-begin-multiline-output "" }
+ | MY_ASSERT_1 (n > 0);
+ | ^~~~~~~~~~~
+ |
+ { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/taint-assert-system-header.c b/gcc/testsuite/gcc.dg/analyzer/taint-assert-system-header.c
new file mode 100644
index 0000000..a65853c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/taint-assert-system-header.c
@@ -0,0 +1,52 @@
+/* Integration test of how the execution path looks for
+ -Wanalyzer-tainted-assertion with macro-tracking enabled
+ (the default), where the assertion macro is defined in
+ a system header. */
+
+// TODO: remove need for this option
+/* { dg-additional-options "-fanalyzer-checker=taint" } */
+
+/* { dg-additional-options "-fdiagnostics-show-path-depths" } */
+/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
+
+/* An assertion macro that has a call to a __noreturn__ function. */
+
+/* This is marked as a system header. */
+#include "test-assert.h"
+
+int __attribute__((tainted_args))
+test_tainted_assert (int n)
+{
+ assert (n > 0); /* { dg-warning "use of attacked-controlled value in condition for assertion \\\[CWE-617\\\] \\\[-Wanalyzer-tainted-assertion\\\]" } */
+ return n * n;
+}
+
+/* { dg-begin-multiline-output "" }
+ assert (n > 0);
+ ^~~~~~
+ 'test_tainted_assert': event 1 (depth 0)
+ |
+ | test_tainted_assert (int n)
+ | ^~~~~~~~~~~~~~~~~~~
+ | |
+ | (1) function 'test_tainted_assert' marked with '__attribute__((tainted_args))'
+ |
+ +--> 'test_tainted_assert': event 2 (depth 1)
+ |
+ | test_tainted_assert (int n)
+ | ^~~~~~~~~~~~~~~~~~~
+ | |
+ | (2) entry to 'test_tainted_assert'
+ |
+ 'test_tainted_assert': events 3-6 (depth 1)
+ |
+ |
+ | do { if (!(EXPR)) __assert_fail (#EXPR, __FILE__, __LINE__); } while (0)
+ | ^ ~~~~~~~~~~~~~
+ | | |
+ | | (5) ...to here
+ | | (6) treating '__assert_fail' as an assertion failure handler due to '__attribute__((__noreturn__))'
+ | (3) use of attacker-controlled value for control flow
+ | (4) following 'true' branch (when 'n <= 0')...
+ |
+ { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/taint-assert.c b/gcc/testsuite/gcc.dg/analyzer/taint-assert.c
new file mode 100644
index 0000000..b09f8c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/taint-assert.c
@@ -0,0 +1,346 @@
+// TODO: remove need for this option
+/* { dg-additional-options "-fanalyzer-checker=taint" } */
+
+/* We need this, otherwise the warnings are emitted inside the macros, which
+ makes it hard to write the DejaGnu directives. */
+/* { dg-additional-options " -ftrack-macro-expansion=0" } */
+
+#include "analyzer-decls.h"
+
+/* An assertion macro that has a call to a __noreturn__ function. */
+
+extern void my_assert_fail (const char *expr, const char *file, int line)
+ __attribute__ ((__noreturn__));
+
+#define MY_ASSERT_1(EXPR) \
+ do { if (!(EXPR)) my_assert_fail (#EXPR, __FILE__, __LINE__); } while (0)
+
+int
+test_not_tainted_MY_ASSERT_1 (int n)
+{
+ MY_ASSERT_1 (n > 0); /* { dg-bogus "-Wanalyzer-tainted-assertion" } */
+ return n * n;
+}
+
+int __attribute__((tainted_args))
+test_tainted_MY_ASSERT_1 (int n)
+{
+ MY_ASSERT_1 (n > 0); /* { dg-warning "use of attacked-controlled value in condition for assertion \\\[CWE-617\\\] \\\[-Wanalyzer-tainted-assertion\\\]" "warning" } */
+ /* { dg-message "treating 'my_assert_fail' as an assertion failure handler due to '__attribute__\\(\\(__noreturn__\\)\\)'" "final event" { target *-*-* } .-1 } */
+ return n * n;
+}
+
+
+/* An assertion macro that has a call to __builtin_unreachable. */
+
+#define MY_ASSERT_2(EXPR) \
+ do { if (!(EXPR)) __builtin_unreachable (); } while (0)
+
+int
+test_not_tainted_MY_ASSERT_2 (int n)
+{
+ MY_ASSERT_2 (n > 0); /* { dg-bogus "-Wanalyzer-tainted-assertion" } */
+ return n * n;
+}
+
+int __attribute__((tainted_args))
+test_tainted_MY_ASSERT_2 (int n)
+{
+ MY_ASSERT_2 (n > 0); /* { dg-warning "-Wanalyzer-tainted-assertion" "warning" } */
+ /* { dg-message "treating '__builtin_unreachable' as an assertion failure handler" "final event" { target *-*-* } .-1 } */
+ return n * n;
+}
+
+
+/* An assertion macro that's preprocessed away.
+ The analyzer doesn't see this, so can't warn. */
+
+#define MY_ASSERT_3(EXPR) do { } while (0)
+
+int
+test_not_tainted_MY_ASSERT_3 (int n)
+{
+ MY_ASSERT_3 (n > 0); /* { dg-bogus "-Wanalyzer-tainted-assertion" } */
+ return n * n;
+}
+
+int __attribute__((tainted_args))
+test_tainted_MY_ASSERT_3 (int n)
+{
+ MY_ASSERT_3 (n > 0); /* { dg-bogus "-Wanalyzer-tainted-assertion" } */
+ return n * n;
+}
+
+
+/* A macro that isn't an assertion. */
+
+extern void do_something_benign ();
+
+#define NOT_AN_ASSERT(EXPR) \
+ do { if (!(EXPR)) do_something_benign (); } while (0)
+
+int
+test_not_tainted_NOT_AN_ASSERT (int n)
+{
+ NOT_AN_ASSERT (n > 0); /* { dg-bogus "-Wanalyzer-tainted-assertion" } */
+ return n * n;
+}
+
+int __attribute__((tainted_args))
+test_tainted_NOT_AN_ASSERT (int n)
+{
+ NOT_AN_ASSERT (n > 0); /* { dg-bogus "-Wanalyzer-tainted-assertion" } */
+ return n * n;
+}
+
+
+/* A condition that isn't an assertion. */
+
+int __attribute__((tainted_args))
+test_tainted_condition (int n)
+{
+ if (n > 0) /* { dg-bogus "-Wanalyzer-tainted-assertion" } */
+ return 1;
+ else
+ return -1;
+}
+
+
+/* More complicated expressions in assertions. */
+
+int g;
+
+void __attribute__((tainted_args))
+test_compound_condition_in_assert_1 (int n)
+{
+ MY_ASSERT_1 ((n * 2) < (g + 3)); /* { dg-warning "-Wanalyzer-tainted-assertion" } */
+}
+
+void __attribute__((tainted_args))
+test_compound_condition_in_assert_2 (int x, int y)
+{
+ MY_ASSERT_1 (x < 100 && y < 100); /* { dg-warning "-Wanalyzer-tainted-assertion" } */
+}
+
+void __attribute__((tainted_args))
+test_compound_condition_in_assert_3 (int x, int y)
+{
+ MY_ASSERT_1 (x < 100 || y < 100); /* { dg-warning "-Wanalyzer-tainted-assertion" } */
+}
+
+void __attribute__((tainted_args))
+test_sanitized_expression_in_assert (int n)
+{
+ __analyzer_dump_state ("taint", n); /* { dg-warning "state: 'tainted'" } */
+ if (n < 0 || n >= 100)
+ return;
+ __analyzer_dump_state ("taint", n); /* { dg-warning "state: 'stop'" } */
+ MY_ASSERT_1 (n < 200); /* { dg-bogus "-Wanalyzer-tainted-assertion" } */
+}
+
+void __attribute__((tainted_args))
+test_sanitization_then_ok_assertion (unsigned n)
+{
+ if (n >= 100)
+ return;
+
+ /* Shouldn't warn here, as g isn't attacker-controlled. */
+ MY_ASSERT_1 (g > 42); /* { dg-bogus "-Wanalyzer-tainted-assertion" } */
+}
+
+void __attribute__((tainted_args))
+test_good_assert_then_bad_assert (unsigned n)
+{
+ /* Shouldn't warn here, as g isn't attacker-controlled. */
+ MY_ASSERT_1 (g > 42); /* { dg-bogus "-Wanalyzer-tainted-assertion" } */
+
+ /* ...but n is: */
+ MY_ASSERT_1 (n < 100); /* { dg-warning "-Wanalyzer-tainted-assertion" } */
+}
+
+void __attribute__((tainted_args))
+test_bad_assert_then_good_assert (unsigned n)
+{
+ MY_ASSERT_1 (n < 100); /* { dg-warning "-Wanalyzer-tainted-assertion" } */
+ MY_ASSERT_1 (g > 42); /* { dg-bogus "-Wanalyzer-tainted-assertion" } */
+}
+
+
+/* */
+
+void __attribute__((tainted_args))
+test_zero_MY_ASSERT_1 (unsigned n)
+{
+ if (n >= 100)
+ MY_ASSERT_1 (0); /* { dg-warning "-Wanalyzer-tainted-assertion" } */
+}
+
+void __attribute__((tainted_args))
+test_nonzero_MY_ASSERT_1 (unsigned n)
+{
+ if (n >= 100)
+ MY_ASSERT_1 (1); /* { dg-bogus "-Wanalyzer-tainted-assertion" } */
+}
+
+void __attribute__((tainted_args))
+test_zero_MY_ASSERT_2 (unsigned n)
+{
+ if (n >= 100)
+ MY_ASSERT_2 (0); /* { dg-warning "-Wanalyzer-tainted-assertion" } */
+}
+
+void __attribute__((tainted_args))
+test_nonzero_MY_ASSERT_2 (unsigned n)
+{
+ if (n >= 100)
+ MY_ASSERT_2 (1); /* { dg-bogus "-Wanalyzer-tainted-assertion" } */
+}
+
+
+/* Assertions that call a subroutine to do validity checking. */
+
+static int
+__analyzer_valid_1 (int x)
+{
+ return x < 100;
+}
+
+void __attribute__((tainted_args))
+test_assert_calling_valid_1 (int n)
+{
+ MY_ASSERT_1 (__analyzer_valid_1 (n)); /* { dg-warning "-Wanalyzer-tainted-assertion" } */
+}
+
+static int
+__analyzer_valid_2 (int x)
+{
+ return x < 100;
+}
+
+void __attribute__((tainted_args))
+test_assert_calling_valid_2 (int n)
+{
+ MY_ASSERT_1 (__analyzer_valid_2 (n)); /* { dg-warning "-Wanalyzer-tainted-assertion" } */
+}
+
+static int
+__analyzer_valid_3 (int x, int y)
+{
+ if (x >= 100)
+ return 0;
+ if (y >= 100)
+ return 0;
+ return 1;
+}
+
+void __attribute__((tainted_args))
+test_assert_calling_valid_3 (int a, int b)
+{
+ MY_ASSERT_1 (__analyzer_valid_3 (a, b)); /* { dg-warning "-Wanalyzer-tainted-assertion" "TODO" { xfail *-*-* } } */
+}
+
+
+/* 'switch' statements with supposedly unreachable cases/defaults. */
+
+int __attribute__((tainted_args))
+test_switch_default (int n)
+{
+ switch (n) /* { dg-message "use of attacker-controlled value for control flow" "why" } */
+ /* { dg-message "following 'default:' branch" "dest" { target *-*-* } .-1 } */
+ {
+ case 0:
+ return 5;
+ case 1:
+ return 22;
+ case 2:
+ return -1;
+ default:
+ /* The wording is rather inaccurate here. */
+ __builtin_unreachable (); /* { dg-warning "use of attacked-controlled value in condition for assertion" } */
+ }
+}
+
+int __attribute__((tainted_args))
+test_switch_unhandled_case (int n)
+{
+ switch (n) /* { dg-message "use of attacker-controlled value for control flow" "why" } */
+ /* { dg-message "following 'default:' branch" "dest" { target *-*-* } .-1 } */
+ {
+ case 0:
+ return 5;
+ case 1:
+ return 22;
+ case 2:
+ return -1;
+ }
+
+ /* The wording is rather inaccurate here. */
+ __builtin_unreachable (); /* { dg-warning "use of attacked-controlled value in condition for assertion" } */
+}
+
+int __attribute__((tainted_args))
+test_switch_bogus_case_MY_ASSERT_1 (int n)
+{
+ switch (n)
+ {
+ default:
+ case 0:
+ return 5;
+ case 1:
+ return 22;
+ case 2:
+ return -1;
+ case 42:
+ MY_ASSERT_1 (0); /* { dg-warning "-Wanalyzer-tainted-assertion" } */
+ }
+}
+
+int __attribute__((tainted_args))
+test_switch_bogus_case_MY_ASSERT_2 (int n)
+{
+ switch (n)
+ {
+ default:
+ case 0:
+ return 5;
+ case 1:
+ return 22;
+ case 2:
+ return -1;
+ case 42:
+ MY_ASSERT_2 (0); /* { dg-warning "-Wanalyzer-tainted-assertion" } */
+ }
+}
+
+int __attribute__((tainted_args))
+test_switch_bogus_case_unreachable (int n)
+{
+ switch (n)
+ {
+ default:
+ case 0:
+ return 5;
+ case 1:
+ return 22;
+ case 2:
+ return -1;
+ case 42:
+ /* This case gets optimized away before we see it. */
+ __builtin_unreachable ();
+ }
+}
+
+
+/* Contents of a struct. */
+
+struct s
+{
+ int x;
+ int y;
+};
+
+int __attribute__((tainted_args))
+test_assert_struct (struct s *p)
+{
+ MY_ASSERT_1 (p->x < p->y); /* { dg-warning "-Wanalyzer-tainted-assertion" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/test-assert.h b/gcc/testsuite/gcc.dg/analyzer/test-assert.h
new file mode 100644
index 0000000..4a24b72
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/test-assert.h
@@ -0,0 +1,7 @@
+#pragma GCC system_header
+
+extern void __assert_fail (const char *expr, const char *file, int line)
+ __attribute__ ((__noreturn__));
+
+#define assert(EXPR) \
+ do { if (!(EXPR)) __assert_fail (#EXPR, __FILE__, __LINE__); } while (0)
diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/fold-ptr-arith-pr105784.c b/gcc/testsuite/gcc.dg/analyzer/torture/fold-ptr-arith-pr105784.c
new file mode 100644
index 0000000..5e5a2bf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/torture/fold-ptr-arith-pr105784.c
@@ -0,0 +1,43 @@
+/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */
+
+#include "../analyzer-decls.h"
+
+extern _Bool quit_flag;
+extern void char_charset (int);
+
+static void
+__analyzer_ccl_driver (int *source, int src_size)
+{
+ int *src = source, *src_end = src + src_size;
+ int i = 0;
+
+ while (!quit_flag)
+ {
+ if (src < src_end)
+ {
+ __analyzer_dump_path (); /* { dg-message "path" } */
+ i = *src++; /* { dg-bogus "uninit" } */
+ }
+ char_charset (i);
+ }
+}
+
+void
+Fccl_execute_on_string (char *str, long str_bytes)
+{
+ while (1)
+ {
+ char *p = str;
+ char *endp = str + str_bytes;
+ int source[1024];
+ int src_size = 0;
+
+ while (src_size < 1024 && p < endp)
+ {
+ __analyzer_dump_path (); /* { dg-message "path" } */
+ source[src_size++] = *p++;
+ }
+
+ __analyzer_ccl_driver (source, src_size);
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/zlib-3.c b/gcc/testsuite/gcc.dg/analyzer/zlib-3.c
index b05b862..def8300 100644
--- a/gcc/testsuite/gcc.dg/analyzer/zlib-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/zlib-3.c
@@ -184,7 +184,7 @@ static int huft_build(uInt *b, uInt n, uInt s, const uInt *d, const uInt *e,
mask = (1 << w) - 1;
/* The analyzer thinks that h can be -1 here.
This is probably a false positive. */
- while ((i & mask) != x[h]) { /* { dg-bogus "underread" "" { xfail *-*-* } } */
+ while ((i & mask) != x[h]) { /* { dg-bogus "under-read" "" { xfail *-*-* } } */
h--;
w -= l;
mask = (1 << w) - 1;
diff --git a/gcc/testsuite/gcc.dg/asan/pr107317.c b/gcc/testsuite/gcc.dg/asan/pr107317.c
new file mode 100644
index 0000000..dd7ad7d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/pr107317.c
@@ -0,0 +1,13 @@
+/* PR middle-end/107317 */
+/* { dg-do compile { target ilp32 } } */
+/* { dg-options "-fsanitize=address -ffat-lto-objects" } */
+
+void bar (float *, float *);
+
+void
+foo (void) /* { dg-error "exceeds maximum" } */
+{
+ float a[400000000];
+ float b[200000000];
+ bar (a, b);
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
index 01a280b..f9047a0 100644
--- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
@@ -479,6 +479,52 @@ test_loop (int *obj, size_t sz, size_t start, size_t end, int incr)
return __builtin_dynamic_object_size (ptr, 0);
}
+/* strdup/strndup. */
+
+size_t
+__attribute__ ((noinline))
+test_strdup (const char *in)
+{
+ char *res = __builtin_strdup (in);
+ size_t sz = __builtin_dynamic_object_size (res, 0);
+
+ __builtin_free (res);
+ return sz;
+}
+
+size_t
+__attribute__ ((noinline))
+test_strndup (const char *in, size_t bound)
+{
+ char *res = __builtin_strndup (in, bound);
+ size_t sz = __builtin_dynamic_object_size (res, 0);
+
+ __builtin_free (res);
+ return sz;
+}
+
+size_t
+__attribute__ ((noinline))
+test_strdup_min (const char *in)
+{
+ char *res = __builtin_strdup (in);
+ size_t sz = __builtin_dynamic_object_size (res, 2);
+
+ __builtin_free (res);
+ return sz;
+}
+
+size_t
+__attribute__ ((noinline))
+test_strndup_min (const char *in, size_t bound)
+{
+ char *res = __builtin_strndup (in, bound);
+ size_t sz = __builtin_dynamic_object_size (res, 2);
+
+ __builtin_free (res);
+ return sz;
+}
+
/* Other tests. */
struct TV4
@@ -651,6 +697,15 @@ main (int argc, char **argv)
int *t = test_pr105736 (&val3);
if (__builtin_dynamic_object_size (t, 0) != -1)
FAIL ();
+ const char *str = "hello world";
+ if (test_strdup (str) != __builtin_strlen (str) + 1)
+ FAIL ();
+ if (test_strndup (str, 4) != 5)
+ FAIL ();
+ if (test_strdup_min (str) != __builtin_strlen (str) + 1)
+ FAIL ();
+ if (test_strndup_min (str, 4) != 1)
+ FAIL ();
if (nfails > 0)
__builtin_abort ();
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c
index 7cc8b1c..8f17c8e 100644
--- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-stringop-overread" } */
/* { dg-require-effective-target alloca } */
#define __builtin_object_size __builtin_dynamic_object_size
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c
index 267dbf4..3677782 100644
--- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-stringop-overread" } */
/* { dg-require-effective-target alloca } */
#define __builtin_object_size __builtin_dynamic_object_size
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c
index fb9dc56..5b6987b 100644
--- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-stringop-overread" } */
/* { dg-require-effective-target alloca } */
#define __builtin_object_size __builtin_dynamic_object_size
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c
index 870548b..9d79622 100644
--- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-stringop-overread" } */
/* { dg-require-effective-target alloca } */
#define __builtin_object_size __builtin_dynamic_object_size
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-1.c b/gcc/testsuite/gcc.dg/builtin-object-size-1.c
index b772e2d..c6e5b4c 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-1.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-1.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-stringop-overread" } */
/* { dg-require-effective-target alloca } */
typedef __SIZE_TYPE__ size_t;
@@ -7,10 +7,13 @@ extern void abort (void);
extern void exit (int);
extern void *malloc (size_t);
extern void *calloc (size_t, size_t);
+extern void free (void *);
extern void *alloca (size_t);
extern void *memcpy (void *, const void *, size_t);
extern void *memset (void *, int, size_t);
extern char *strcpy (char *, const char *);
+extern char *strdup (const char *);
+extern char *strndup (const char *, size_t);
struct A
{
@@ -629,6 +632,94 @@ test10 (void)
}
}
+/* Tests for strdup/strndup. */
+size_t
+__attribute__ ((noinline))
+test11 (void)
+{
+ int i = 0;
+ const char *ptr = "abcdefghijklmnopqrstuvwxyz";
+ char *res = strndup (ptr, 21);
+ if (__builtin_object_size (res, 0) != 22)
+ abort ();
+
+ free (res);
+
+ res = strndup (ptr, 32);
+ if (__builtin_object_size (res, 0) != 27)
+ abort ();
+
+ free (res);
+
+ res = strdup (ptr);
+ if (__builtin_object_size (res, 0) != 27)
+ abort ();
+
+ free (res);
+
+ char *ptr2 = malloc (64);
+ strcpy (ptr2, ptr);
+
+ res = strndup (ptr2, 21);
+ if (__builtin_object_size (res, 0) != 22)
+ abort ();
+
+ free (res);
+
+ res = strndup (ptr2, 32);
+ if (__builtin_object_size (res, 0) != 33)
+ abort ();
+
+ free (res);
+
+ res = strndup (ptr2, 128);
+ if (__builtin_object_size (res, 0) != 64)
+ abort ();
+
+ free (res);
+
+ res = strdup (ptr2);
+#ifdef __builtin_object_size
+ if (__builtin_object_size (res, 0) != 27)
+#else
+ if (__builtin_object_size (res, 0) != (size_t) -1)
+#endif
+ abort ();
+ free (res);
+ free (ptr2);
+
+ ptr = "abcd\0efghijklmnopqrstuvwxyz";
+ res = strdup (ptr);
+ if (__builtin_object_size (res, 0) != 5)
+ abort ();
+ free (res);
+
+ res = strndup (ptr, 24);
+ if (__builtin_object_size (res, 0) != 5)
+ abort ();
+ free (res);
+
+ res = strndup (ptr, 2);
+ if (__builtin_object_size (res, 0) != 3)
+ abort ();
+ free (res);
+
+ res = strdup (&ptr[4]);
+ if (__builtin_object_size (res, 0) != 1)
+ abort ();
+ free (res);
+
+ res = strndup (&ptr[4], 4);
+ if (__builtin_object_size (res, 0) != 1)
+ abort ();
+ free (res);
+
+ res = strndup (&ptr[4], 1);
+ if (__builtin_object_size (res, 0) != 1)
+ abort ();
+ free (res);
+}
+
int
main (void)
{
@@ -644,5 +735,6 @@ main (void)
test8 ();
test9 (1);
test10 ();
+ test11 ();
exit (0);
}
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-2.c b/gcc/testsuite/gcc.dg/builtin-object-size-2.c
index 2729538..639a83c 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-2.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-2.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-stringop-overread" } */
/* { dg-require-effective-target alloca } */
typedef __SIZE_TYPE__ size_t;
@@ -7,10 +7,13 @@ extern void abort (void);
extern void exit (int);
extern void *malloc (size_t);
extern void *calloc (size_t, size_t);
+extern void free (void *);
extern void *alloca (size_t);
extern void *memcpy (void *, const void *, size_t);
extern void *memset (void *, int, size_t);
extern char *strcpy (char *, const char *);
+extern char *strdup (const char *);
+extern char *strndup (const char *, size_t);
struct A
{
@@ -544,6 +547,94 @@ test8 (unsigned cond)
#endif
}
+/* Tests for strdup/strndup. */
+size_t
+__attribute__ ((noinline))
+test9 (void)
+{
+ const char *ptr = "abcdefghijklmnopqrstuvwxyz";
+ char *res = strndup (ptr, 21);
+ if (__builtin_object_size (res, 1) != 22)
+ abort ();
+
+ free (res);
+
+ res = strndup (ptr, 32);
+ if (__builtin_object_size (res, 1) != 27)
+ abort ();
+
+ free (res);
+
+ res = strdup (ptr);
+ if (__builtin_object_size (res, 1) != 27)
+ abort ();
+
+ free (res);
+
+ char *ptr2 = malloc (64);
+ strcpy (ptr2, ptr);
+
+ res = strndup (ptr2, 21);
+ if (__builtin_object_size (res, 1) != 22)
+ abort ();
+
+ free (res);
+
+ res = strndup (ptr2, 32);
+ if (__builtin_object_size (res, 1) != 33)
+ abort ();
+
+ free (res);
+
+ res = strndup (ptr2, 128);
+ if (__builtin_object_size (res, 1) != 64)
+ abort ();
+
+ free (res);
+
+ res = strdup (ptr2);
+#ifdef __builtin_object_size
+ if (__builtin_object_size (res, 1) != 27)
+#else
+ if (__builtin_object_size (res, 1) != (size_t) -1)
+#endif
+ abort ();
+
+ free (res);
+ free (ptr2);
+
+ ptr = "abcd\0efghijklmnopqrstuvwxyz";
+ res = strdup (ptr);
+ if (__builtin_object_size (res, 1) != 5)
+ abort ();
+ free (res);
+
+ res = strndup (ptr, 24);
+ if (__builtin_object_size (res, 1) != 5)
+ abort ();
+ free (res);
+
+ res = strndup (ptr, 2);
+ if (__builtin_object_size (res, 1) != 3)
+ abort ();
+ free (res);
+
+ res = strdup (&ptr[4]);
+ if (__builtin_object_size (res, 1) != 1)
+ abort ();
+ free (res);
+
+ res = strndup (&ptr[4], 4);
+ if (__builtin_object_size (res, 1) != 1)
+ abort ();
+ free (res);
+
+ res = strndup (&ptr[4], 1);
+ if (__builtin_object_size (res, 1) != 1)
+ abort ();
+ free (res);
+}
+
int
main (void)
{
@@ -557,5 +648,6 @@ main (void)
test6 ();
test7 ();
test8 (1);
+ test9 ();
exit (0);
}
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-3.c b/gcc/testsuite/gcc.dg/builtin-object-size-3.c
index 44a9918..ff4f174 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-3.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-3.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-stringop-overread" } */
/* { dg-require-effective-target alloca } */
typedef __SIZE_TYPE__ size_t;
@@ -7,10 +7,13 @@ extern void abort (void);
extern void exit (int);
extern void *malloc (size_t);
extern void *calloc (size_t, size_t);
+extern void free (void *);
extern void *alloca (size_t);
extern void *memcpy (void *, const void *, size_t);
extern void *memset (void *, int, size_t);
extern char *strcpy (char *, const char *);
+extern char *strdup (const char *);
+extern char *strndup (const char *, size_t);
struct A
{
@@ -636,6 +639,95 @@ test10 (void)
}
}
+/* Tests for strdup/strndup. */
+size_t
+__attribute__ ((noinline))
+test11 (void)
+{
+ const char *ptr = "abcdefghijklmnopqrstuvwxyz";
+ char *res = strndup (ptr, 21);
+ if (__builtin_object_size (res, 2) != 22)
+ abort ();
+
+ free (res);
+
+ res = strndup (ptr, 32);
+ if (__builtin_object_size (res, 2) != 27)
+ abort ();
+
+ free (res);
+
+ res = strdup (ptr);
+ if (__builtin_object_size (res, 2) != 27)
+ abort ();
+
+ free (res);
+
+ char *ptr2 = malloc (64);
+ strcpy (ptr2, ptr);
+
+ res = strndup (ptr2, 21);
+ if (__builtin_object_size (res, 2) != 1)
+ abort ();
+
+ free (res);
+
+ res = strndup (ptr2, 32);
+ if (__builtin_object_size (res, 2) != 1)
+ abort ();
+
+ free (res);
+
+ res = strndup (ptr2, 128);
+ if (__builtin_object_size (res, 2) != 1)
+ abort ();
+
+ free (res);
+
+ res = strdup (ptr2);
+
+#ifdef __builtin_object_size
+ if (__builtin_object_size (res, 2) != 27)
+#else
+ if (__builtin_object_size (res, 2) != 1)
+#endif
+ abort ();
+
+ free (res);
+ free (ptr2);
+
+ ptr = "abcd\0efghijklmnopqrstuvwxyz";
+ res = strdup (ptr);
+ if (__builtin_object_size (res, 2) != 5)
+ abort ();
+ free (res);
+
+ res = strndup (ptr, 24);
+ if (__builtin_object_size (res, 2) != 5)
+ abort ();
+ free (res);
+
+ res = strndup (ptr, 2);
+ if (__builtin_object_size (res, 2) != 3)
+ abort ();
+ free (res);
+
+ res = strdup (&ptr[4]);
+ if (__builtin_object_size (res, 2) != 1)
+ abort ();
+ free (res);
+
+ res = strndup (&ptr[4], 4);
+ if (__builtin_object_size (res, 2) != 1)
+ abort ();
+ free (res);
+
+ res = strndup (&ptr[4], 1);
+ if (__builtin_object_size (res, 2) != 1)
+ abort ();
+ free (res);
+}
+
int
main (void)
{
@@ -651,5 +743,6 @@ main (void)
test8 ();
test9 (1);
test10 ();
+ test11 ();
exit (0);
}
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-4.c b/gcc/testsuite/gcc.dg/builtin-object-size-4.c
index b9fddfe..4c007c3 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-4.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-4.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-stringop-overread" } */
/* { dg-require-effective-target alloca } */
typedef __SIZE_TYPE__ size_t;
@@ -7,10 +7,13 @@ extern void abort (void);
extern void exit (int);
extern void *malloc (size_t);
extern void *calloc (size_t, size_t);
+extern void free (void *);
extern void *alloca (size_t);
extern void *memcpy (void *, const void *, size_t);
extern void *memset (void *, int, size_t);
extern char *strcpy (char *, const char *);
+extern char *strdup (const char *);
+extern char *strndup (const char *, size_t);
struct A
{
@@ -517,6 +520,94 @@ test8 (unsigned cond)
#endif
}
+/* Tests for strdup/strndup. */
+size_t
+__attribute__ ((noinline))
+test9 (void)
+{
+ const char *ptr = "abcdefghijklmnopqrstuvwxyz";
+ char *res = strndup (ptr, 21);
+ if (__builtin_object_size (res, 3) != 22)
+ abort ();
+
+ free (res);
+
+ res = strndup (ptr, 32);
+ if (__builtin_object_size (res, 3) != 27)
+ abort ();
+
+ free (res);
+
+ res = strdup (ptr);
+ if (__builtin_object_size (res, 3) != 27)
+ abort ();
+
+ free (res);
+
+ char *ptr2 = malloc (64);
+ strcpy (ptr2, ptr);
+
+ res = strndup (ptr2, 21);
+ if (__builtin_object_size (res, 3) != 1)
+ abort ();
+
+ free (res);
+
+ res = strndup (ptr2, 32);
+ if (__builtin_object_size (res, 3) != 1)
+ abort ();
+
+ free (res);
+
+ res = strndup (ptr2, 128);
+ if (__builtin_object_size (res, 3) != 1)
+ abort ();
+
+ free (res);
+
+ res = strdup (ptr2);
+#ifdef __builtin_object_size
+ if (__builtin_object_size (res, 3) != 27)
+#else
+ if (__builtin_object_size (res, 3) != 1)
+#endif
+ abort ();
+
+ free (res);
+ free (ptr2);
+
+ ptr = "abcd\0efghijklmnopqrstuvwxyz";
+ res = strdup (ptr);
+ if (__builtin_object_size (res, 3) != 5)
+ abort ();
+ free (res);
+
+ res = strndup (ptr, 24);
+ if (__builtin_object_size (res, 3) != 5)
+ abort ();
+ free (res);
+
+ res = strndup (ptr, 2);
+ if (__builtin_object_size (res, 3) != 3)
+ abort ();
+ free (res);
+
+ res = strdup (&ptr[4]);
+ if (__builtin_object_size (res, 3) != 1)
+ abort ();
+ free (res);
+
+ res = strndup (&ptr[4], 4);
+ if (__builtin_object_size (res, 3) != 1)
+ abort ();
+ free (res);
+
+ res = strndup (&ptr[4], 1);
+ if (__builtin_object_size (res, 3) != 1)
+ abort ();
+ free (res);
+}
+
int
main (void)
{
@@ -530,5 +621,6 @@ main (void)
test6 ();
test7 ();
test8 (1);
+ test9 ();
exit (0);
}
diff --git a/gcc/testsuite/gcc.dg/c11-float-8.c b/gcc/testsuite/gcc.dg/c11-float-8.c
new file mode 100644
index 0000000..7fb1e0a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-float-8.c
@@ -0,0 +1,9 @@
+/* Test __STDC_VERSION_FLOAT_H__ not in C11. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <float.h>
+
+#ifdef __STDC_VERSION_FLOAT_H__
+#error "__STDC_VERSION_FLOAT_H__ defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c11-keywords-1.c b/gcc/testsuite/gcc.dg/c11-keywords-1.c
index 974ccfc..997c1b0 100644
--- a/gcc/testsuite/gcc.dg/c11-keywords-1.c
+++ b/gcc/testsuite/gcc.dg/c11-keywords-1.c
@@ -5,6 +5,7 @@
int alignas;
int alignof;
int bool;
+int constexpr;
int false;
int true;
int static_assert;
diff --git a/gcc/testsuite/gcc.dg/c11-limits-1.c b/gcc/testsuite/gcc.dg/c11-limits-1.c
new file mode 100644
index 0000000..6dc5737
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-limits-1.c
@@ -0,0 +1,9 @@
+/* Test __STDC_VERSION_LIMITS_H__ not in C11. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <limits.h>
+
+#ifdef __STDC_VERSION_LIMITS_H__
+#error "__STDC_VERSION_LIMITS_H__ defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c11-stdarg-4.c b/gcc/testsuite/gcc.dg/c11-stdarg-4.c
new file mode 100644
index 0000000..06bff1f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-stdarg-4.c
@@ -0,0 +1,9 @@
+/* Test __STDC_VERSION_STDARG_H__ not in C11. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdarg.h>
+
+#ifdef __STDC_VERSION_STDARG_H__
+#error "__STDC_VERSION_STDARG_H__ defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c11-stdatomic-3.c b/gcc/testsuite/gcc.dg/c11-stdatomic-3.c
new file mode 100644
index 0000000..1f5a71b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-stdatomic-3.c
@@ -0,0 +1,9 @@
+/* Test __STDC_VERSION_STDATOMIC_H__ not in C11. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+#ifdef __STDC_VERSION_STDATOMIC_H__
+#error "__STDC_VERSION_STDATOMIC_H__ defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c11-stddef-1.c b/gcc/testsuite/gcc.dg/c11-stddef-1.c
new file mode 100644
index 0000000..9918d94
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-stddef-1.c
@@ -0,0 +1,9 @@
+/* Test __STDC_VERSION_STDDEF_H__ not in C11. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stddef.h>
+
+#ifdef __STDC_VERSION_STDDEF_H__
+#error "__STDC_VERSION_STDDEF_H__ defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c11-stdint-1.c b/gcc/testsuite/gcc.dg/c11-stdint-1.c
new file mode 100644
index 0000000..43fe681
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-stdint-1.c
@@ -0,0 +1,9 @@
+/* Test __STDC_VERSION_STDINT_H__ not in C11. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors -ffreestanding" } */
+
+#include <stdint.h>
+
+#ifdef __STDC_VERSION_STDINT_H__
+#error "__STDC_VERSION_STDINT_H__ defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-auto-1.c b/gcc/testsuite/gcc.dg/c2x-auto-1.c
new file mode 100644
index 0000000..f8460fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-auto-1.c
@@ -0,0 +1,81 @@
+/* Test C2x auto. Valid code, compilation tests. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+auto i = 1;
+extern int i;
+static auto l = { 0L };
+extern long l;
+extern auto const d = 0.0; /* { dg-warning "initialized and declared 'extern'" } */
+extern const double d;
+double dx;
+auto ((i2)) = 3;
+extern int i2;
+const auto i3 [[]] = { 4, };
+extern int i4;
+thread_local auto f = 1.0f;
+float ff;
+extern typeof (f) ff;
+auto h = (short) 0;
+extern short h;
+
+struct s { int a; };
+struct s sv;
+struct s2;
+enum e : int;
+
+extern const volatile long double cvld;
+extern void (*tfp) (void);
+
+int a[10];
+int *ap;
+
+typedef int ti;
+
+void
+tf ()
+{
+ auto asv = (struct s) { 0 };
+ extern typeof (asv) sv;
+ auto s2p = (struct s2 *) 0;
+ struct s3;
+ auto s3p = (struct s3 *) 0;
+ auto ev = (enum e) 0;
+ static const auto volatile acvld = 0.5L;
+ extern typeof (acvld) cvld;
+ /* lvalue conversion occurs on the initializer, so losing qualifiers. */
+ auto ncd = d;
+ extern typeof (ncd) dx;
+ _Atomic double ad = 0.0;
+ auto nad = ad;
+ extern typeof (nad) dx;
+ /* Function-to-pointer conversion occurs on the initializer. */
+ auto fp = tf;
+ extern typeof (fp) tfp;
+ /* Array-to-pointer conversion occurs on the initializer. */
+ auto aap = a;
+ extern typeof (aap) ap;
+ /* Shadowing a declaration from a containing scope is OK. */
+ auto i = 2L;
+ extern typeof (i) l;
+ /* auto can be used in for loops. */
+ for (auto ix = 2; ix < 10; ix++)
+ {
+ extern typeof (ix) i2;
+ }
+ /* auto is valid with bit-field initializers; the choice of type those have
+ in expressions is unspecified but should match how _Generic handles such
+ expressions. */
+ struct b { int a : 2; unsigned b : 3; } bv = { };
+ auto bfa = bv.a;
+ auto bfb = bv.b;
+ static_assert (_Generic (bv.a, typeof (bfa) : 1, default : 2) == 1);
+ static_assert (_Generic (bv.b, typeof (bfb) : 1, default : 2) == 1);
+ /* The traditional meaning of auto with a type specifier is OK. */
+ auto short s;
+ char auto c;
+ auto struct t { int x; } t;
+ /* That includes the case where the type comes from a typedef name. */
+ auto ti int_from_typedef = 3.0;
+ extern typeof (int_from_typedef) i2;
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-auto-2.c b/gcc/testsuite/gcc.dg/c2x-auto-2.c
new file mode 100644
index 0000000..a41f813
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-auto-2.c
@@ -0,0 +1,38 @@
+/* Test C2x auto. Valid code, execution tests. Based on auto-type-1.c. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+/* { dg-require-effective-target alloca } */
+
+extern void abort (void);
+extern void exit (int);
+
+auto i = 1;
+extern int i;
+auto c = (char) 1;
+extern char c;
+static auto u = 10U;
+extern unsigned int u;
+const auto ll = 1LL;
+extern const long long ll;
+
+int
+main (void)
+{
+ if (i != 1 || c != 1 || u != 10U)
+ abort ();
+ auto ai = i;
+ int *aip = &ai;
+ if (ai != 1)
+ abort ();
+ auto p = (int (*) [++i]) 0;
+ if (i != 2)
+ abort ();
+ if (sizeof (*p) != 2 * sizeof (int))
+ abort ();
+ int vla[u][u];
+ int (*vp)[u] = &vla[0];
+ auto vpp = ++vp;
+ if (vp != &vla[1])
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-auto-3.c b/gcc/testsuite/gcc.dg/c2x-auto-3.c
new file mode 100644
index 0000000..a34ce31
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-auto-3.c
@@ -0,0 +1,64 @@
+/* Test C2x auto. Invalid code. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+auto; /* { dg-error "empty declaration" } */
+auto *p = (int *) 0; /* { dg-error "plain identifier" } */
+auto i; /* { dg-error "initialized data declaration" } */
+auto g { } /* { dg-error "initialized data declaration" } */
+auto a = 1, b = 2; /* { dg-error "single declarator" } */
+auto long e0 = 0; /* { dg-error "file-scope declaration" } */
+long auto e1 = 0; /* { dg-error "file-scope declaration" } */
+int auto e2 = 0; /* { dg-error "file-scope declaration" } */
+
+extern int e3;
+auto e3 = 1; /* { dg-error "underspecified declaration of 'e3', which is already declared in this scope" } */
+
+void
+f ()
+{
+ extern int fe1;
+ auto fe1 = 1; /* { dg-error "underspecified declaration of 'fe1', which is already declared in this scope" } */
+ /* { dg-error "declaration of 'fe1' with no linkage follows extern declaration" "linkage error" { target *-*-* } .-1 } */
+ auto fe2 = (struct s *) 0; /* { dg-error "declared in underspecified object initializer" } */
+ auto fe3 = (union u *) 0; /* { dg-error "declared in underspecified object initializer" } */
+ auto fe4 = (struct s2 { int a; }) { }; /* { dg-error "defined in underspecified object initializer" } */
+ auto fe5 = (struct { int a; }) { }; /* { dg-error "defined in underspecified object initializer" } */
+ auto fe6 = (union u2 { int a; }) { }; /* { dg-error "defined in underspecified object initializer" } */
+ auto fe7 = (union { int a; }) { }; /* { dg-error "defined in underspecified object initializer" } */
+ auto fe8 = sizeof (enum e { A }); /* { dg-error "defined in underspecified object initializer" } */
+ /* The following case is undefined behavior (so doesn't actually require a
+ diagnostic). */
+ auto fe9 = sizeof (enum { B }); /* { dg-error "defined in underspecified object initializer" } */
+ /* Examples with a forward declaration, then definition inside auto. */
+ struct s3;
+ auto fe10 = (struct s3 { int a; }) { }; /* { dg-error "defined in underspecified object initializer" } */
+ union u3;
+ auto fe11 = (union u3 { int a; }) { }; /* { dg-error "defined in underspecified object initializer" } */
+}
+
+void f2 (auto x); /* { dg-error "storage class specified for parameter" } */
+void f3 (auto y) { } /* { dg-error "storage class specified for parameter" } */
+
+auto e4 = sizeof (e4); /* { dg-error "underspecified 'e4' referenced in its initializer" } */
+__SIZE_TYPE__ e5;
+void
+f4 ()
+{
+ auto e5 = sizeof (e5); /* { dg-error "underspecified 'e5' referenced in its initializer" } */
+}
+
+auto typedef int T; /* { dg-error "'typedef' used with 'auto'" } */
+auto auto e6 = 1; /* { dg-error "duplicate 'auto'" } */
+static auto int e7 = 1; /* { dg-error "multiple storage classes in declaration specifiers" } */
+_Thread_local auto int e8 = 2; /* { dg-error "'_Thread_local' used with 'auto'" } */
+_Thread_local int auto e9 = 3; /* { dg-error "'_Thread_local' used with 'auto'" } */
+/* { dg-error "file-scope declaration of 'e9' specifies 'auto'" "file-scope error" { target *-*-* } .-1 } */
+
+typedef auto int T2; /* { dg-error "multiple storage classes in declaration specifiers" } */
+
+void
+f5 ()
+{
+ static int auto e10 = 3; /* { dg-error "multiple storage classes in declaration specifiers" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-auto-4.c b/gcc/testsuite/gcc.dg/c2x-auto-4.c
new file mode 100644
index 0000000..3c6cb34
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-auto-4.c
@@ -0,0 +1,5 @@
+/* Test C2x auto. -Wc11-c2x-compat warning. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors -Wc11-c2x-compat" } */
+
+auto x = 2; /* { dg-warning "ISO C does not support 'auto' type deduction before" } */
diff --git a/gcc/testsuite/gcc.dg/c2x-constexpr-1.c b/gcc/testsuite/gcc.dg/c2x-constexpr-1.c
new file mode 100644
index 0000000..d43d95d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-constexpr-1.c
@@ -0,0 +1,312 @@
+/* Test C2x constexpr. Valid code, compilation tests. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include <float.h>
+
+constexpr int v1 = 1;
+static_assert (v1 == 1);
+extern typeof (v1) *pci;
+extern const int *pci;
+extern typeof (&(constexpr int) {}) pci;
+/* Redeclaring a constexpr object is OK (although it can't be declared before
+ the definition without undefined behavior). */
+extern const int v1;
+static_assert (v1 == 1);
+unsigned int constexpr v2 = 2;
+static_assert (v2 == 2);
+extern typeof (v2) *pcui;
+extern const unsigned int *pcui;
+static constexpr char v3 = 3;
+static_assert (v3 == 3);
+extern typeof (v3) *pcc;
+extern const char *pcc;
+constexpr void *v4 = 0;
+extern typeof (v4) *pcpv;
+extern void *const *pcpv;
+constexpr int *v5 = nullptr;
+extern typeof (v5) *pcpi;
+extern int *const *pcpi;
+constexpr double v6 = 3.5;
+extern typeof (v6) *pcd;
+extern const double *pcd;
+auto constexpr v7 = 1.0;
+extern typeof (v7) *pcd;
+constexpr auto v8 = 1.5f;
+extern typeof (v8) *pcf;
+extern const float *pcf;
+constexpr static long v9 = 2ULL;
+static_assert (v9 == 2);
+extern typeof (v9) *pcl;
+extern const long *pcl;
+const short *v10 = &(constexpr short) { 10 };
+/* Qualifiers that aren't permitted on a constexpr object itself are OK in a
+ pointer target. */
+constexpr volatile int *v11 = nullptr;
+extern typeof (v11) *pcpvi;
+extern volatile int *const *pcpvi;
+constexpr _Atomic int *v12 = nullptr;
+extern typeof (v12) *pcpai;
+extern _Atomic int *const *pcpai;
+constexpr int *restrict *v13 = nullptr;
+extern typeof (v13) cprpi;
+extern int *restrict *const cprpi;
+typedef int *P;
+constexpr restrict P *v14 = nullptr;
+extern typeof (v14) cprpi;
+struct s15 { volatile int a; _Atomic int b; int *restrict p; };
+constexpr struct s15 *v16 = nullptr;
+constexpr char v17[3] = { 1, 2, 3 };
+struct s18 { int a; int *b; double c; };
+constexpr struct s18 v19 = { 12345ULL, 0, 19.0L };
+static_assert (v19.a == 12345);
+union u20 { int a; float b; };
+constexpr union u20 v21 = { 1 };
+static_assert (v21.a == 1);
+constexpr union u20 v22 = { .b = 23.0 };
+constexpr float v23 = (float) (1.0f / 3.0f);
+constexpr double v24 = (double) (1.0 / 3.0);
+constexpr struct s18 v25 = { 0, 0, (double) (1.0 / 3.0) };
+static_assert (v25.a == 0);
+constexpr char v26[] = "abc\xfe";
+constexpr unsigned char v27[] = u8"xyz\xff";
+constexpr unsigned char v28[] = "\x12\x7f";
+constexpr signed char v29[] = "\x34\x66";
+constexpr double v30 = (int) (double) 3.0 - (long) (double) 2.0;
+constexpr int v31 = 1 + 2 + (int) 3.0;
+static_assert (v31 == 6);
+constexpr typeof (nullptr) v32 = nullptr;
+constexpr _Complex double v33 = __builtin_complex (1.0f, 3.0f / 2.0f);
+constexpr float v34 = 1234.0L;
+constexpr char v35 = 127ULL;
+#if FLT_MIN_EXP == -125 && FLT_MANT_DIG == 24
+constexpr float v36 = 0x1p-149;
+constexpr float _Complex v37 = __builtin_complex (0x1p-149, 0x1p127);
+constexpr float v38 = 0xffffffUL;
+constexpr float v39 = -0xffffffL;
+constexpr float v40 = 0xffffff0L;
+constexpr float v41 = 1ULL << 63;
+#endif
+#if DBL_MIN_EXP == -1021 && DBL_MANT_DIG == 53
+constexpr double v42 = 0x1p-1074L;
+constexpr _Complex double v43 = __builtin_complex (0x1p1023L, 0x1p-1074L);
+constexpr double v44 = 0x1fffffffffffffULL;
+constexpr double v45 = -0x1fffffffffffffLL;
+constexpr double v46 = 0x3ffffffffffffeULL;
+constexpr double v47 = 1ULL << 63;
+#endif
+constexpr void *v48 = (void *) 0;
+constexpr int *v49 = (void *) 0L;
+constexpr long *v50 = 0LL;
+constexpr int v51 = {};
+static_assert (v51 == 0);
+constexpr float v52 = {};
+constexpr long double v53 = {};
+constexpr int *v54 = {};
+constexpr void *v55 = {};
+constexpr typeof (nullptr) v56 = {};
+struct s57 { int *p; };
+union u58 { int *p; };
+constexpr int *v59 = 0;
+constexpr int *v60 = { 0 };
+constexpr struct s57 v61 = { 0 };
+constexpr struct s57 v62 = { { } }; /* { dg-warning "braces around scalar initializer" } */
+constexpr struct s57 v63 = { { 0 } }; /* { dg-warning "braces around scalar initializer" } */
+constexpr union u58 v64 = { 0 };
+constexpr union u58 v65 = { { } }; /* { dg-warning "braces around scalar initializer" } */
+constexpr union u58 v66 = { { 0 } }; /* { dg-warning "braces around scalar initializer" } */
+struct s67 { int a; float b; void *c; int *d; typeof (nullptr) e; int f; int g[2]; };
+struct s68 { struct s67 x; };
+union u69 { int a; float b; void *c; int *d; struct s68 e; };
+struct s70 { union u69 x; };
+constexpr struct s67 v71 = { 1, 2.0, 0, 0, nullptr, 7, { 3, 4 } };
+static_assert (v71.a == 1);
+static_assert (v71.f == 7);
+constexpr struct s67 v72 = v71;
+static_assert (v72.a == 1);
+static_assert (v72.f == 7);
+extern const struct s67 v71;
+constexpr auto v73 = v71;
+static_assert (v73.a == 1);
+static_assert (v73.f == 7);
+auto v74 = v71;
+constexpr struct s68 v75 = { v72 };
+static_assert (v75.x.a == 1);
+static_assert (v75.x.f == 7);
+constexpr union u69 v76 = { };
+static_assert (v76.a == 0);
+constexpr union u69 v77 = { .e = v75 };
+static_assert (v77.e.x.a == 1);
+static_assert (v77.e.x.f == 7);
+constexpr union u69 v78 = { .a = 1 };
+static_assert (v78.a == 1);
+constexpr union u69 v79 = { .e = { v72 } };
+static_assert (v79.e.x.a == 1);
+static_assert (v79.e.x.f == 7);
+enum e80 { E80 = v79.e.x.f };
+static_assert (E80 == 7);
+constexpr struct s70 v81 = { v79 };
+static_assert (v81.x.e.x.f == 7);
+constexpr struct s68 v82 = { (constexpr struct s67) { 5, 6, 0, 0, nullptr, 9, { 1, 2 } } };
+static_assert (v82.x.a == 5);
+static_assert (v82.x.f == 9);
+constexpr auto v83 = (constexpr int) { (constexpr int) { 0 } };
+/* These are null pointers but not null pointer constants. */
+constexpr typeof (nullptr) v84 = nullptr;
+constexpr void *v85 = 0;
+int *v86 = v85;
+int *v87 = v84;
+typeof (1 ? v85 : (int *) 0) v88;
+extern void *v88;
+typeof (1 ? (void *) 0 : (int *) 0) v89;
+extern int *v89;
+constexpr struct s68 v90 = { };
+static_assert (v90.x.a == 0);
+static_assert (v90.x.f == 0);
+constexpr int v91 = { 123 };
+static_assert (v91 == 123);
+constexpr int v92 = { v91 };
+static_assert (v92 == 123);
+/* Verify that constexpr values can be used in various contexts requiring
+ (integer) constant expressions. */
+struct s93 { int x : v79.e.x.f; };
+constexpr int v94 = alignof (int);
+alignas (v94) int v95;
+constexpr int v97[100] = { [v82.x.f] = 7 };
+static int v98[v94];
+
+void
+f0 ()
+{
+ constexpr int fv0 = 3;
+ static_assert (fv0 == 3);
+ auto constexpr fv1 = 4;
+ static_assert (fv1 == 4);
+ register constexpr float fv2 = 1.0;
+ constexpr auto fv3 = 123;
+ static_assert (fv3 == 123);
+ constexpr register void *fv4 = (void *) 0;
+ const int *fv5 = &(constexpr int) { 234 };
+ const int *fv6 = &(constexpr static int) { 234 };
+ const int *fv7 = &(static constexpr int) { 234 };
+ typeof ((constexpr register int) { 234 }) *fv8;
+ typeof ((register constexpr int) { 234 }) *fv9;
+ int fv10 = (constexpr int) { 1 } + sizeof (struct fs *);
+ constexpr auto fv11 = (constexpr int) { (constexpr int) { 0 } };
+ static_assert (fv11 == 0);
+ constexpr char fv12[3] = { 1, 2, 3 };
+ (constexpr short [4]) { 9, 8, 7, -6 };
+ constexpr struct s18 fv13 = { 1234ULL, 0, 13.0f };
+ (constexpr struct s18) { 123, (void *) 0, 11 };
+ constexpr union u20 fv14 = { 2 };
+ (constexpr union u20) { 5 };
+ constexpr union u20 fv15 = { .b = 15.0 };
+ (constexpr union u20) { .b = 20 };
+ (constexpr float) { (float) (1.0f / 3.0f) };
+ (constexpr double) { (double) (1.0 / 3.0) };
+ (constexpr struct s18) { 0, 0, (double) (1.0 / 3.0) };
+ (constexpr char []) { "abc\xfe" };
+ (constexpr unsigned char []) { u8"xyz\xff" };
+ (constexpr unsigned char []) { "\x12\x7f" };
+ (constexpr signed char []) { "\x34\x66" };
+ (constexpr double) { (int) (double) 3.0 - (long) (double) 2.0 };
+ (constexpr int) { 1 + 2 + (int) 3.0 };
+ (constexpr typeof (nullptr)) { nullptr };
+ (constexpr _Complex double) { __builtin_complex (1.0f, 3.0f / 2.0f) };
+ (constexpr float) { 1234.0L };
+ (constexpr char) { 127ULL };
+#if FLT_MIN_EXP == -125 && FLT_MANT_DIG == 24
+ (constexpr float) { 0x1p-149 };
+ (constexpr float _Complex) { __builtin_complex (0x1p-149, 0x1p127) };
+ (constexpr float) { 0xffffffUL };
+ (constexpr float) { -0xffffffL };
+ (constexpr float) { 0xffffff0L };
+ (constexpr float) { 1ULL << 63 };
+#endif
+#if DBL_MIN_EXP == -1021 && DBL_MANT_DIG == 53
+ (constexpr double) { 0x1p-1074L };
+ (constexpr _Complex double) { __builtin_complex (0x1p1023L, 0x1p-1074L) };
+ (constexpr double) { 0x1fffffffffffffULL };
+ (constexpr double) { -0x1fffffffffffffLL };
+ (constexpr double) { 0x3ffffffffffffeULL };
+ (constexpr double) { 1ULL << 63 };
+#endif
+ (constexpr void *) { (void *) 0 };
+ (constexpr int *) { (void *) 0L };
+ (constexpr long *) { 0LL };
+ (constexpr int) {};
+ (constexpr float) {};
+ (constexpr long double) {};
+ (constexpr int *) {};
+ (constexpr void *) {};
+ (constexpr typeof (nullptr)) {};
+ (constexpr int *) { 0 };
+ (constexpr struct s57) { 0 };
+ (constexpr struct s57) { { } }; /* { dg-warning "braces around scalar initializer" } */
+ (constexpr struct s57) { { 0 } }; /* { dg-warning "braces around scalar initializer" } */
+ (constexpr union u58) { 0 };
+ (constexpr union u58) { { } }; /* { dg-warning "braces around scalar initializer" } */
+ (constexpr union u58) { { 0 } }; /* { dg-warning "braces around scalar initializer" } */
+ /* It's not entirely clear if constexpr declarations are allowed in this
+ position in a for loop; presume they are, as implicitly auto just as if no
+ storage class specifiers were used. */
+ for (constexpr int fv16 = 1;;)
+ break;
+ constexpr struct s67 fv17 = { 1, 2.0, 0, 0, nullptr, 7, { 3, 4 } };
+ static_assert (fv17.a == 1);
+ static_assert (fv17.f == 7);
+ constexpr struct s67 fv18 = fv17;
+ static_assert (fv18.a == 1);
+ static_assert (fv18.f == 7);
+ constexpr auto fv19 = fv17;
+ static_assert (fv19.a == 1);
+ static_assert (fv19.f == 7);
+ auto fv20 = fv17;
+ constexpr struct s68 fv21 = { fv18 };
+ static_assert (fv21.x.a == 1);
+ static_assert (fv21.x.f == 7);
+ constexpr union u69 fv22 = { };
+ static_assert (fv22.a == 0);
+ constexpr union u69 fv23 = { .e = fv21 };
+ static_assert (fv23.e.x.a == 1);
+ static_assert (fv23.e.x.f == 7);
+ constexpr union u69 fv24 = { .a = 1 };
+ static_assert (fv24.a == 1);
+ constexpr union u69 fv25 = { .e = { fv18 } };
+ static_assert (fv25.e.x.a == 1);
+ static_assert (fv25.e.x.f == 7);
+ enum fe80 { FE80 = fv25.e.x.f };
+ static_assert (FE80 == 7);
+ constexpr struct s70 fv26 = { fv25 };
+ static_assert (fv26.x.e.x.f == 7);
+ constexpr struct s68 fv27 = { (constexpr struct s67) { 5, 6, 0, 0, nullptr, 9, { 1, 2 } } };
+ static_assert (fv27.x.a == 5);
+ static_assert (fv27.x.f == 9);
+ constexpr struct s68 fv28 = { };
+ static_assert (fv28.x.a == 0);
+ static_assert (fv28.x.f == 0);
+ constexpr int fv29 = { 123 };
+ static_assert (fv29 == 123);
+ constexpr int fv30 = { fv29 };
+ static_assert (fv30 == 123);
+ static_assert ((constexpr struct s67) { 1, 2.0, 0, 0, nullptr, 7, { 3, 4 } }.f == 7);
+ static_assert ((constexpr struct s68) { fv18 }.x.a == 1);
+ static_assert ((constexpr union u69) { }.a == 0);
+ static_assert ((constexpr union u69) { .e = fv21 }.e.x.f == 7);
+ static_assert ((constexpr union u69) { .a = 1 }.a == 1);
+ static_assert ((constexpr union u69) { .e = { fv18 } }.e.x.a == 1);
+ static_assert ((constexpr struct s70) { fv25 }.x.e.x.f == 7);
+ static_assert ((constexpr struct s68) { (constexpr struct s67) { 5, 6, 0, 0, nullptr, 9, { 1, 2 } } }.x.f == 9);
+ static_assert ((constexpr struct s68) { }.x.f == 0);
+ /* Verify that constexpr values can be used in various contexts requiring
+ (integer) constant expressions. */
+ struct fs93 { int x : fv25.e.x.f; };
+ constexpr int fv31 = alignof (int);
+ alignas (fv31) int fv32;
+ constexpr int fv33[100] = { [fv27.x.f] = 7 };
+ static int fv34[fv31];
+ switch (fv0)
+ {
+ case fv27.x.f: ;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-constexpr-2a.c b/gcc/testsuite/gcc.dg/c2x-constexpr-2a.c
new file mode 100644
index 0000000..f74e2ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-constexpr-2a.c
@@ -0,0 +1,37 @@
+/* Test C2x constexpr. Valid code, execution test. */
+/* { dg-do link } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+/* { dg-additional-sources "c2x-constexpr-2b.c" } */
+
+extern void abort (void);
+extern void exit (int);
+
+/* constexpr objects at file scope have internal linkage. */
+constexpr int a = 2;
+
+struct s { int a; float b; int c[3]; };
+constexpr struct s s1 = { 2, 3, { 4, 5, 6 } };
+constexpr struct s s2 = s1;
+struct s s3 = s2;
+
+void
+check (const struct s *p)
+{
+ if (p->a != 2 || p->b != 3 || p->c[0] != 4 || p->c[1] != 5 || p->c[2] != 6)
+ abort ();
+}
+
+int
+main ()
+{
+ constexpr struct s s4 = s1;
+ struct s s5 = s4;
+ constexpr struct s s6 = { s1.a, s2.b, { 4, 5, 6 } };
+ check (&s1);
+ check (&s2);
+ check (&s3);
+ check (&s4);
+ check (&s5);
+ check (&s6);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-constexpr-2b.c b/gcc/testsuite/gcc.dg/c2x-constexpr-2b.c
new file mode 100644
index 0000000..04058b3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-constexpr-2b.c
@@ -0,0 +1,6 @@
+/* Test C2x constexpr. Second file for link test. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+/* constexpr objects at file scope have internal linkage. */
+constexpr int a = 3;
diff --git a/gcc/testsuite/gcc.dg/c2x-constexpr-3.c b/gcc/testsuite/gcc.dg/c2x-constexpr-3.c
new file mode 100644
index 0000000..29fedc0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-constexpr-3.c
@@ -0,0 +1,236 @@
+/* Test C2x constexpr. Invalid code. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+extern constexpr int v0 = 0; /* { dg-error "'constexpr' used with 'extern'" } */
+/* { dg-warning "initialized and declared 'extern'" "initialized extern" { target *-*-* } .-1 } */
+constexpr extern int v1 = 0; /* { dg-error "'constexpr' used with 'extern'" } */
+/* { dg-warning "initialized and declared 'extern'" "initialized extern" { target *-*-* } .-1 } */
+typedef constexpr int v2; /* { dg-error "'constexpr' used with 'typedef'" } */
+constexpr typedef int v3; /* { dg-error "'constexpr' used with 'typedef'" } */
+thread_local constexpr int v4 = 0; /* { dg-error "'constexpr' used with '_Thread_local'" } */
+constexpr thread_local int v5 = 0; /* { dg-error "'thread_local' used with 'constexpr'" } */
+constexpr constexpr int v6 = 1; /* { dg-error "duplicate 'constexpr'" } */
+constexpr struct v7; /* { dg-error "'constexpr' in empty declaration" } */
+/* { dg-error "'struct v7' declared in underspecified object declaration" "underspecified" { target *-*-* } .-1 } */
+constexpr union v8; /* { dg-error "'constexpr' in empty declaration" } */
+/* { dg-error "'union v8' declared in underspecified object declaration" "underspecified" { target *-*-* } .-1 } */
+constexpr struct v9 { int a; }; /* { dg-error "'constexpr' in empty declaration" } */
+/* { dg-error "'struct v9' defined in underspecified object declaration" "underspecified" { target *-*-* } .-1 } */
+constexpr union v10 { int a; }; /* { dg-error "'constexpr' in empty declaration" } */
+/* { dg-error "'union v10' defined in underspecified object declaration" "underspecified" { target *-*-* } .-1 } */
+constexpr; /* { dg-error "'constexpr' in empty declaration" } */
+constexpr int; /* { dg-error "empty declaration" } */
+constexpr const; /* { dg-error "empty declaration" } */
+constexpr int v11; /* { dg-error "initialized data declaration" } */
+constexpr int v12 { } /* { dg-error "initialized data declaration" } */
+constexpr int v13 = 1, v14 = 2; /* { dg-error "single declarator" } */
+constexpr int v15 = sizeof (struct v16 *); /* { dg-error "declared in underspecified object initializer" } */
+constexpr int v17 = sizeof (union v18 *); /* { dg-error "declared in underspecified object initializer" } */
+constexpr int v19 = sizeof (struct v20 { int a; }); /* { dg-error "defined in underspecified object initializer" } */
+constexpr int v21 = sizeof (struct { int a; }); /* { dg-error "defined in underspecified object initializer" } */
+constexpr int v22 = sizeof (union v23 { int a; }); /* { dg-error "defined in underspecified object initializer" } */
+constexpr int v24 = sizeof (union { int a; }); /* { dg-error "defined in underspecified object initializer" } */
+constexpr int v25 = sizeof (enum v26 { A }); /* { dg-error "defined in underspecified object initializer" } */
+/* The following case is undefined behavior (so doesn't actually require a
+ diagnostic). */
+constexpr int v27 = sizeof (enum { B }); /* { dg-error "defined in underspecified object initializer" } */
+/* Examples with a forward declaration, then definition inside constexpr. */
+struct v28;
+constexpr int v29 = sizeof (struct v28 { int a; }); /* { dg-error "defined in underspecified object initializer" } */
+union v30;
+constexpr int v31 = sizeof (union v30 { int a; }); /* { dg-error "defined in underspecified object initializer" } */
+constexpr int v32 = sizeof (v32); /* { dg-error "underspecified 'v32' referenced in its initializer" } */
+static const int v33;
+constexpr const int v33 = 1; /* { dg-error "underspecified declaration of 'v33', which is already declared in this scope" } */
+constexpr void v34 () {} /* { dg-error "'constexpr' requires an initialized data declaration" } */
+void v35 (constexpr int v36); /* { dg-error "storage class specified for parameter 'v36'" } */
+void v37 (constexpr short); /* { dg-error "storage class specified for unnamed parameter" } */
+void v38 (constexpr register int v39); /* { dg-error "storage class specified for parameter 'v39'" } */
+void v40 (constexpr register short); /* { dg-error "storage class specified for unnamed parameter" } */
+/* The following case is undefined behavior (presumably to allow for possible
+ future support for constexpr functions), but should clearly be diagnosed
+ when such functions aren't actually supported. */
+constexpr int v41 (); /* { dg-error "'constexpr' requires an initialized data declaration" } */
+typedef volatile long t42;
+typedef int *restrict t43;
+typedef _Atomic int t44;
+struct t45 { struct { struct { t42 a[2]; } a; } a; };
+struct t46 { struct { struct { int z; int *restrict a; } a[3]; } a; };
+struct t47 { short x; struct { struct { _Atomic long a; } a; } a[4][5]; };
+constexpr t42 v48 = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+constexpr t43 v49 = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+constexpr t44 v50 = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+constexpr volatile double v51 = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+constexpr int *restrict v52 = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+constexpr _Atomic (short) v53 = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+constexpr long *volatile v54 = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+constexpr struct t45 v55 = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+constexpr struct t46 v56 = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+constexpr struct t47 v57 = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+union t58 { struct { union { t42 a[1]; } a; } a; };
+union t59 { struct { union { int z; int *restrict a; } a; } a; };
+union t60 { short x; union { struct { _Atomic long a; } a[3]; } a; };
+constexpr union t58 v61 = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+constexpr union t59 v62 = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+constexpr union t60 v63 = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+constexpr t42 v64[1][2][3] = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+constexpr volatile int v65[1][2][3] = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+constexpr struct t45 v66[2][2][4] = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+constexpr union t60 v67[2][2][4] = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+int v68 = 0;
+constexpr int v69 = v68; /* { dg-error "initializer element is not constant" } */
+double exp (double);
+constexpr double v70 = exp (0); /* { dg-error "initializer element is not a constant expression" } */
+struct s71 { int a; double b; };
+constexpr struct s71 v72 = { 0, exp (0) }; /* { dg-error "initializer element is not a constant expression" } */
+/* { dg-error "'constexpr' initializer is not an arithmetic constant expression" "arithmetic" { target *-*-* } .-1 } */
+constexpr struct s71 v73 = { v68, 0 }; /* { dg-error "initializer element is not constant" } */
+union u74 { int a; double b; };
+constexpr union u74 v75 = { v68 }; /* { dg-error "initializer element is not constant" } */
+constexpr union u74 v76 = { .b = exp (0) }; /* { dg-error "initializer element is not a constant expression" } */
+/* { dg-error "'constexpr' initializer is not an arithmetic constant expression" "arithmetic" { target *-*-* } .-1 } */
+constexpr struct s77 *v77 = 0; /* { dg-error "'struct s77' declared in underspecified object declaration" } */
+constexpr union u78 *v78 = 0; /* { dg-error "'union u78' declared in underspecified object declaration" } */
+constexpr struct s79 { int a; } v79 = { 0 }; /* { dg-error "'struct s79' defined in underspecified object declaration" } */
+constexpr union u80 { int a; } v80 = { 0 }; /* { dg-error "'union u80' defined in underspecified object declaration" } */
+constexpr enum e81 { E81 } v81 = E81; /* { dg-error "'enum e81' defined in underspecified object declaration" } */
+constexpr enum { E82 } v82 = E82; /* { dg-error "defined in underspecified object declaration" } */
+struct s83 constexpr *v83 = 0; /* { dg-error "'struct s83' declared in underspecified object declaration" } */
+union u84 constexpr *v84 = 0; /* { dg-error "'union u84' declared in underspecified object declaration" } */
+struct s85 { int a; } constexpr v85 = { 0 }; /* { dg-error "'struct s85' defined in underspecified object declaration" } */
+union u86 { int a; } constexpr v86 = { 0 }; /* { dg-error "'union u86' defined in underspecified object declaration" } */
+enum e87 { E87 } constexpr v87 = E87; /* { dg-error "'enum e87' defined in underspecified object declaration" } */
+enum { E88 } constexpr v88 = E88; /* { dg-error "defined in underspecified object declaration" } */
+constexpr int *v89 = (int *) 0; /* { dg-error "'constexpr' pointer initializer is not a null pointer constant" } */
+constexpr void *v90 = (void *) (void *) 0; /* { dg-error "'constexpr' pointer initializer is not a null pointer constant" } */
+constexpr int v91 = (int) (double) 1.0; /* { dg-error "constexpr' integer initializer is not an integer constant expression" } */
+constexpr struct s71 v92 = { (int) (double) 1.0, 0 }; /* { dg-error "constexpr' integer initializer is not an integer constant expression" } */
+struct s93 { void *p; };
+constexpr struct s93 v94 = { (int *) 0 }; /* { dg-error "'constexpr' pointer initializer is not a null pointer constant" } */
+constexpr int v95 = (unsigned int) -1; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr unsigned char v96 = -1; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr signed char v97 = 1234567LL; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+/* { dg-warning "overflow in conversion" "overflow warning" { target *-*-* } .-1 } */
+/* Disallow all real/complex conversions (the C2x CD is unclear about
+ real-to-complex and about complex-to-real with imaginary part positive 0, if
+ the real parts can be exactly represented in the relevant types). */
+constexpr double v98 = __builtin_complex (1.0, 0.0); /* { dg-error "'constexpr' initializer for a real type is of complex type" } */
+constexpr double v99 = __builtin_complex (1.0, 1.0); /* { dg-error "'constexpr' initializer for a real type is of complex type" } */
+constexpr double v100 = __builtin_complex (1.0, -0.0); /* { dg-error "'constexpr' initializer for a real type is of complex type" } */
+constexpr _Complex double v101 = 1.0; /* { dg-error "'constexpr' initializer for a complex type is of real type" } */
+constexpr float v102 = (unsigned long long) -1; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr double v103 = (unsigned long long) -1; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr float v104 = __LONG_LONG_MAX__; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr double v105 = __LONG_LONG_MAX__; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr signed char v106[] = u8"\xff"; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+/* Only the initialized (possibly by default) element of a constexpr union is a
+ named constant. */
+union u107 { int a; int b; };
+constexpr union u107 v108 = { };
+constexpr union u107 v109 = { .a = 0 };
+constexpr union u107 v110 = { .b = 0 };
+constexpr int v111 = v108.b; /* { dg-error "initializer" } */
+constexpr int v112 = v109.b; /* { dg-error "initializer" } */
+constexpr int v113 = v110.a; /* { dg-error "initializer" } */
+/* A reference to an array in a constexpr object is converted to a pointer as
+ usual, so in particular is not equivalent to directly using a string literal
+ initializer extracted from the initializer of that object. */
+struct s114 { char c[10]; };
+constexpr struct s114 v115 = { "abc" };
+constexpr struct s114 v116 = { v115.c }; /* { dg-error "initializer" } */
+/* { dg-error "integer from pointer" "conversion" { target *-*-* } .-1 } */
+
+void
+f0 ()
+{
+ (constexpr constexpr int) { 1 }; /* { dg-error "duplicate 'constexpr'" } */
+ (constexpr thread_local int) { 1 }; /* { dg-error "'thread_local' used with 'constexpr'" } */
+ (thread_local constexpr static int) { 1 }; /* { dg-error "'constexpr' used with '_Thread_local'" } */
+ (constexpr int) { sizeof (struct fs1 *) }; /* { dg-error "declared in underspecified object initializer" } */
+ (constexpr int) { sizeof (union fs2 *) }; /* { dg-error "declared in underspecified object initializer" } */
+ (constexpr int) { sizeof (struct fs3 { int a; }) }; /* { dg-error "defined in underspecified object initializer" } */
+ (constexpr int) { sizeof (struct { int a; }) }; /* { dg-error "defined in underspecified object initializer" } */
+ (constexpr int) { sizeof (union fs4 { int a; }) }; /* { dg-error "defined in underspecified object initializer" } */
+ (constexpr int) { sizeof (union { int a; }) }; /* { dg-error "defined in underspecified object initializer" } */
+ (constexpr int) { sizeof (enum fs5 { A }) }; /* { dg-error "defined in underspecified object initializer" } */
+ /* The following case is undefined behavior (so doesn't actually require a
+ diagnostic). */
+ (constexpr int) { sizeof (enum { B }) }; /* { dg-error "defined in underspecified object initializer" } */
+ /* Examples with a forward declaration, then definition inside constexpr. */
+ struct fs6;
+ (constexpr int) { sizeof (struct fs6 { int a; }) }; /* { dg-error "defined in underspecified object initializer" } */
+ union fs7;
+ (constexpr int) { sizeof (union fs7 { int a; }) }; /* { dg-error "defined in underspecified object initializer" } */
+ constexpr int fv32 = sizeof (fv32); /* { dg-error "underspecified 'fv32' referenced in its initializer" } */
+ /* Test entering then exiting nested underspecified initializers. */
+ constexpr int x = (constexpr int) { 1 } + sizeof (struct fs8 *); /* { dg-error "declared in underspecified object initializer" } */
+ auto y = (constexpr int) { 1 } + sizeof (struct fs9 *); /* { dg-error "declared in underspecified object initializer" } */
+ extern const int z; /* { dg-message "previous declaration" } */
+ constexpr const int z = 1; /* { dg-error "underspecified declaration of 'z', which is already declared in this scope" } */
+ /* { dg-error "declaration of 'z' with no linkage follows extern declaration" "linkage error" { target *-*-* } .-1 } */
+ int non_const = 1;
+ typedef int VLA[non_const];
+ constexpr VLA *pnc = nullptr; /* { dg-error "'constexpr' object has variably modified type" } */
+ (constexpr t42) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+ (constexpr t43) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+ (constexpr t44) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+ (constexpr volatile double) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+ (constexpr int *restrict) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+ (constexpr _Atomic (short)) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+ (constexpr long *volatile) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+ (constexpr struct t45) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+ (constexpr struct t46) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+ (constexpr struct t47) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+ (constexpr union t58) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+ (constexpr union t59) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+ (constexpr union t60) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+ (constexpr t42 [1][2][3]) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+ (constexpr volatile int [1][2][3]) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
+ (constexpr struct t45 [2][2][4]) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+ (constexpr union t60 [2][2][4]) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
+ (constexpr int) { v68 }; /* { dg-error "initializer element is not constant" } */
+ (constexpr double) { exp (0) }; /* { dg-error "initializer element is not a constant expression" } */
+ /* { dg-error "'constexpr' initializer is not an arithmetic constant expression" "arithmetic" { target *-*-* } .-1 } */
+ (constexpr struct s71) { 0, exp (0) }; /* { dg-error "initializer element is not a constant expression" } */
+ /* { dg-error "'constexpr' initializer is not an arithmetic constant expression" "arithmetic" { target *-*-* } .-1 } */
+ (constexpr struct s71) { v68, 0 }; /* { dg-error "initializer element is not constant" } */
+ (constexpr union u74) { v68 }; /* { dg-error "initializer element is not constant" } */
+ (constexpr union u74) { .b = exp (0) }; /* { dg-error "initializer element is not a constant expression" } */
+ /* { dg-error "'constexpr' initializer is not an arithmetic constant expression" "arithmetic" { target *-*-* } .-1 } */
+ (constexpr struct fs10 *) { 0 }; /* { dg-error "declared in 'constexpr' compound literal" } */
+ (constexpr union fs11 *) { 0 }; /* { dg-error "declared in 'constexpr' compound literal" } */
+ (constexpr struct fs12 { int a; }) { 0 }; /* { dg-error "defined in 'constexpr' compound literal" } */
+ (constexpr union fs13 { int a; }) { 0 }; /* { dg-error "defined in 'constexpr' compound literal" } */
+ (constexpr enum fs14 { FS14 }) { FS14 }; /* { dg-error "defined in 'constexpr' compound literal" } */
+ (constexpr enum { FS15 }) { FS15 }; /* { dg-error "defined in 'constexpr' compound literal" } */
+ (constexpr int *) { (int *) 0 }; /* { dg-error "'constexpr' pointer initializer is not a null pointer constant" } */
+ (constexpr void *) { (void *) (void *) 0 }; /* { dg-error "'constexpr' pointer initializer is not a null pointer constant" } */
+ (constexpr int) { (int) (double) 1.0 }; /* { dg-error "constexpr' integer initializer is not an integer constant expression" } */
+ (constexpr struct s71) { (int) (double) 1.0, 0 }; /* { dg-error "constexpr' integer initializer is not an integer constant expression" } */
+ (constexpr struct s93) { (int *) 0 }; /* { dg-error "'constexpr' pointer initializer is not a null pointer constant" } */
+ (constexpr int) { (unsigned int) -1 }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr unsigned char) { -1 }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr signed char) { 1234567LL }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ /* { dg-warning "overflow in conversion" "overflow warning" { target *-*-* } .-1 } */
+ (constexpr double) { __builtin_complex (1.0, 0.0) }; /* { dg-error "'constexpr' initializer for a real type is of complex type" } */
+ (constexpr double) { __builtin_complex (1.0, 1.0) }; /* { dg-error "'constexpr' initializer for a real type is of complex type" } */
+ (constexpr double) { __builtin_complex (1.0, -0.0) }; /* { dg-error "'constexpr' initializer for a real type is of complex type" } */
+ (constexpr _Complex double) { 1.0 }; /* { dg-error "'constexpr' initializer for a complex type is of real type" } */
+ (constexpr float) { (unsigned long long) -1 }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr double) { (unsigned long long) -1 }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr float) { __LONG_LONG_MAX__ }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr double) { __LONG_LONG_MAX__ }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr signed char []) { u8"\xff" }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ constexpr typeof (nullptr) not_npc = nullptr;
+ int *ptr = 0;
+ (void) (ptr == not_npc); /* { dg-error "invalid operands" } */
+ /* auto may only be used with another storage class specifier, such as
+ constexpr, if the type is inferred. */
+ auto constexpr int a_c_t = 1; /* { dg-error "'auto' used with 'constexpr'" } */
+ constexpr auto int c_a_t = 1; /* { dg-error "'auto' used with 'constexpr'" } */
+ auto int constexpr a_t_c = 1; /* { dg-error "'constexpr' used with 'auto'" } */
+ constexpr int auto c_t_a = 1; /* { dg-error "'auto' used with 'constexpr'" } */
+ int auto constexpr t_a_c = 1; /* { dg-error "'constexpr' used with 'auto'" } */
+ int constexpr auto t_c_a = 1; /* { dg-error "'auto' used with 'constexpr'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-constexpr-4.c b/gcc/testsuite/gcc.dg/c2x-constexpr-4.c
new file mode 100644
index 0000000..2a42af8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-constexpr-4.c
@@ -0,0 +1,21 @@
+/* Test C2x constexpr. Valid code, compilation tests, signed char. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors -fsigned-char" } */
+
+constexpr char v1[] = "\x00\xff";
+constexpr signed char v2[] = "\x7f\x80";
+constexpr unsigned char v3[] = "\x00\x7f";
+constexpr char v4[] = u8"\x00\x7f";
+constexpr signed char v5[] = u8"\x7f\x00";
+constexpr unsigned char v6[] = u8"\x00\xff";
+
+void
+f0 ()
+{
+ (constexpr char []) { "\x00\xff" };
+ (constexpr signed char []) { "\x7f\x80" };
+ (constexpr unsigned char []) { "\x00\x7f" };
+ (constexpr char []) { u8"\x00\x7f" };
+ (constexpr signed char []) { u8"\x7f\x00" };
+ (constexpr unsigned char []) { u8"\x00\xff" };
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-constexpr-5.c b/gcc/testsuite/gcc.dg/c2x-constexpr-5.c
new file mode 100644
index 0000000..6febd2e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-constexpr-5.c
@@ -0,0 +1,21 @@
+/* Test C2x constexpr. Valid code, compilation tests, unsigned char. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors -funsigned-char" } */
+
+constexpr char v1[] = "\x00\xff";
+constexpr signed char v2[] = "\x7f\x00";
+constexpr unsigned char v3[] = "\x80\x7f";
+constexpr char v4[] = u8"\x00\xff";
+constexpr signed char v5[] = u8"\x7f\x00";
+constexpr unsigned char v6[] = u8"\x00\xff";
+
+void
+f0 ()
+{
+ (constexpr char []) { "\x00\xff" };
+ (constexpr signed char []) { "\x7f\x00" };
+ (constexpr unsigned char []) { "\x80\x7f" };
+ (constexpr char []) { u8"\x00\xff" };
+ (constexpr signed char []) { u8"\x7f\x00" };
+ (constexpr unsigned char []) { u8"\x00\xff" };
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-constexpr-6.c b/gcc/testsuite/gcc.dg/c2x-constexpr-6.c
new file mode 100644
index 0000000..a86124a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-constexpr-6.c
@@ -0,0 +1,15 @@
+/* Test C2x constexpr. Invalid code, compilation tests, signed char. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors -fsigned-char" } */
+
+constexpr unsigned char v3[] = "\x00\xff"; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr char v4[] = u8"\x00\xff"; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr signed char v5[] = u8"\x00\xff"; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+
+void
+f0 ()
+{
+ (constexpr unsigned char []) { "\x00\xff" }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr char []) { u8"\x00\xff" }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr signed char []) { u8"\x00\xff" }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-constexpr-7.c b/gcc/testsuite/gcc.dg/c2x-constexpr-7.c
new file mode 100644
index 0000000..5282d92
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-constexpr-7.c
@@ -0,0 +1,13 @@
+/* Test C2x constexpr. Invalid code, compilation tests, unsigned char. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors -funsigned-char" } */
+
+constexpr signed char v2[] = "\x00\xff"; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr signed char v5[] = u8"\x00\xff"; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+
+void
+f0 ()
+{
+ (constexpr signed char []) { "\x00\xff" }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr signed char []) { u8"\x00\xff" }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-constexpr-8.c b/gcc/testsuite/gcc.dg/c2x-constexpr-8.c
new file mode 100644
index 0000000..c7119c9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-constexpr-8.c
@@ -0,0 +1,23 @@
+/* Test C2x constexpr. Valid code, compilation tests, IEEE arithmetic. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target inff } */
+
+constexpr float fi = __builtin_inf ();
+constexpr double di = __builtin_inff ();
+constexpr float fn = __builtin_nan ("");
+constexpr double dn = __builtin_nanf ("");
+constexpr float fns = __builtin_nansf ("");
+constexpr double dns = __builtin_nans ("");
+
+void
+f0 (void)
+{
+ (constexpr float) { __builtin_inf () };
+ (constexpr double) { __builtin_inff () };
+ (constexpr float) { __builtin_nan ("") };
+ (constexpr double) { __builtin_nanf ("") };
+ (constexpr float) { __builtin_nansf ("") };
+ (constexpr double) { __builtin_nans ("") };
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-constexpr-9.c b/gcc/testsuite/gcc.dg/c2x-constexpr-9.c
new file mode 100644
index 0000000..c62fc73
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-constexpr-9.c
@@ -0,0 +1,39 @@
+/* Test C2x constexpr. Invalid code, compilation tests, IEEE arithmetic. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target inff } */
+
+/* A conversion from signaling NaN to quiet NaN in a different format is not
+ valid for constexpr. */
+constexpr float fns = __builtin_nans (""); /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr double dns = __builtin_nansf (""); /* { dg-error "'constexpr' initializer not representable in type of object" } */
+
+/* Test out-of-range values. */
+constexpr float fu = __DBL_MIN__; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr float fo = __DBL_MAX__; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr float fp = 0x1.ffffffp0; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+
+constexpr _Complex float cfur = __builtin_complex (__DBL_MIN__, 0.0); /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr _Complex float cfor = __builtin_complex (__DBL_MAX__, 0.0); /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr _Complex float cfpr = __builtin_complex (0x1.ffffffp0, 0.0); /* { dg-error "'constexpr' initializer not representable in type of object" } */
+
+constexpr _Complex float cfui = __builtin_complex (0.0, __DBL_MIN__); /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr _Complex float cfoi = __builtin_complex (0.0, __DBL_MAX__); /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr _Complex float cfpi = __builtin_complex (0.0, 0x1.ffffffp0); /* { dg-error "'constexpr' initializer not representable in type of object" } */
+
+void
+f0 ()
+{
+ (constexpr float) { __builtin_nans ("") }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr double) { __builtin_nansf ("") }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr float) { __DBL_MIN__ }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr float) { __DBL_MAX__ }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr float) { 0x1.ffffffp0 }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Complex float) { __builtin_complex (__DBL_MIN__, 0.0) }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Complex float) { __builtin_complex (__DBL_MAX__, 0.0) }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Complex float) { __builtin_complex (0x1.ffffffp0, 0.0) }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Complex float) { __builtin_complex (0.0, __DBL_MIN__) }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Complex float) { __builtin_complex (0.0, __DBL_MAX__) }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Complex float) { __builtin_complex (0.0, 0x1.ffffffp0) }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-float-13.c b/gcc/testsuite/gcc.dg/c2x-float-13.c
new file mode 100644
index 0000000..dc54bc7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-13.c
@@ -0,0 +1,13 @@
+/* Test __STDC_VERSION_FLOAT_H__ in C2x. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include <float.h>
+
+#ifndef __STDC_VERSION_FLOAT_H__
+#error "__STDC_VERSION_FLOAT_H__ not defined"
+#endif
+
+#if __STDC_VERSION_FLOAT_H__ != 202311L
+#error "bad value of __STDC_VERSION_FLOAT_H__"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-limits-1.c b/gcc/testsuite/gcc.dg/c2x-limits-1.c
new file mode 100644
index 0000000..4977faf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-limits-1.c
@@ -0,0 +1,13 @@
+/* Test __STDC_VERSION_LIMITS_H__ in C2x. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include <limits.h>
+
+#ifndef __STDC_VERSION_LIMITS_H__
+#error "__STDC_VERSION_LIMITS_H__ not defined"
+#endif
+
+#if __STDC_VERSION_LIMITS_H__ != 202311L
+#error "bad value of __STDC_VERSION_LIMITS_H__"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-stdarg-5.c b/gcc/testsuite/gcc.dg/c2x-stdarg-5.c
new file mode 100644
index 0000000..1342443
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-stdarg-5.c
@@ -0,0 +1,13 @@
+/* Test __STDC_VERSION_STDARG_H__ in C2x. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include <stdarg.h>
+
+#ifndef __STDC_VERSION_STDARG_H__
+#error "__STDC_VERSION_STDARG_H__ not defined"
+#endif
+
+#if __STDC_VERSION_STDARG_H__ != 202311L
+#error "bad value of __STDC_VERSION_STDARG_H__"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-stdatomic-1.c b/gcc/testsuite/gcc.dg/c2x-stdatomic-1.c
new file mode 100644
index 0000000..3a9ceb0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-stdatomic-1.c
@@ -0,0 +1,13 @@
+/* Test __STDC_VERSION_STDATOMIC_H__ in C2x. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+#ifndef __STDC_VERSION_STDATOMIC_H__
+#error "__STDC_VERSION_STDATOMIC_H__ not defined"
+#endif
+
+#if __STDC_VERSION_STDATOMIC_H__ != 202311L
+#error "bad value of __STDC_VERSION_STDATOMIC_H__"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-stddef-1.c b/gcc/testsuite/gcc.dg/c2x-stddef-1.c
new file mode 100644
index 0000000..1ebdf20
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-stddef-1.c
@@ -0,0 +1,13 @@
+/* Test __STDC_VERSION_STDDEF_H__ in C2x. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include <stddef.h>
+
+#ifndef __STDC_VERSION_STDDEF_H__
+#error "__STDC_VERSION_STDDEF_H__ not defined"
+#endif
+
+#if __STDC_VERSION_STDDEF_H__ != 202311L
+#error "bad value of __STDC_VERSION_STDDEF_H__"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-stdint-1.c b/gcc/testsuite/gcc.dg/c2x-stdint-1.c
new file mode 100644
index 0000000..3ba6ce5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-stdint-1.c
@@ -0,0 +1,13 @@
+/* Test __STDC_VERSION_STDINT_H__ in C2x. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors -ffreestanding" } */
+
+#include <stdint.h>
+
+#ifndef __STDC_VERSION_STDINT_H__
+#error "__STDC_VERSION_STDINT_H__ not defined"
+#endif
+
+#if __STDC_VERSION_STDINT_H__ != 202311L
+#error "bad value of __STDC_VERSION_STDINT_H__"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c90-auto-1.c b/gcc/testsuite/gcc.dg/c90-auto-1.c
new file mode 100644
index 0000000..f00f767
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c90-auto-1.c
@@ -0,0 +1,12 @@
+/* Test auto with implicit int for C90. */
+/* { dg-do compile } */
+/* { dg-options "-std=c90 -pedantic-errors" } */
+
+void
+f (void)
+{
+ /* This should have type int following C90 rules, whereas in C2x it
+ would have type double. */
+ auto x = 1.5;
+ int *p = &x;
+}
diff --git a/gcc/testsuite/gcc.dg/cpp/c11-vararg-1.c b/gcc/testsuite/gcc.dg/cpp/c11-vararg-1.c
new file mode 100644
index 0000000..6b1bc38
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/c11-vararg-1.c
@@ -0,0 +1,9 @@
+/* Test error in C11 for no arguments passed for variable arguments to a
+ macro. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#define M(X, ...) X
+
+M (x); /* { dg-error "requires at least one argument" } */
+M (x, y);
diff --git a/gcc/testsuite/gcc.dg/cpp/c2x-va-opt-1.c b/gcc/testsuite/gcc.dg/cpp/c2x-va-opt-1.c
new file mode 100644
index 0000000..bd438f7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/c2x-va-opt-1.c
@@ -0,0 +1,11 @@
+/* Test __VA_OPT__ and no "..." arguments in a call to a variable-arguments
+ macro accepted for C2X. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#define CALL(F, ...) F (7 __VA_OPT__(,) __VA_ARGS__)
+#define M(X, ...) X
+
+CALL (a);
+CALL (b, 1);
+M (x);
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c
index 7e94052..2887cb1 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c
@@ -1,7 +1,7 @@
/* Test BTF generation for enums. */
/* { dg-do compile } */
-/* { dg-options "-O0 -gbtf -dA" } */
+/* { dg-options "-O0 -gbtf -fno-short-enums -dA" } */
/* { dg-final { scan-assembler-times "\[\t \]0x6000004\[\t \]+\[^\n\]*btt_info" 1 } } */
/* { dg-final { scan-assembler-times "\[\t \]0x86000003\[\t \]+\[^\n\]*btt_info" 1 } } */
diff --git a/gcc/testsuite/gcc.dg/dfp/c2x-constexpr-dfp-1.c b/gcc/testsuite/gcc.dg/dfp/c2x-constexpr-dfp-1.c
new file mode 100644
index 0000000..568f142
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/c2x-constexpr-dfp-1.c
@@ -0,0 +1,79 @@
+/* Test C2x constexpr. Valid code, compilation tests, DFP. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+constexpr _Decimal32 v1 = __DEC32_MIN__;
+constexpr _Decimal32 v2 = __DEC32_SUBNORMAL_MIN__;
+constexpr _Decimal32 v3 = -__DEC32_MAX__;
+constexpr _Decimal64 v4 = __DEC32_MIN__;
+constexpr _Decimal64 v5 = __DEC32_SUBNORMAL_MIN__;
+constexpr _Decimal64 v6 = -__DEC32_MAX__;
+constexpr _Decimal64 v7 = __DEC64_MIN__;
+constexpr _Decimal64 v8 = __DEC64_SUBNORMAL_MIN__;
+constexpr _Decimal64 v9 = -__DEC64_MAX__;
+constexpr _Decimal128 v10 = __DEC32_MIN__;
+constexpr _Decimal128 v11 = __DEC32_SUBNORMAL_MIN__;
+constexpr _Decimal128 v12 = -__DEC32_MAX__;
+constexpr _Decimal128 v13 = __DEC64_MIN__;
+constexpr _Decimal128 v14 = __DEC64_SUBNORMAL_MIN__;
+constexpr _Decimal128 v15 = -__DEC64_MAX__;
+constexpr _Decimal128 v16 = __DEC128_MIN__;
+constexpr _Decimal128 v17 = __DEC128_SUBNORMAL_MIN__;
+constexpr _Decimal128 v18 = -__DEC128_MAX__;
+constexpr _Decimal32 v19 = 1234567L;
+constexpr _Decimal32 v20 = -123456700000LL;
+constexpr _Decimal64 v21 = 1234567890123456LL;
+constexpr _Decimal64 v22 = -123456789012345600LL;
+constexpr _Decimal128 v23 = (unsigned long long) -1;
+constexpr _Decimal32 v24 = 1e-101DL;
+constexpr _Decimal64 v25 = 1e-398DL;
+constexpr _Decimal32 v26 = __builtin_infd128 ();
+constexpr _Decimal128 v27 = __builtin_infd32 ();
+constexpr _Decimal64 v28 = __builtin_nand128 ("");
+constexpr _Decimal128 v29 = __builtin_nand32 ("");
+constexpr _Decimal32 v30 = __builtin_nansd32 ("");
+constexpr _Decimal64 v31 = __builtin_nansd64 ("");
+constexpr _Decimal128 v32 = __builtin_nansd128 ("");
+constexpr _Decimal32 v33 = {};
+constexpr _Decimal64 v34 = {};
+constexpr _Decimal128 v35 = {};
+
+void
+f0 ()
+{
+ (constexpr _Decimal32) { __DEC32_MIN__ };
+ (constexpr _Decimal32) { __DEC32_SUBNORMAL_MIN__ };
+ (constexpr _Decimal32) { -__DEC32_MAX__ };
+ (constexpr _Decimal64) { __DEC32_MIN__ };
+ (constexpr _Decimal64) { __DEC32_SUBNORMAL_MIN__ };
+ (constexpr _Decimal64) { -__DEC32_MAX__ };
+ (constexpr _Decimal64) { __DEC64_MIN__ };
+ (constexpr _Decimal64) { __DEC64_SUBNORMAL_MIN__ };
+ (constexpr _Decimal64) { -__DEC64_MAX__ };
+ (constexpr _Decimal128) { __DEC32_MIN__ };
+ (constexpr _Decimal128) { __DEC32_SUBNORMAL_MIN__ };
+ (constexpr _Decimal128) { -__DEC32_MAX__ };
+ (constexpr _Decimal128) { __DEC64_MIN__ };
+ (constexpr _Decimal128) { __DEC64_SUBNORMAL_MIN__ };
+ (constexpr _Decimal128) { -__DEC64_MAX__ };
+ (constexpr _Decimal128) { __DEC128_MIN__ };
+ (constexpr _Decimal128) { __DEC128_SUBNORMAL_MIN__ };
+ (constexpr _Decimal128) { -__DEC128_MAX__ };
+ (constexpr _Decimal32) { 1234567L };
+ (constexpr _Decimal32) { -123456700000LL };
+ (constexpr _Decimal64) { 1234567890123456LL };
+ (constexpr _Decimal64) { -123456789012345600LL };
+ (constexpr _Decimal128) { (unsigned long long) -1 };
+ (constexpr _Decimal32) { 1e-101DL };
+ (constexpr _Decimal64) { 1e-398DL };
+ (constexpr _Decimal32) { __builtin_infd128 () };
+ (constexpr _Decimal128) { __builtin_infd32 () };
+ (constexpr _Decimal64) { __builtin_nand128 ("") };
+ (constexpr _Decimal128) { __builtin_nand32 ("") };
+ (constexpr _Decimal32) { __builtin_nansd32 ("") };
+ (constexpr _Decimal64) { __builtin_nansd64 ("") };
+ (constexpr _Decimal128) { __builtin_nansd128 ("") };
+ (constexpr _Decimal32) {};
+ (constexpr _Decimal64) {};
+ (constexpr _Decimal128) {};
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/c2x-constexpr-dfp-2.c b/gcc/testsuite/gcc.dg/dfp/c2x-constexpr-dfp-2.c
new file mode 100644
index 0000000..8b1ecf2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/c2x-constexpr-dfp-2.c
@@ -0,0 +1,48 @@
+/* Test C2x constexpr. Invalid code, compilation tests, DFP. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+/* Test conversions between binary and decimal. */
+constexpr _Decimal32 v1 = 0.0; /* { dg-error "'constexpr' initializer for a decimal floating-point type is of binary type" } */
+constexpr double v2 = 0.0DF; /* { dg-error "'constexpr' initializer for a binary floating-point type is of decimal type" } */
+
+/* A conversion from signaling NaN to quiet NaN in a different format is not
+ valid for constexpr. */
+constexpr _Decimal32 v3 = __builtin_nansd64 (""); /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr _Decimal32 v4 = __builtin_nansd128 (""); /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr _Decimal64 v5 = __builtin_nansd32 (""); /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr _Decimal64 v6 = __builtin_nansd128 (""); /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr _Decimal128 v7 = __builtin_nansd32 (""); /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr _Decimal128 v8 = __builtin_nansd64 (""); /* { dg-error "'constexpr' initializer not representable in type of object" } */
+
+/* Test out-of-range values, including integers. */
+constexpr _Decimal32 v9 = 12345678; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr _Decimal64 v10 = (unsigned long long) -1; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr _Decimal32 v11 = __DEC64_MIN__; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr _Decimal64 v12 = -__DEC128_MAX__; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr _Decimal64 v13 = 12345678901234567890.DL; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+
+/* Test cases where the value can be represented, but the quantum exponent
+ cannot. */
+constexpr _Decimal32 v14 = 0e-200DD; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr _Decimal32 v15 = 0e200DL; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+
+void
+f0 ()
+{
+ (constexpr _Decimal32) { 0.0 }; /* { dg-error "'constexpr' initializer for a decimal floating-point type is of binary type" } */
+ (constexpr double) { 0.0DF }; /* { dg-error "'constexpr' initializer for a binary floating-point type is of decimal type" } */
+ (constexpr _Decimal32) { __builtin_nansd64 ("") }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Decimal32) { __builtin_nansd128 ("") }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Decimal64) { __builtin_nansd32 ("") }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Decimal64) { __builtin_nansd128 ("") }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Decimal128) { __builtin_nansd32 ("") }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Decimal128) { __builtin_nansd64 ("") }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Decimal32) { 12345678 }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Decimal64) { (unsigned long long) -1 }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Decimal32) { __DEC64_MIN__ }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Decimal64) { -__DEC128_MAX__ }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Decimal64) { 12345678901234567890.DL }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Decimal32) { 0e-200DD }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+ (constexpr _Decimal32) { 0e200DL }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+}
diff --git a/gcc/testsuite/gcc.dg/gnu2x-auto-1.c b/gcc/testsuite/gcc.dg/gnu2x-auto-1.c
new file mode 100644
index 0000000..e0b9e86
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gnu2x-auto-1.c
@@ -0,0 +1,11 @@
+/* Test C2x auto. Invalid code with GNU extensions. */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu2x" } */
+
+void
+f ()
+{
+ /* Do not allow a non-definition declaration of a tag in the auto
+ initializer, to avoid it escaping an inner scope as shown here. */
+ auto x = ({ struct s; struct s *x = 0; x; }); /* { dg-error "declared in underspecified object initializer" } */
+}
diff --git a/gcc/testsuite/gcc.dg/gnu2x-constexpr-1.c b/gcc/testsuite/gcc.dg/gnu2x-constexpr-1.c
new file mode 100644
index 0000000..6078f08
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gnu2x-constexpr-1.c
@@ -0,0 +1,17 @@
+/* Test C2x constexpr. Valid code using GNU extensions, compilation tests. */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu2x" } */
+
+struct s { struct { int x, y; } x; };
+constexpr struct s v = { { 123, 150 } };
+int k;
+constexpr int a[200] = { [v.x.x ... v.x.y] = 7 };
+
+void
+f ()
+{
+ switch (k)
+ {
+ case v.x.x ... v.x.y: ;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/target-simd-clone-1.c b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-1.c
new file mode 100644
index 0000000..388dc2a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-1.c
@@ -0,0 +1,25 @@
+/* { dg-options "-fopenmp -O2" } */
+/* { dg-additional-options "-fopenmp-target-simd-clone=any -fdump-ipa-simdclone-details" } */
+
+/* Test that simd clones are generated for functions with "declare target". */
+
+#pragma omp declare target
+__attribute__ ((__noinline__)) int addit (int a, int b)
+{
+ return a + b;
+}
+#pragma omp end declare target
+
+void callit (int *a, int *b, int *c)
+{
+ int i;
+ #pragma omp for simd
+ for (i = 0; i < 16; i++)
+ c[i] = addit (a[i], b[i]);
+}
+
+/* Although addit has external linkage, we expect clones to be generated as
+ for a function with internal linkage. */
+
+/* { dg-final { scan-ipa-dump "Generated local clone _ZGV.*N.*_addit" "simdclone" { target x86_64-*-* } } } */
+/* { dg-final { scan-ipa-dump "Generated local clone _ZGV.*M.*_addit" "simdclone" { target x86_64-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/target-simd-clone-2.c b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-2.c
new file mode 100644
index 0000000..acdc241
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-2.c
@@ -0,0 +1,22 @@
+/* { dg-options "-fopenmp -O2" } */
+/* { dg-additional-options "-fdump-ipa-simdclone-details" } */
+
+/* Test that host simd clones are not generated for functions with
+ "declare target" by default at -O2. */
+
+#pragma omp declare target
+__attribute__ ((__noinline__)) int addit (int a, int b)
+{
+ return a + b;
+}
+#pragma omp end declare target
+
+void callit (int *a, int *b, int *c)
+{
+ int i;
+ #pragma omp for simd
+ for (i = 0; i < 16; i++)
+ c[i] = addit (a[i], b[i]);
+}
+
+/* { dg-final { scan-ipa-dump-not "Generated .* clone" "simdclone" { target x86_64-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/target-simd-clone-3.c b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-3.c
new file mode 100644
index 0000000..e90d49c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-3.c
@@ -0,0 +1,22 @@
+/* { dg-options "-fopenmp -O2" } */
+/* { dg-additional-options "-fopenmp-target-simd-clone=any -fdump-ipa-simdclone-details" } */
+
+/* Test that host simd clones are not generated for functions with the nohost
+ "declare target" clause. */
+
+__attribute__ ((__noinline__)) int addit (int a, int b)
+{
+ return a + b;
+}
+#pragma omp declare target to(addit) device_type(nohost)
+
+void callit (int *a, int *b, int *c)
+{
+ int i;
+ #pragma omp for simd
+ for (i = 0; i < 16; i++)
+ c[i] = addit (a[i], b[i]);
+}
+
+/* { dg-final { scan-ipa-dump "device doesn't match" "simdclone" { target x86_64-*-* } } } */
+/* { dg-final { scan-ipa-dump-not "Generated .* clone" "simdclone" { target x86_64-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/target-simd-clone-4.c b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-4.c
new file mode 100644
index 0000000..141097b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-4.c
@@ -0,0 +1,26 @@
+/* { dg-options "-fopenmp -O2" } */
+/* { dg-additional-options "-fopenmp-target-simd-clone=any -fdump-ipa-simdclone-details" } */
+
+/* Test that simd clones are not generated for functions with
+ "declare target" but that write memory in the body. */
+
+extern int save;
+
+#pragma omp declare target
+__attribute__ ((__noinline__)) int addit(int a, int b)
+{
+ save = a;
+ return a + b;
+}
+#pragma omp end declare target
+
+void callit (int *a, int *b, int *c)
+{
+ int i;
+ #pragma omp for simd
+ for (i = 0; i < 16; i++)
+ c[i] = addit (a[i], b[i]);
+}
+
+/* { dg-final { scan-ipa-dump "body includes memory write" "simdclone" { target x86_64-*-* } } } */
+/* { dg-final { scan-ipa-dump-not "Generated .* clone" "simdclone" { target x86_64-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/target-simd-clone-5.c b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-5.c
new file mode 100644
index 0000000..93f9774
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-5.c
@@ -0,0 +1,28 @@
+/* { dg-options "-fopenmp -O2" } */
+/* { dg-additional-options "-fopenmp-target-simd-clone=any -fdump-ipa-simdclone-details" } */
+
+/* Test that simd clones are not generated for functions with
+ "declare target" but unsuitable arguments. */
+
+struct s {
+ int a;
+ int b;
+};
+
+#pragma omp declare target
+__attribute__ ((__noinline__)) int addit (struct s x)
+{
+ return x.a + x.b;
+}
+#pragma omp end declare target
+
+void callit (struct s *ss, int *c)
+{
+ int i;
+ #pragma omp for simd
+ for (i = 0; i < 16; i++)
+ c[i] = addit (ss[i]);
+}
+
+/* { dg-final { scan-ipa-dump "argument type fails sniff test" "simdclone" { target x86_64-*-* } } } */
+/* { dg-final { scan-ipa-dump-not "Generated .* clone" "simdclone" { target x86_64-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/target-simd-clone-6.c b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-6.c
new file mode 100644
index 0000000..4c34967
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-6.c
@@ -0,0 +1,27 @@
+/* { dg-options "-fopenmp -O2" } */
+/* { dg-additional-options "-fopenmp-target-simd-clone=any -fdump-ipa-simdclone-details" } */
+
+/* Test that simd clones are not generated for functions with
+ "declare target" but that call possibly side-effecting functions
+ in the body. */
+
+extern int f (int);
+
+#pragma omp declare target
+__attribute__ ((__noinline__)) int addit(int a, int b)
+{
+ return f(a) + b;
+}
+#pragma omp end declare target
+
+void callit (int *a, int *b, int *c)
+{
+ int i;
+ #pragma omp for simd
+ for (i = 0; i < 16; i++)
+ c[i] = addit (a[i], b[i]);
+}
+
+/* { dg-final { scan-ipa-dump "body contains unsafe function call" "simdclone" { target x86_64-*-* } } } */
+/* { dg-final { scan-ipa-dump-not "Generated .* clone" "simdclone" { target x86_64-*-* } } } */
+
diff --git a/gcc/testsuite/gcc.dg/gomp/target-simd-clone-7.c b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-7.c
new file mode 100644
index 0000000..78c60f9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-7.c
@@ -0,0 +1,15 @@
+/* { dg-options "-fopenmp -O2" } */
+/* { dg-additional-options "-fopenmp-target-simd-clone=any -fdump-ipa-simdclone-details" } */
+
+/* Test that simd clones are not generated for functions with
+ "declare target" that have no callers in the same compilation unit. */
+
+#pragma omp declare target
+__attribute__ ((__noinline__)) int addit (int a, int b)
+{
+ return a + b;
+}
+#pragma omp end declare target
+
+/* { dg-final { scan-ipa-dump "function is not used" "simdclone" { target x86_64-*-* } } } */
+/* { dg-final { scan-ipa-dump-not "Generated .* clone" "simdclone" { target x86_64-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/target-simd-clone-8.c b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-8.c
new file mode 100644
index 0000000..561766c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/target-simd-clone-8.c
@@ -0,0 +1,25 @@
+/* { dg-options "-fopenmp -O2" } */
+/* { dg-additional-options "-fopenmp-target-simd-clone=any -fdump-ipa-simdclone-details" } */
+
+/* Test that simd clones are not generated for functions with
+ "declare target" but that read volatile memory in the body. */
+
+extern volatile int save;
+
+#pragma omp declare target
+__attribute__ ((__noinline__)) int addit(int a, int b)
+{
+ return save + a + b;
+}
+#pragma omp end declare target
+
+void callit (int *a, int *b, int *c)
+{
+ int i;
+ #pragma omp for simd
+ for (i = 0; i < 16; i++)
+ c[i] = addit (a[i], b[i]);
+}
+
+/* { dg-final { scan-ipa-dump "body includes volatile op" "simdclone" { target x86_64-*-* } } } */
+/* { dg-final { scan-ipa-dump-not "Generated .* clone" "simdclone" { target x86_64-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/guality/guality.exp b/gcc/testsuite/gcc.dg/guality/guality.exp
index ba87132..075bebe 100644
--- a/gcc/testsuite/gcc.dg/guality/guality.exp
+++ b/gcc/testsuite/gcc.dg/guality/guality.exp
@@ -8,6 +8,10 @@ if { [istarget *-*-darwin*] } {
return
}
+if { [istarget hppa*-*-hpux*] } {
+ return
+}
+
if { [istarget "powerpc-ibm-aix*"] } {
set torture_execute_xfail "powerpc-ibm-aix*"
return
diff --git a/gcc/testsuite/gcc.dg/guality/param-6.c b/gcc/testsuite/gcc.dg/guality/param-6.c
new file mode 100644
index 0000000..9c4ba5c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/param-6.c
@@ -0,0 +1,20 @@
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-g" } */
+
+void __attribute__((noipa)) bar (void *p)
+{}
+
+void __attribute__((noipa)) foo (int i)
+{
+ void *p = __builtin_alloca (i);
+
+ asm volatile ("" : : : "ebx");
+
+ bar (p); /* { dg-final { gdb-test . "i" "5" } } */
+}
+
+int main (void)
+{
+ foo (5);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/iinline-attr.c b/gcc/testsuite/gcc.dg/ipa/iinline-attr.c
index 6309afe..4b9e857 100644
--- a/gcc/testsuite/gcc.dg/ipa/iinline-attr.c
+++ b/gcc/testsuite/gcc.dg/ipa/iinline-attr.c
@@ -23,5 +23,5 @@ int test (void)
return 0;
}
-/* { dg-final { scan-ipa-dump "hooray\[^\\n\]*inline copy in test" "inline" { xfail visium-*-* } } } */
-/* Missing back-end support for attribute __optimize__ on Visium. */
+/* { dg-final { scan-ipa-dump "hooray\[^\\n\]*inline copy in test" "inline" { xfail sparc*-*-* visium-*-* } } } */
+/* Missing back-end support for attribute __optimize__ on SPARC and Visium. */
diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-18.c b/gcc/testsuite/gcc.dg/loop-unswitch-18.c
new file mode 100644
index 0000000..91dc201
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/loop-unswitch-18.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-unswitch-optimized" } */
+
+void bar();
+void foo (int x, int n, int m)
+{
+ for (int i = 0; i < n; ++i)
+ for (int j = 0; j < m; ++j)
+ if (x)
+ bar ();
+}
+
+/* { dg-final { scan-tree-dump "unswitching outer loop" "unswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
index 2a8bf11..e494315 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
@@ -4,10 +4,12 @@
*/
/* { dg-options "-g" } */
+#define INCLUDE_MEMORY
#include "gcc-plugin.h"
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "make-unique.h"
#include "diagnostic.h"
#include "tree.h"
#include "gimple.h"
@@ -87,7 +89,8 @@ public:
return 0;
}
- location_t fixup_location (location_t loc) const final override
+ location_t fixup_location (location_t loc,
+ bool) const final override
{
/* Ideally we'd check for specific macros here, and only
resolve certain macros. */
@@ -309,9 +312,9 @@ gil_state_machine::check_for_pyobject_in_call (sm_context *sm_ctxt,
if (type_based_on_pyobject_p (type))
{
sm_ctxt->warn (node, call, NULL_TREE,
- new fncall_without_gil (*this, call,
- callee_fndecl,
- i));
+ make_unique<fncall_without_gil> (*this, call,
+ callee_fndecl,
+ i));
sm_ctxt->set_global_state (m_stop);
}
}
@@ -337,7 +340,7 @@ gil_state_machine::on_stmt (sm_context *sm_ctxt,
if (global_state == m_released_gil)
{
sm_ctxt->warn (node, stmt, NULL_TREE,
- new double_save_thread (*this, call));
+ make_unique<double_save_thread> (*this, call));
sm_ctxt->set_global_state (m_stop);
}
else
@@ -393,7 +396,7 @@ gil_state_machine::check_for_pyobject_usage_without_gil (sm_context *sm_ctxt,
if (type_based_on_pyobject_p (type))
{
sm_ctxt->warn (node, stmt, NULL_TREE,
- new pyobject_usage_without_gil (*this, op));
+ make_unique<pyobject_usage_without_gil> (*this, op));
sm_ctxt->set_global_state (m_stop);
}
}
@@ -408,7 +411,8 @@ gil_analyzer_init_cb (void *gcc_data, void */*user_data*/)
LOG_SCOPE (iface->get_logger ());
if (0)
inform (input_location, "got here: gil_analyzer_init_cb");
- iface->register_state_machine (new gil_state_machine (iface->get_logger ()));
+ iface->register_state_machine
+ (make_unique<gil_state_machine> (iface->get_logger ()));
}
} // namespace ana
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.c b/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.c
index 6ec08bf..57bccf4 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.c
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.c
@@ -1,6 +1,7 @@
/* Proof-of-concept of a -fanalyzer plugin for the Linux kernel. */
/* { dg-options "-g" } */
+#define INCLUDE_MEMORY
#include "gcc-plugin.h"
#include "config.h"
#include "system.h"
@@ -40,7 +41,9 @@
#include "analyzer/program-point.h"
#include "analyzer/store.h"
#include "analyzer/region-model.h"
+#include "analyzer/call-details.h"
#include "analyzer/call-info.h"
+#include "make-unique.h"
int plugin_is_GPL_compatible;
@@ -56,6 +59,11 @@ class copy_across_boundary_fn : public known_function
virtual bool untrusted_source_p () const = 0;
virtual bool untrusted_destination_p () const = 0;
+ bool matches_call_types_p (const call_details &cd) const final override
+ {
+ return cd.num_args () == 3;
+ }
+
void impl_call_pre (const call_details &cd) const final override
{
region_model_manager *mgr = cd.get_manager ();
@@ -94,7 +102,7 @@ class copy_across_boundary_fn : public known_function
if (ctxt)
{
/* Bifurcate state, creating a "failure" out-edge. */
- ctxt->bifurcate (new copy_failure (cd));
+ ctxt->bifurcate (make_unique<copy_failure> (cd));
/* The "unbifurcated" state is the "success" case. */
copy_success success (cd,
@@ -208,10 +216,11 @@ kernel_analyzer_init_cb (void *gcc_data, void */*user_data*/)
LOG_SCOPE (iface->get_logger ());
if (0)
inform (input_location, "got here: kernel_analyzer_init_cb");
- iface->register_known_function ("copy_from_user",
- new known_function_copy_from_user ());
+ iface->register_known_function
+ ("copy_from_user",
+ make_unique<known_function_copy_from_user> ());
iface->register_known_function ("copy_to_user",
- new known_function_copy_to_user ());
+ make_unique<known_function_copy_to_user> ());
}
} // namespace ana
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.c b/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.c
index 060a308..de887db 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.c
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.c
@@ -1,6 +1,7 @@
/* Proof-of-concept of a -fanalyzer plugin to handle known functions. */
/* { dg-options "-g" } */
+#define INCLUDE_MEMORY
#include "gcc-plugin.h"
#include "config.h"
#include "system.h"
@@ -40,7 +41,9 @@
#include "analyzer/program-point.h"
#include "analyzer/store.h"
#include "analyzer/region-model.h"
+#include "analyzer/call-details.h"
#include "analyzer/call-info.h"
+#include "make-unique.h"
int plugin_is_GPL_compatible;
@@ -53,6 +56,11 @@ namespace ana {
class known_function_returns_42 : public known_function
{
public:
+ bool matches_call_types_p (const call_details &) const final override
+ {
+ return true;
+ }
+
void impl_call_pre (const call_details &cd) const final override
{
if (cd.get_lhs_type ())
@@ -113,6 +121,11 @@ public:
}
};
+ bool matches_call_types_p (const call_details &cd) const
+ {
+ return cd.num_args () == 3;
+ }
+
void impl_call_pre (const call_details &cd) const final override
{
region_model_manager *mgr = cd.get_manager ();
@@ -151,7 +164,7 @@ public:
if (cd.get_ctxt ())
{
/* Bifurcate state, creating a "failure" out-edge. */
- cd.get_ctxt ()->bifurcate (new copy_failure (cd));
+ cd.get_ctxt ()->bifurcate (make_unique<copy_failure> (cd));
/* The "unbifurcated" state is the "success" case. */
copy_success success (cd,
@@ -173,9 +186,10 @@ known_fn_analyzer_init_cb (void *gcc_data, void */*user_data*/)
if (0)
inform (input_location, "got here: known_fn_analyzer_init_cb");
iface->register_known_function ("returns_42",
- new known_function_returns_42 ());
- iface->register_known_function ("attempt_to_copy",
- new known_function_attempt_to_copy ());
+ make_unique<known_function_returns_42> ());
+ iface->register_known_function
+ ("attempt_to_copy",
+ make_unique<known_function_attempt_to_copy> ());
}
} // namespace ana
diff --git a/gcc/testsuite/gcc.dg/pr102650.c b/gcc/testsuite/gcc.dg/pr102650.c
new file mode 100644
index 0000000..16ae840
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr102650.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-vrp1" } */
+
+static int a = 2, b, c, d;
+void foo(void);
+int main() {
+ short e;
+ int f = -1;
+ if (b)
+ c = 0;
+ c || (f = 2);
+ for (; d < 1; d++)
+ e = f + a;
+ if (!e)
+ foo();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "foo" "vrp1" } } */
+
diff --git a/gcc/testsuite/gcc.dg/pr103356-1.c b/gcc/testsuite/gcc.dg/pr103356-1.c
new file mode 100644
index 0000000..61d0b81
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr103356-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-forwprop1" } */
+
+_Bool foo (_Bool a, _Bool b)
+{
+ return a == (!b);
+}
+
+/* { dg-final { scan-tree-dump "\[ab\]_\[0-9\]+\\(D\\) \\\^ \[ba\]_\[0-9\]+\\(D\\)" "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/pr104530.c b/gcc/testsuite/gcc.dg/pr104530.c
new file mode 100644
index 0000000..1ec1015
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr104530.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void foo(void);
+
+static int a, *b = &a, c, d = 1;
+
+int main() {
+ c = 0 == b;
+ a = *b;
+ if (c % d)
+ for (; d; --d)
+ foo();
+ b = 0;
+}
+
+
+/* { dg-final { scan-tree-dump-not "foo" "evrp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/pr105676.c b/gcc/testsuite/gcc.dg/pr105676.c
new file mode 100644
index 0000000..077fc18
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr105676.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wsuggest-attribute=pure" } */
+
+__attribute__((const))
+extern int do_expensive_calculation(void);
+
+__attribute__((const))
+int getval(void) /* { dg-bogus "candidate for attribute" } */
+{
+ static int cache = -1;
+ if (cache == -1)
+ cache = do_expensive_calculation();
+ return cache;
+}
diff --git a/gcc/testsuite/gcc.dg/pr106719.c b/gcc/testsuite/gcc.dg/pr106719.c
new file mode 100644
index 0000000..772bd4a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr106719.c
@@ -0,0 +1,13 @@
+/* PR debug/106719 */
+/* { dg-do compile { target sync_char_short } } */
+/* { dg-options "-O2 -fcompare-debug" } */
+
+extern short int esi, easi[2];
+
+void
+foo (void)
+{
+ short int *psi = &easi[1];
+ __atomic_nand_fetch (psi, esi, 0);
+ psi = &easi[1];
+}
diff --git a/gcc/testsuite/gcc.dg/pr107127.c b/gcc/testsuite/gcc.dg/pr107127.c
new file mode 100644
index 0000000..d25cced
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107127.c
@@ -0,0 +1,13 @@
+/* PR c/107127 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+int *v;
+
+_Complex double
+foo (_Complex double a, double b, double c)
+{
+ return v[0] / ((((c * (0 - 0 / a + 699.0 + 7.05 - 286.0 - +-4.65 + 1.57 + 0) * 0.1 - 3.28 + 4.22 + 0.1)) * b + 5.06)
+ * 1.23 * 8.0 * 12.0 * 16.0 * 2.0 * 2.0 * 0.25 * 0.125 * 18.2 * -15.25 * 0.0001
+ * 42.0 * 0.012 - 8.45 + 0 + 88.0 + 6.96 + 867.0 + 9.10 - 7.04 * -1.0);
+}
diff --git a/gcc/testsuite/gcc.dg/pr107389.c b/gcc/testsuite/gcc.dg/pr107389.c
new file mode 100644
index 0000000..deb6338
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107389.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-optimized-alias" } */
+
+unsigned foo (void *p)
+{
+ unsigned i;
+ __builtin_memcpy (&i, __builtin_assume_aligned (p, 4), sizeof (unsigned));
+ return i;
+}
+
+/* Even when not optimizing we should have alignment info on the temporary
+ feeding the memcpy. */
+/* { dg-final { scan-tree-dump "ALIGN = 4" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr107505.c b/gcc/testsuite/gcc.dg/pr107505.c
new file mode 100644
index 0000000..01270eac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107505.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-guess-branch-probability" } */
+
+int n;
+
+void
+bar (void);
+
+__attribute__ ((noinline, returns_twice)) int
+zero (void)
+{
+ return 0;
+}
+
+void
+foo (void)
+{
+ int a = zero ();
+
+ for (n = 0; n < 2; ++n)
+ {
+ }
+
+ if (a)
+ bar ();
+}
diff --git a/gcc/testsuite/gcc.dg/pr107523.c b/gcc/testsuite/gcc.dg/pr107523.c
new file mode 100644
index 0000000..1e5ed46
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107523.c
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-options "-O2 " } */
+
+int a, b = 1;
+unsigned int c = 1;
+int main() {
+ int d = 1, f;
+ if (b)
+ d = 0;
+ a = -1;
+ b = ~d ^ 465984011;
+ L1:;
+ if (b < 2)
+ f = b;
+ b = f;
+ if (f <= a) {
+ int g = -(a && 1), h = g - f && a, i = ~(c / f) && 1 % (a | h);
+ if (c) {
+ g = f;
+ if (i || (g && (g > -465984012)))
+ goto L2;
+ }
+ c = g | f / c;
+ }
+ if (0)
+ L2:
+ a = 0;
+ if (a <= c)
+ goto L1;
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr107547.c b/gcc/testsuite/gcc.dg/pr107547.c
new file mode 100644
index 0000000..c6992c8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107547.c
@@ -0,0 +1,40 @@
+/* PR tree-optimization/107547 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int x;
+
+void
+foo (void)
+{
+#define TEST(...) \
+ __builtin_acos##__VA_ARGS__ (x); \
+ __builtin_asin##__VA_ARGS__ (x); \
+ __builtin_acosh##__VA_ARGS__ (x); \
+ __builtin_atanh##__VA_ARGS__ (x); \
+ __builtin_cosh##__VA_ARGS__ (x); \
+ __builtin_sinh##__VA_ARGS__ (x); \
+ __builtin_log##__VA_ARGS__ (x); \
+ __builtin_log2##__VA_ARGS__ (x); \
+ __builtin_log10##__VA_ARGS__ (x); \
+ __builtin_log1p##__VA_ARGS__ (x); \
+ __builtin_exp##__VA_ARGS__ (x); \
+ __builtin_expm1##__VA_ARGS__ (x); \
+ __builtin_exp2##__VA_ARGS__ (x); \
+ __builtin_sqrt##__VA_ARGS__ (x)
+ TEST (f);
+ TEST ();
+ TEST (l);
+#ifdef __FLT16_MAX__
+ TEST (f16);
+#endif
+#ifdef __FLT32_MAX__
+ TEST (f32);
+#endif
+#ifdef __FLT64_MAX__
+ TEST (f64);
+#endif
+#ifdef __FLT128_MAX__
+ TEST (f128);
+#endif
+}
diff --git a/gcc/testsuite/gcc.dg/pr107554.c b/gcc/testsuite/gcc.dg/pr107554.c
new file mode 100644
index 0000000..61ef2bc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107554.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O -foptimize-strlen" } */
+
+#define ELEMS 0x40000000
+
+int a[ELEMS];
+int b[ELEMS];
+
+int main()
+{
+ __builtin_memcpy(a, b, ELEMS*sizeof(int));
+}
diff --git a/gcc/testsuite/gcc.dg/pr107585.c b/gcc/testsuite/gcc.dg/pr107585.c
new file mode 100644
index 0000000..820e04b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107585.c
@@ -0,0 +1,13 @@
+/* PR target/107585 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef unsigned char __attribute__((__vector_size__ (16))) V;
+char c;
+void bar (int);
+
+void
+foo (void)
+{
+ bar (((V) (c <= (V){127}))[2]);
+}
diff --git a/gcc/testsuite/gcc.dg/pr107618.c b/gcc/testsuite/gcc.dg/pr107618.c
new file mode 100644
index 0000000..9e73cc1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107618.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-Og" } */
+
+void a(void) __attribute__((__warning__("")));
+int main(void)
+{
+ unsigned long b = __builtin_object_size(0, 0);
+ if (__builtin_expect(b < 1, 0))
+ a(); /* { dg-bogus "warning" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr107686.c b/gcc/testsuite/gcc.dg/pr107686.c
new file mode 100644
index 0000000..2378103
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107686.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { dfp && longlong64 } } } */
+/* { dg-options "-O" } */
+/* { dg-additional-options "-mavx2" { target x86_64-*-* i?86-*-* } } */
+
+typedef _Decimal64 __attribute__((__vector_size__ (64))) D;
+typedef __INT32_TYPE__ __attribute__((__vector_size__ (32))) U;
+typedef __INT64_TYPE__ __attribute__((__vector_size__ (64))) V;
+
+U u;
+D d;
+
+void
+foo (void)
+{
+ d = d < (D) __builtin_convertvector (u, V);
+}
diff --git a/gcc/testsuite/gcc.dg/pr107787.c b/gcc/testsuite/gcc.dg/pr107787.c
new file mode 100644
index 0000000..922dbff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107787.c
@@ -0,0 +1,13 @@
+/* PR driver/107787 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Werror=array-bounds=1" } */
+/* { dg-message "some warnings being treated as errors" "" {target "*-*-*"} 0 } */
+
+int a[10]; /* { dg-note "while referencing" } */
+
+int* f(void) {
+
+ a[-1] = 0; /* { dg-error "is below array bounds" } */
+
+ return a;
+}
diff --git a/gcc/testsuite/gcc.dg/pr107805-1.c b/gcc/testsuite/gcc.dg/pr107805-1.c
new file mode 100644
index 0000000..559b6a5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107805-1.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+typedef int t;
+typedef struct { double a; int b; } t; /* { dg-error "conflicting types" } */
+t x; /* No warning here. */
+
diff --git a/gcc/testsuite/gcc.dg/pr107805-2.c b/gcc/testsuite/gcc.dg/pr107805-2.c
new file mode 100644
index 0000000..fa5fa4c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107805-2.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+typedef int t;
+typedef struct { double a; int b; } t; /* { dg-error "conflicting types" } */
+t char x; /* { dg-error "two or more data types" } */
diff --git a/gcc/testsuite/gcc.dg/pr107937.c b/gcc/testsuite/gcc.dg/pr107937.c
new file mode 100644
index 0000000..524850b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107937.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized" } */
+
+int _setjmp(int);
+int regs, vm_debug_engine_vp_0, vm_debug_engine_vp_2;
+
+void
+vm_dispatch_hook();
+
+
+void
+vm_debug_engine() {
+ int fp;
+ void *jump_table = &&l_nop;
+l_nop:
+ if (__builtin_expect(vm_debug_engine_vp_2, 0))
+ vm_dispatch_hook();
+ if (_setjmp(regs)) {
+ fp = fp;
+ vm_dispatch_hook();
+ goto *jump_table;
+ }
+ vm_debug_engine_vp_0 = fp;
+}
diff --git a/gcc/testsuite/gcc.dg/pr107967-1.c b/gcc/testsuite/gcc.dg/pr107967-1.c
new file mode 100644
index 0000000..d099231
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107967-1.c
@@ -0,0 +1,35 @@
+/* PR tree-optimization/107967 */
+/* { dg-do compile { target float64 } } */
+/* { dg-options "-O2 -frounding-math -fno-trapping-math -fdump-tree-optimized" } */
+/* { dg-add-options float64 } */
+/* { dg-final { scan-tree-dump-not "return\[ \t]\*-?Inf;" "optimized" } } */
+
+_Float64
+foo (void)
+{
+ const _Float64 huge = 1.0e+300f64;
+ return huge * huge;
+}
+
+_Float64
+bar (void)
+{
+ const _Float64 huge = 1.0e+300f64;
+ return huge * -huge;
+}
+
+_Float64
+baz (void)
+{
+ const _Float64 a = 0x1.fffffffffffffp+1023f64;
+ const _Float64 b = 0x1.fffffffffffffp+970f64;
+ return a + b;
+}
+
+_Float64
+qux (void)
+{
+ const _Float64 a = 0x1.fffffffffffffp+1023f64;
+ const _Float64 b = 0x1.fffffffffffffp+969f64;
+ return a + b;
+}
diff --git a/gcc/testsuite/gcc.dg/pr107967-2.c b/gcc/testsuite/gcc.dg/pr107967-2.c
new file mode 100644
index 0000000..554000c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107967-2.c
@@ -0,0 +1,35 @@
+/* PR tree-optimization/107967 */
+/* { dg-do compile { target float64 } } */
+/* { dg-options "-O2 -fno-rounding-math -fno-trapping-math -fdump-tree-optimized" } */
+/* { dg-add-options float64 } */
+/* { dg-final { scan-tree-dump-times "return\[ \t]\*-?Inf;" 3 "optimized" } } */
+
+_Float64
+foo (void)
+{
+ const _Float64 huge = 1.0e+300f64;
+ return huge * huge;
+}
+
+_Float64
+bar (void)
+{
+ const _Float64 huge = 1.0e+300f64;
+ return huge * -huge;
+}
+
+_Float64
+baz (void)
+{
+ const _Float64 a = 0x1.fffffffffffffp+1023f64;
+ const _Float64 b = 0x1.fffffffffffffp+970f64;
+ return a + b;
+}
+
+_Float64
+qux (void)
+{
+ const _Float64 a = 0x1.fffffffffffffp+1023f64;
+ const _Float64 b = 0x1.fffffffffffffp+969f64;
+ return a + b;
+}
diff --git a/gcc/testsuite/gcc.dg/pr107967-3.c b/gcc/testsuite/gcc.dg/pr107967-3.c
new file mode 100644
index 0000000..9b36a1f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107967-3.c
@@ -0,0 +1,53 @@
+/* PR tree-optimization/107967 */
+/* { dg-do compile { target float64 } } */
+/* { dg-options "-O2 -fno-rounding-math -fno-trapping-math -fdump-tree-optimized" } */
+/* { dg-add-options float64 } */
+/* { dg-final { scan-tree-dump-times "return\[ \t]\*-?Inf;" 3 "optimized" } } */
+
+_Float64
+foo (_Float64 x)
+{
+ if (x >= 1.0e+300f64)
+ ;
+ else
+ __builtin_unreachable ();
+ return x * x;
+}
+
+_Float64
+bar (_Float64 x)
+{
+ if (x >= 1.0e+300f64)
+ ;
+ else
+ __builtin_unreachable ();
+ return x * -x;
+}
+
+_Float64
+baz (_Float64 a, _Float64 b)
+{
+ if (a >= 0x1.fffffffffffffp+1023f64)
+ ;
+ else
+ __builtin_unreachable ();
+ if (b >= 0x1.p+972f64)
+ ;
+ else
+ __builtin_unreachable ();
+ return a + b;
+}
+
+_Float64
+qux (_Float64 a, _Float64 b)
+{
+ if (a >= 0x1.fffffffffffffp+1023f64)
+ ;
+ else
+ __builtin_unreachable ();
+ if (b >= 0x1.fffffffffffffp+969f64)
+ ;
+ else
+ __builtin_unreachable ();
+ return a + b;
+}
diff --git a/gcc/testsuite/gcc.dg/pr107975.c b/gcc/testsuite/gcc.dg/pr107975.c
new file mode 100644
index 0000000..7710f6f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107975.c
@@ -0,0 +1,15 @@
+/* PR tree-optimization/107975 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-add-options ieee } */
+
+double
+foo (double x, double y)
+{
+ if (x == 42.0)
+ return 1.0;
+ double r = x * y;
+ if (!__builtin_isnan (r))
+ __builtin_unreachable ();
+ return r;
+}
diff --git a/gcc/testsuite/gcc.dg/pr25521.c b/gcc/testsuite/gcc.dg/pr25521.c
index 74fe2ae..63363a0 100644
--- a/gcc/testsuite/gcc.dg/pr25521.c
+++ b/gcc/testsuite/gcc.dg/pr25521.c
@@ -7,4 +7,4 @@
const volatile int foo = 30;
-/* { dg-final { scan-assembler "\\.rodata" } } */
+/* { dg-final { scan-assembler "\\.s\?rodata" } } */
diff --git a/gcc/testsuite/gcc.dg/pr77975.c b/gcc/testsuite/gcc.dg/pr77975.c
index 148cebd..a187ce2 100644
--- a/gcc/testsuite/gcc.dg/pr77975.c
+++ b/gcc/testsuite/gcc.dg/pr77975.c
@@ -7,10 +7,11 @@
unsigned int
foo (unsigned int *b)
{
- unsigned int a = 3;
+ unsigned int a = 8;
while (a)
{
- a >>= 1;
+ a += 5;
+ a &= 44;
*b += a;
}
return a;
@@ -21,10 +22,11 @@ foo (unsigned int *b)
unsigned int
bar (unsigned int *b)
{
- unsigned int a = 7;
+ unsigned int a = 3;
while (a)
{
- a >>= 1;
+ a += 5;
+ a &= 44;
*b += a;
}
return a;
diff --git a/gcc/testsuite/gcc.dg/pr93917.c b/gcc/testsuite/gcc.dg/pr93917.c
new file mode 100644
index 0000000..41d27fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr93917.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
+
+void f3(int n);
+
+void f1(int n)
+{
+ if(n<0)
+ __builtin_unreachable();
+ f3(n);
+}
+
+void f2(int*n)
+{
+ if(*n<0)
+ __builtin_unreachable();
+ f3 (*n);
+}
+
+/* { dg-final { scan-tree-dump-times "Global Exported" 2 "vrp1" } } */
diff --git a/gcc/testsuite/gcc.dg/pr96542.c b/gcc/testsuite/gcc.dg/pr96542.c
index 5014f2a..0aad2e9 100644
--- a/gcc/testsuite/gcc.dg/pr96542.c
+++ b/gcc/testsuite/gcc.dg/pr96542.c
@@ -22,6 +22,6 @@ baz (unsigned int x)
return (-1U >> x) * 16;
}
-/* { dg-final { scan-tree-dump-times "254" 2 "evrp" } } */
+/* { dg-final { scan-tree-dump-times "return 254" 2 "evrp" } } */
/* { dg-final { scan-tree-dump "= PHI <32.*, 4294967280" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/redecl-19.c b/gcc/testsuite/gcc.dg/redecl-19.c
new file mode 100644
index 0000000..cc10685
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/redecl-19.c
@@ -0,0 +1,5 @@
+/* We used to ICE in the gimplifier, PR 106764 */
+/* { dg-do compile } */
+/* { dg-options "-w" } */
+(*a)(); // { dg-note "" }
+b(){a()} a; // { dg-error "" }
diff --git a/gcc/testsuite/gcc.dg/redecl-20.c b/gcc/testsuite/gcc.dg/redecl-20.c
new file mode 100644
index 0000000..07f5211
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/redecl-20.c
@@ -0,0 +1,9 @@
+/* We used to ICE in the gimplifier, PR 107307 */
+// { dg-do compile }
+// { dg-options "-w" }
+void f ()
+{
+ const struct { int a[1]; } b; // { dg-note "" }
+ int *c = b.a;
+ int *b; // { dg-error "" }
+}
diff --git a/gcc/testsuite/gcc.dg/redecl-21.c b/gcc/testsuite/gcc.dg/redecl-21.c
new file mode 100644
index 0000000..2f2a654
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/redecl-21.c
@@ -0,0 +1,9 @@
+/* We used to ICE in the gimplifier, PR 106765 */
+/* { dg-do compile } */
+/* { dg-options "-w" } */
+struct a {
+ int b
+} c() {
+ struct a a; // { dg-note "" }
+ a.b;
+ d a; // { dg-error "" }
diff --git a/gcc/testsuite/gcc.dg/redecl-22.c b/gcc/testsuite/gcc.dg/redecl-22.c
new file mode 100644
index 0000000..7758570f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/redecl-22.c
@@ -0,0 +1,9 @@
+/* We used to ICE in the gimplifier, PR 107705 */
+/* { dg-do compile } */
+/* { dg-options "-w" } */
+int f (void)
+{
+ int (*p) (void) = 0; // { dg-note "" }
+ return p ();
+ int p = 1; // { dg-error "" }
+}
diff --git a/gcc/testsuite/gcc.dg/redecl-23.c b/gcc/testsuite/gcc.dg/redecl-23.c
new file mode 100644
index 0000000..425721d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/redecl-23.c
@@ -0,0 +1,6 @@
+/* We used to ICE in the gimplifier, PR 106560. */
+/* { dg-do compile } */
+/* { dg-options "-w" } */
+void **a; /* { dg-note "" } */
+void b() { void **c = a; }
+a; /* { dg-error "" } */
diff --git a/gcc/testsuite/gcc.dg/redecl-24.c b/gcc/testsuite/gcc.dg/redecl-24.c
new file mode 100644
index 0000000..f0f7a72
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/redecl-24.c
@@ -0,0 +1,6 @@
+/* We used to ICE in the gimplifier, PR 106560 */
+/* { dg-do compile } */
+/* { dg-options "-w" } */
+void **a, **b; /* { dg-note "" } */
+c(){b = a;}
+a = /* { dg-error "" } */
diff --git a/gcc/testsuite/gcc.dg/redecl-25.c b/gcc/testsuite/gcc.dg/redecl-25.c
new file mode 100644
index 0000000..4232e19
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/redecl-25.c
@@ -0,0 +1,9 @@
+/* We used to ICE in the gimplifier, PR 106560 */
+/* { dg-do compile } */
+/* { dg-options "-w" } */
+void **a; /* { dg-note "" } */
+void b() {
+ void **c;
+ c = a /* { dg-error "" } */
+}
+a; /* { dg-error "" } */
diff --git a/gcc/testsuite/gcc.dg/signbit-2.c b/gcc/testsuite/gcc.dg/signbit-2.c
index 99a455b..1624225 100644
--- a/gcc/testsuite/gcc.dg/signbit-2.c
+++ b/gcc/testsuite/gcc.dg/signbit-2.c
@@ -1,5 +1,5 @@
-/* { dg-do assemble } */
-/* { dg-options "-O3 --save-temps -fdump-tree-optimized" } */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized" } */
/* This test does not work when the truth type does not match vector type. */
/* { dg-additional-options "-mno-avx512f" { target { i?86-*-* x86_64-*-* } } } */
@@ -21,6 +21,6 @@ void fun2(int32_t *x, int n)
}
/* Xfail amdgcn where vector truth type is not integer type. */
-/* { dg-final { scan-tree-dump {\s+>\s+\{ 0(, 0)+ \}} optimized { target vect_int xfail amdgcn-*-* } } } */
-/* { dg-final { scan-tree-dump {\s+>\s+0} optimized { target { ! vect_int } } } } */
+/* { dg-final { scan-tree-dump {\s+>\s+\{ 0(, 0)+ \}} optimized { target vect_shift xfail amdgcn-*-* } } } */
+/* { dg-final { scan-tree-dump {\s+>\s+0} optimized { target { ! vect_shift } } } } */
/* { dg-final { scan-tree-dump-not {\s+>>\s+31} optimized { xfail amdgcn-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-1.c b/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-1.c
index 0c7bf00..61cfa96 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-1.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-1.c
@@ -1,5 +1,5 @@
/* PR84407 */
-/* { dg-do run } */
+/* { dg-do run { xfail { arm-*-eabi* } } } */
/* { dg-require-effective-target fenv } */
/* { dg-require-effective-target hard_float } */
/* { dg-additional-options "-frounding-math -fexcess-precision=standard" } */
diff --git a/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-2.c b/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-2.c
index ac24b35..b32b28a 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-2.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-2.c
@@ -1,5 +1,5 @@
/* PR84407 */
-/* { dg-do run } */
+/* { dg-do run { xfail { arm-*-eabi* } } } */
/* { dg-require-effective-target fenv } */
/* { dg-require-effective-target hard_float } */
/* { dg-additional-options "-frounding-math" } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr107493.c b/gcc/testsuite/gcc.dg/torture/pr107493.c
new file mode 100644
index 0000000..b366921
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr107493.c
@@ -0,0 +1,13 @@
+/* { dg-do run { target int32plus } } */
+
+int a;
+int b(int c) { return c; }
+int main()
+{
+ a = -21;
+ for (; a <= 0; a = (unsigned short)(b(a + 2) + 8))
+ ;
+ if (a != 65525)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr107833.c b/gcc/testsuite/gcc.dg/torture/pr107833.c
new file mode 100644
index 0000000..0edf7c3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr107833.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+
+int a, b[1] = { 0 }, c, *d = b, e, *f, g;
+
+__attribute__((noipa)) int
+foo (const char *x)
+{
+ (void) x;
+ return 0;
+}
+
+int
+main ()
+{
+ for (int h = 0; a < 2; a++)
+ {
+ int i;
+ for (g = 0; g < 2; g++)
+ if (a < h)
+ {
+ e = i % 2;
+ c = *f;
+ }
+ for (h = 0; h < 3; h++)
+ {
+ if (d)
+ break;
+ i--;
+ foo ("0");
+ }
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr107935.c b/gcc/testsuite/gcc.dg/torture/pr107935.c
new file mode 100644
index 0000000..7817510
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr107935.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+int *a, **b;
+int main() {
+ int d = 0, *e = &d;
+ L:
+ *e = d;
+ if (a) {
+ int *g = e = *b;
+ if (!e)
+ __builtin_abort();
+ if (**b)
+ return 0;
+ *g = 1;
+ goto L;
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr108076.c b/gcc/testsuite/gcc.dg/torture/pr108076.c
new file mode 100644
index 0000000..ebe2e51
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr108076.c
@@ -0,0 +1,17 @@
+/* { dg-do link } */
+
+static void *j;
+int v, g;
+__attribute__((__leaf__)) int atoi (const char *);
+
+int
+main ()
+{
+ j = &&lab1;
+ &&lab2;
+ atoi ("42");
+lab1:
+lab2:
+ if (v)
+ goto *j;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr71462.c b/gcc/testsuite/gcc.dg/torture/pr71462.c
index 390b886..9965963 100644
--- a/gcc/testsuite/gcc.dg/torture/pr71462.c
+++ b/gcc/testsuite/gcc.dg/torture/pr71462.c
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-additional-options "-w" } */
short a;
long b;
diff --git a/gcc/testsuite/gcc.dg/tree-prof/pr108000.c b/gcc/testsuite/gcc.dg/tree-prof/pr108000.c
new file mode 100644
index 0000000..c59ea79
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/pr108000.c
@@ -0,0 +1,93 @@
+/* { dg-options "-O2" } */
+
+#include <stdlib.h>
+
+volatile int flag;
+const int array_size = 10;
+int* array;
+int iterations = 10000000;
+
+#define BAR(num) \
+int __attribute__((noinline)) \
+bar##num (int i, int j) \
+{ \
+ if (i == 0) \
+ return 2*num - 1; \
+ else \
+ return 2*num; \
+}
+
+BAR(1)
+BAR(2)
+BAR(3)
+BAR(4)
+BAR(5)
+BAR(6)
+BAR(7)
+BAR(8)
+BAR(9)
+BAR(10)
+BAR(11)
+BAR(12)
+BAR(13)
+BAR(14)
+BAR(15)
+BAR(16)
+BAR(17)
+BAR(18)
+BAR(19)
+
+int __attribute__((noinline))
+foo ()
+{
+ switch (flag)
+ {
+ case 1:
+ return bar1 (0, 0);
+ case 2:
+ return bar2 (0, 0);
+ case 3:
+ return bar3 (0, 0);
+ case 4:
+ return bar4 (0, 0);
+ case 5:
+ return bar5 (0, 0);
+ case 6:
+ return bar6 (0, 0);
+ case 7:
+ return bar7 (0, 0);
+ case 8:
+ return bar8 (0, 0);
+ case 9:
+ return bar9 (0, 0);
+ case 10:
+ return bar10 (0, 0);
+ case 11:
+ return bar11 (0, 0);
+ case 12:
+ return bar12 (0, 0);
+ case 13:
+ return bar13 (0, 0);
+ case 14:
+ return bar14 (0, 0);
+ case 15:
+ return bar15 (0, 0);
+ case 16:
+ return bar16 (0, 0);
+ case 17:
+ return bar17 (0, 0);
+ case 18:
+ return bar18 (0, 0);
+ default:
+ return bar19(0, 0);
+ }
+}
+
+int
+main ()
+{
+ flag = 0;
+ array = calloc(array_size, sizeof(int));
+ for (int i = 0, j = 0; i < iterations; ++i, j = (j + 1) % 10)
+ array[j] = foo ();
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030808-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030808-1.c
index 456f6f2..7d4a138 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20030808-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030808-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-cddce3" } */
+/* { dg-options "-O1 -fdump-tree-dce7" } */
extern void abort (void);
@@ -33,8 +33,8 @@ delete_dead_jumptables ()
/* There should be no loads of ->code. If any exist, then we failed to
optimize away all the IF statements and the statements feeding
their conditions. */
-/* { dg-final { scan-tree-dump-times "->code" 0 "cddce3"} } */
+/* { dg-final { scan-tree-dump-times "->code" 0 "dce7"} } */
/* There should be no IF statements. */
-/* { dg-final { scan-tree-dump-times "if " 0 "cddce3"} } */
+/* { dg-final { scan-tree-dump-times "if " 0 "dce7"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/branchless-cond.c b/gcc/testsuite/gcc.dg/tree-ssa/branchless-cond.c
new file mode 100644
index 0000000..68087ae
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/branchless-cond.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int f1(unsigned int x, unsigned int y, unsigned int z)
+{
+ return ((x & 1) == 0) ? y : z ^ y;
+}
+
+int f2(unsigned int x, unsigned int y, unsigned int z)
+{
+ return ((x & 1) != 0) ? z ^ y : y;
+}
+
+int f3(unsigned int x, unsigned int y, unsigned int z)
+{
+ return ((x & 1) == 0) ? y : z | y;
+}
+
+int f4(unsigned int x, unsigned int y, unsigned int z)
+{
+ return ((x & 1) != 0) ? z | y : y;
+}
+
+/* { dg-final { scan-tree-dump-times " -" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " & " 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "if" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-3.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-3.c
index 4aa68c6..bfdfba1 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-3.c
@@ -14,4 +14,4 @@ int foo(struct bar *x)
return 0;
}
-/* { dg-final { scan-tree-dump "Replaced .p_. < q_.. with .1." "forwprop1" } } */
+/* { dg-final { scan-tree-dump "return 1;" "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-34.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-34.c
index 41877e0..c2e5dfe 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-34.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-34.c
@@ -13,4 +13,4 @@ float summul(int n, float *arg1, float *arg2)
return res1;
}
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! { avr-*-* pru-*-* riscv*-*-* } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_masked_load } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loopclosedphi.c b/gcc/testsuite/gcc.dg/tree-ssa/loopclosedphi.c
index d71b757..0a8a417 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loopclosedphi.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loopclosedphi.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -fno-tree-ch -w -fdump-tree-loopdone-details" } */
+/* { dg-options "-O3 -fno-tree-ch -fno-unswitch-loops -w -fdump-tree-loopdone-details" } */
void
t6 (int qz, int wh)
@@ -18,4 +18,4 @@ t6 (int qz, int wh)
qz = jl * wh;
}
-/* { dg-final { scan-tree-dump-times "Replacing" 2 "loopdone"} } */
+/* { dg-final { scan-tree-dump-times "Replacing" 3 "loopdone"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount-max.c b/gcc/testsuite/gcc.dg/tree-ssa/popcount-max.c
new file mode 100644
index 0000000..ca7204c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount-max.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-loop-optimize -fdump-tree-optimized" } */
+
+#define PREC (__CHAR_BIT__)
+
+int count1 (unsigned char b) {
+ int c = 0;
+
+ while (b) {
+ b &= b - 1;
+ c++;
+ }
+ if (c <= PREC)
+ return 0;
+ else
+ return 34567;
+}
+
+int count2 (unsigned char b) {
+ int c = 0;
+
+ while (b) {
+ b &= b - 1;
+ c++;
+ }
+ if (c <= PREC - 1)
+ return 0;
+ else
+ return 76543;
+}
+
+/* { dg-final { scan-tree-dump-times "34567" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "76543" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107490.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107490.c
new file mode 100644
index 0000000..87c7f0a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107490.c
@@ -0,0 +1,28 @@
+// { dg-do compile }
+// { dg-options "-Os -fno-trapping-math -w" }
+
+extern void abort (void);
+
+#define MIN2(a,b) (((a)<(b)) ? (a) : (b))
+#define MAX2(a,b) (((a)>(b)) ? (a) : (b))
+
+double p[2] = { 4.f, 5.f };
+
+int main()
+{
+ long j;
+ double R, n, x;
+ n = 1.e300f;
+ x = -1.e300f;
+ for( j=0; j < 2; j++ )
+ {
+ x = MAX2(x,p[j]);
+ n = MIN2(n,p[j]);
+ }
+ R = x-n;
+
+ if( R < 0.1 )
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107541.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107541.c
new file mode 100644
index 0000000..9c89db5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107541.c
@@ -0,0 +1,18 @@
+// { dg-do run }
+// { dg-options "-O1" }
+
+unsigned char a = 1;
+char b, e;
+long long c;
+short d;
+int main() {
+ if (sizeof (short) != 2 || sizeof (int) != 4 || sizeof (long long) != 8)
+ return 0;
+ a = ~(1 && a);
+ c = ~((~a / 8 | -2) & 11007578330939886389LLU);
+ e = -c;
+ d = ~c / e;
+ if (d < 2000)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107699.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107699.c
new file mode 100644
index 0000000..4bf864d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107699.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-forwprop1" } */
+
+struct { int data[16]; } x;
+
+int foo (int n)
+{
+ int *p = x.data + n;
+ /* Should simplify this to n * 4 != 0. */
+ if ((void *)&x != (void *)p)
+ return 1;
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump " != 0" "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107732.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107732.c
new file mode 100644
index 0000000..b216f38
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107732.c
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-options "-O2" }
+
+double sqrt(double);
+double a, b, c;
+void d() {
+ for (;;) {
+ c = __builtin_fabs(a);
+ sqrt(c);
+ if (a)
+ a = b;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr55157.c b/gcc/testsuite/gcc.dg/tree-ssa/pr55157.c
new file mode 100644
index 0000000..bbdda45
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr55157.c
@@ -0,0 +1,19 @@
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-evrp" }
+
+void gg(void);
+int f(unsigned t)
+{
+ unsigned g = t*16;
+ if (g==0) return 1;
+ gg();
+ gg();
+ gg();
+ gg();
+ gg();
+ gg();
+ if (g<=4) return 1;
+ return 0;
+}
+
+// { dg-final { scan-tree-dump-times " if " 1 "evrp" } }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89317.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89317.c
new file mode 100644
index 0000000..0c8f2f5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89317.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-ccp1" } */
+
+struct b { int data[16]; };
+
+int foo (struct b *x)
+{
+ int *a = x->data;
+ int *b = ((int*)x) + 4;
+ return b - a;
+}
+
+int bar (struct b *x)
+{
+ int *a = x->data;
+ int *b = ((int*)x) + 4;
+ if (a != b)
+ return 1;
+ return 0;
+}
+
+int baz (struct b *x)
+{
+ int *a = x->data;
+ int *b = ((int*)x) + 4;
+ return (a != b);
+}
+
+/* { dg-final { scan-tree-dump "return 4;" "ccp1" } } */
+/* { dg-final { scan-tree-dump-times "return 1;" 2 "ccp1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-42.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-42.c
new file mode 100644
index 0000000..b4e5c0f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-42.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple -O -fdump-tree-ccp1" } */
+
+__GIMPLE (ssa,startwith("ccp")) int foo (int n)
+{
+ int i;
+ int j;
+
+ __BB(2):
+ i_1 = 0;
+ goto __BB3;
+
+ __BB(3):
+ i_2 = __PHI (__BB2: i_1, __BB3: i_4);
+ j_3 = i_2;
+ i_4 = i_2 + 1;
+ if (i_4 < n_5(D))
+ goto __BB3;
+ else
+ goto __BB4;
+
+ __BB(4):
+ return j_3;
+}
+
+/* { dg-final { scan-tree-dump "return i_2;" "ccp1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-101.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-101.c
new file mode 100644
index 0000000..c67f211
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-101.c
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1-details" } */
+
+int test1 (int i, int j)
+{
+ int k;
+ if (i != j)
+ k = i;
+ else
+ k = j;
+ return k;
+}
+
+int test2 (int i, int j)
+{
+ int k;
+ if (i != j)
+ k = j;
+ else
+ k = i;
+ return k;
+}
+
+int test3 (int i, int j)
+{
+ int k;
+ if (i == j)
+ k = j;
+ else
+ k = i;
+ return k;
+}
+
+int test4 (int i, int j)
+{
+ int k;
+ if (i == j)
+ k = i;
+ else
+ k = j;
+ return k;
+}
+
+/* We'd expect 4 hits but since we only keep one forwarder the
+ VN predication machinery cannot record something for the entry
+ block since it doesn't work on edges but on their source. */
+/* { dg-final { scan-tree-dump-times "equal on edge" 2 "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-18.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-18.c
index 421c78e..9ac0fc6e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-18.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-18.c
@@ -207,6 +207,9 @@ compute_on_bytes (uint8_t *in_data, int in_len, uint8_t *out_data, int out_len)
from bb 31 to bb 33"
When -m32, Power and X86 will sink 3 instructions, but arm ilp32 couldn't
sink due to ivopts chooses two IV candidates instead of one, which is
- expected, so this case is restricted to lp64 only so far. */
+ expected, so this case is restricted to lp64 only so far. This different
+ ivopts choice affects riscv64 as well, probably because it also lacks
+ base+index addressing modes, so the ip[len] address computation can't be
+ made from the IV computation above. */
- /* { dg-final { scan-tree-dump-times "Sunk statements: 4" 1 "sink2" { target lp64 } } } */
+ /* { dg-final { scan-tree-dump-times "Sunk statements: 4" 1 "sink2" { target lp64 xfail { riscv64-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-plus.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-plus.c
new file mode 100644
index 0000000..3739ea4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-plus.c
@@ -0,0 +1,21 @@
+// { dg-do compile }
+// { dg-options "-O2 -fno-tree-fre -fno-tree-dominator-opts -fno-thread-jumps -fdump-tree-vrp2" }
+
+double BG_SplineLength ()
+{
+ double lastPoint;
+ double i;
+
+ for (i = 0.01;i<=1;i+=0.1f)
+ if (!(i != 0.0))
+ {
+ lastPoint = i;
+ }
+ else
+ {
+ lastPoint = 2;
+ }
+ return lastPoint;
+}
+
+// { dg-final { scan-tree-dump-times "return 2\\.0e" 1 "vrp2" } }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-update.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-update.c
new file mode 100644
index 0000000..9e5da88
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-update.c
@@ -0,0 +1,21 @@
+/* { dg-options "-O2 -fdump-tree-vrp1 " } */
+
+/* Tests that calls to update_stmt by the folder will also update ranger's
+ cache value and produce the correct result for the builtin_constant_p
+ function. */
+
+void dead ();
+
+void foo( void *_thrdescr, int _result)
+{
+ const char *lossage = _result ? "constant string" : 0;
+
+ if (__builtin_expect (lossage != ((void *)0) , 0))
+ {
+ unsigned __message_length = __builtin_strlen (lossage);
+ if (! __builtin_constant_p (__message_length))
+ dead ();
+ }
+}
+
+/* { dg-final { scan-tree-dump-not "dead" "vrp1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp122.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp122.c
new file mode 100644
index 0000000..b2ddcda
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp122.c
@@ -0,0 +1,19 @@
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-evrp-details" }
+
+void gg(void);
+int f(unsigned t)
+{
+ unsigned g = t*16;
+ if (g==0) return 1;
+ gg();
+ gg();
+ gg();
+ gg();
+ gg();
+ gg();
+ if (g<=4) return 1;
+ return 0;
+}
+
+// { dg-final { scan-tree-dump "Global Exported: g_.* NONZERO 0x.*fff0" "evrp" } }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp123.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp123.c
new file mode 100644
index 0000000..1ad3caa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp123.c
@@ -0,0 +1,18 @@
+// { dg-options "-O1 -fdump-tree-dom3-raw" }
+
+extern int
+__attribute__((const))
+foo4b (int);
+
+int f4b (unsigned int r)
+{
+ if (foo4b (r))
+ r *= 8U;
+
+ if ((r / 2U) & 2U)
+ r += foo4b (r);
+
+ return r;
+}
+
+// { dg-final { scan-tree-dump-times {gimple_call <foo4b,} 1 dom3 } }
diff --git a/gcc/testsuite/gcc.dg/ubsan/pr107183.c b/gcc/testsuite/gcc.dg/ubsan/pr107183.c
new file mode 100644
index 0000000..e54a361
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/pr107183.c
@@ -0,0 +1,12 @@
+/* PR target/107183 */
+/* { dg-do compile } */
+/* { dg-options "-O -fsanitize=float-cast-overflow -fcompare-debug" } */
+
+long double a, b, c;
+
+int
+foo (void)
+{
+ unsigned u = b || __builtin_rintl (c);
+ return u + (unsigned) a;
+}
diff --git a/gcc/testsuite/gcc.dg/ubsan/pr107668.c b/gcc/testsuite/gcc.dg/ubsan/pr107668.c
new file mode 100644
index 0000000..e94d6cd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/pr107668.c
@@ -0,0 +1,12 @@
+/* PR tree-optimization/107668 */
+/* { dg-do compile } */
+/* { dg-options "-ffast-math -fno-associative-math -fsanitize=float-cast-overflow -fno-guess-branch-probability -fsigned-zeros" } */
+
+_Complex int c;
+int i;
+
+void
+foo (void)
+{
+ c /= (_Complex) i;
+}
diff --git a/gcc/testsuite/gcc.dg/uninit-pr107839.c b/gcc/testsuite/gcc.dg/uninit-pr107839.c
new file mode 100644
index 0000000..c2edcfa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/uninit-pr107839.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wuninitialized" } */
+
+int f (int);
+void g (int c)
+{
+ int v;
+ if (c)
+ v = f(0);
+ while (1)
+ if (c)
+ f(v + v); /* { dg-bogus "uninitialized" } */
+}
diff --git a/gcc/testsuite/gcc.dg/uninit-pr40635.c b/gcc/testsuite/gcc.dg/uninit-pr40635.c
new file mode 100644
index 0000000..fab7c3d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/uninit-pr40635.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized" } */
+
+struct hostent {
+ char **h_addr_list;
+};
+struct hostent *gethostbyname(const char*);
+int socket(void);
+int close(int);
+int connect(int, const char*);
+
+int get_tcp_socket(const char *machine)
+{
+ struct hostent *hp;
+ int s42, x;
+ char **addr;
+
+ hp = gethostbyname(machine);
+ x = 0;
+ for (addr = hp->h_addr_list; *addr; addr++)
+ {
+ s42 = socket();
+ if (s42 < 0)
+ return -1;
+ x = connect(s42, *addr);
+ if (x == 0)
+ break;
+ close(s42);
+ }
+ if (x < 0)
+ return -1;
+ return s42; /* { dg-warning "uninitialized" } */
+}
diff --git a/gcc/testsuite/gcc.dg/uninit-pred-9_b.c b/gcc/testsuite/gcc.dg/uninit-pred-9_b.c
index 53c4a53..c8f427b 100644
--- a/gcc/testsuite/gcc.dg/uninit-pred-9_b.c
+++ b/gcc/testsuite/gcc.dg/uninit-pred-9_b.c
@@ -17,7 +17,7 @@ int foo (int n, int l, int m, int r)
if (l > 100)
if ( (n <= 9) && (m < 100) && (r < 19) )
- blah(v); /* { dg-bogus "uninitialized" "bogus warning" { xfail powerpc64*-*-* cris-*-* } } */
+ blah(v); /* { dg-bogus "uninitialized" "bogus warning" { xfail powerpc64*-*-* cris-*-* riscv*-*-* } } */
if ( (n <= 8) && (m < 99) && (r < 19) )
blah(v); /* { dg-bogus "uninitialized" "pr101674" { xfail mmix-*-* } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-div-bitmask-1.c b/gcc/testsuite/gcc.dg/vect/vect-div-bitmask-1.c
new file mode 100644
index 0000000..472cd71
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-div-bitmask-1.c
@@ -0,0 +1,25 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdint.h>
+#include "tree-vect.h"
+
+#define N 50
+#define TYPE uint8_t
+
+__attribute__((noipa, noinline, optimize("O1")))
+void fun1(TYPE* restrict pixel, TYPE level, int n)
+{
+ for (int i = 0; i < n; i+=1)
+ pixel[i] = (pixel[i] * level) / 0xff;
+}
+
+__attribute__((noipa, noinline, optimize("O3")))
+void fun2(TYPE* restrict pixel, TYPE level, int n)
+{
+ for (int i = 0; i < n; i+=1)
+ pixel[i] = (pixel[i] * level) / 0xff;
+}
+
+#include "vect-div-bitmask.h"
+
+/* { dg-final { scan-tree-dump-not "vect_recog_divmod_pattern: detected" "vect" { target aarch64*-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-div-bitmask-2.c b/gcc/testsuite/gcc.dg/vect/vect-div-bitmask-2.c
new file mode 100644
index 0000000..e904a71
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-div-bitmask-2.c
@@ -0,0 +1,25 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdint.h>
+#include "tree-vect.h"
+
+#define N 50
+#define TYPE uint16_t
+
+__attribute__((noipa, noinline, optimize("O1")))
+void fun1(TYPE* restrict pixel, TYPE level, int n)
+{
+ for (int i = 0; i < n; i+=1)
+ pixel[i] = (pixel[i] * level) / 0xffffU;
+}
+
+__attribute__((noipa, noinline, optimize("O3")))
+void fun2(TYPE* restrict pixel, TYPE level, int n)
+{
+ for (int i = 0; i < n; i+=1)
+ pixel[i] = (pixel[i] * level) / 0xffffU;
+}
+
+#include "vect-div-bitmask.h"
+
+/* { dg-final { scan-tree-dump-not "vect_recog_divmod_pattern: detected" "vect" { target aarch64*-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-div-bitmask-3.c b/gcc/testsuite/gcc.dg/vect/vect-div-bitmask-3.c
new file mode 100644
index 0000000..a1418eb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-div-bitmask-3.c
@@ -0,0 +1,26 @@
+/* { dg-require-effective-target vect_int } */
+/* { dg-additional-options "-fno-vect-cost-model" { target aarch64*-*-* } } */
+
+#include <stdint.h>
+#include "tree-vect.h"
+
+#define N 50
+#define TYPE uint32_t
+
+__attribute__((noipa, noinline, optimize("O1")))
+void fun1(TYPE* restrict pixel, TYPE level, int n)
+{
+ for (int i = 0; i < n; i+=1)
+ pixel[i] = (pixel[i] * (uint64_t)level) / 0xffffffffUL;
+}
+
+__attribute__((noipa, noinline, optimize("O3")))
+void fun2(TYPE* restrict pixel, TYPE level, int n)
+{
+ for (int i = 0; i < n; i+=1)
+ pixel[i] = (pixel[i] * (uint64_t)level) / 0xffffffffUL;
+}
+
+#include "vect-div-bitmask.h"
+
+/* { dg-final { scan-tree-dump-not "vect_recog_divmod_pattern: detected" "vect" { target aarch64*-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-div-bitmask.h b/gcc/testsuite/gcc.dg/vect/vect-div-bitmask.h
new file mode 100644
index 0000000..29a1673
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-div-bitmask.h
@@ -0,0 +1,43 @@
+#include <stdio.h>
+
+#ifndef N
+#define N 65
+#endif
+
+#ifndef TYPE
+#define TYPE uint32_t
+#endif
+
+#ifndef DEBUG
+#define DEBUG 0
+#endif
+
+#define BASE ((TYPE) -1 < 0 ? -126 : 4)
+
+int main ()
+{
+ TYPE a[N];
+ TYPE b[N];
+
+ for (int i = 0; i < N; ++i)
+ {
+ a[i] = BASE + i * 13;
+ b[i] = BASE + i * 13;
+ if (DEBUG)
+ printf ("%d: 0x%x\n", i, a[i]);
+ }
+
+ fun1 (a, N / 2, N);
+ fun2 (b, N / 2, N);
+
+ for (int i = 0; i < N; ++i)
+ {
+ if (DEBUG)
+ printf ("%d = 0x%x == 0x%x\n", i, a[i], b[i]);
+
+ if (a[i] != b[i])
+ __builtin_abort ();
+ }
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.misc-tests/gcov.exp b/gcc/testsuite/gcc.misc-tests/gcov.exp
index b8e9661..bc8e2c9 100644
--- a/gcc/testsuite/gcc.misc-tests/gcov.exp
+++ b/gcc/testsuite/gcc.misc-tests/gcov.exp
@@ -24,9 +24,9 @@ global GCC_UNDER_TEST
# For now find gcov in the same directory as $GCC_UNDER_TEST.
if { ![is_remote host] && [string match "*/*" [lindex $GCC_UNDER_TEST 0]] } {
- set GCOV [file dirname [lindex $GCC_UNDER_TEST 0]]/[transform gcov]
+ set GCOV [file dirname [lindex $GCC_UNDER_TEST 0]]/[gcc-transform-out-of-tree gcov]
} else {
- set GCOV [transform gcov]
+ set GCOV [gcc-transform-out-of-tree gcov]
}
# Initialize harness.
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_17.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_17.c
index 22dc462..3c45f71 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_17.c
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_17.c
@@ -32,6 +32,10 @@ struct z b = { 9.0dd, 10.0dd, 11.0dd, 12.0dd };
ANON(struct z, a, D1)
ANON(struct z, b, STACK)
ANON(int , 5, W0)
+#ifndef __AAPCS64_BIG_ENDIAN__
ANON(_Decimal32, f1, STACK+32) /* Note: no promotion to _Decimal64. */
+#else
+ ANON(_Decimal32, f1, STACK+36) /* Note: no promotion to _Decimal64. */
+#endif
LAST_ANON(_Decimal64, 0.5dd, STACK+40)
#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/acle/bti_def.c b/gcc/testsuite/gcc.target/aarch64/acle/bti_def.c
new file mode 100644
index 0000000..db94769
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/acle/bti_def.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+#pragma GCC target "arch=armv8.5-a"
+#ifndef __ARM_FEATURE_BTI
+#error "__ARM_FEATURE_BTI is not defined but should be!"
+#endif
+
+void
+foo (void) {}
+
diff --git a/gcc/testsuite/gcc.target/aarch64/acle/pauth_def.c b/gcc/testsuite/gcc.target/aarch64/acle/pauth_def.c
new file mode 100644
index 0000000..400a0f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/acle/pauth_def.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+#pragma GCC target "+pauth"
+#ifndef __ARM_FEATURE_PAUTH
+#error "__ARM_FEATURE_PAUTH is not defined but should be!"
+#endif
+
+void
+foo (void) {}
+
diff --git a/gcc/testsuite/gcc.target/aarch64/cssc_1.c b/gcc/testsuite/gcc.target/aarch64/cssc_1.c
new file mode 100644
index 0000000..eecd00b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cssc_1.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "--save-temps -O1" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <stdint.h>
+
+#pragma GCC target "+cssc"
+
+/*
+** absw:
+** abs w0, w0
+** ret
+*/
+
+int32_t
+absw (int32_t a)
+{
+ return __builtin_abs (a);
+}
+
+/*
+** absx:
+** abs x0, x0
+** ret
+*/
+
+int64_t
+absx (int64_t a)
+{
+ return __builtin_labs (a);
+}
+
diff --git a/gcc/testsuite/gcc.target/aarch64/cssc_2.c b/gcc/testsuite/gcc.target/aarch64/cssc_2.c
new file mode 100644
index 0000000..1637d29
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cssc_2.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "--save-temps -O1" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <stdint.h>
+
+#pragma GCC target "+cssc"
+
+/*
+** cntw:
+** cnt w0, w0
+** ret
+*/
+
+int32_t
+cntw (int32_t a)
+{
+ return __builtin_popcount (a);
+}
+
+/*
+** cntx:
+** cnt x0, x0
+** ret
+*/
+
+int64_t
+cntx (int64_t a)
+{
+ return __builtin_popcountll (a);
+}
+
diff --git a/gcc/testsuite/gcc.target/aarch64/cssc_3.c b/gcc/testsuite/gcc.target/aarch64/cssc_3.c
new file mode 100644
index 0000000..8965256
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cssc_3.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "--save-temps -O1" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <stdint.h>
+
+#pragma GCC target "+cssc"
+
+/*
+** ctzw:
+** ctz w0, w0
+** ret
+*/
+
+int32_t
+ctzw (int32_t a)
+{
+ return __builtin_ctz (a);
+}
+
+/*
+** ctzx:
+** ctz x0, x0
+** ret
+*/
+
+int64_t
+ctzx (int64_t a)
+{
+ return __builtin_ctzll (a);
+}
+
diff --git a/gcc/testsuite/gcc.target/aarch64/cssc_4.c b/gcc/testsuite/gcc.target/aarch64/cssc_4.c
new file mode 100644
index 0000000..34ccd0e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cssc_4.c
@@ -0,0 +1,107 @@
+/* { dg-do compile } */
+/* { dg-additional-options "--save-temps -O1" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <stdint.h>
+
+#pragma GCC target "+cssc"
+
+#define MIN(X, Y) ((X) > (Y) ? (Y) : (X))
+#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
+
+/*
+** uminw:
+** umin w0, w[01], w[01]
+** ret
+*/
+
+uint32_t
+uminw (uint32_t a, uint32_t b)
+{
+ return MIN (a, b);
+}
+
+/*
+** uminx:
+** umin x0, x[01], x[01]
+** ret
+*/
+
+uint64_t
+uminx (uint64_t a, uint64_t b)
+{
+ return MIN (a, b);
+}
+
+/*
+** sminw:
+** smin w0, w[01], w[01]
+** ret
+*/
+
+int32_t
+sminw (int32_t a, int32_t b)
+{
+ return MIN (a, b);
+}
+
+/*
+** sminx:
+** smin x0, x[01], x[01]
+** ret
+*/
+
+int64_t
+sminx (int64_t a, int64_t b)
+{
+ return MIN (a, b);
+}
+
+/*
+** umaxw:
+** umax w0, w[01], w[01]
+** ret
+*/
+
+uint32_t
+umaxw (uint32_t a, uint32_t b)
+{
+ return MAX (a, b);
+}
+
+/*
+** umaxx:
+** umax x0, x[01], x[01]
+** ret
+*/
+
+uint64_t
+umaxx (uint64_t a, uint64_t b)
+{
+ return MAX (a, b);
+}
+
+/*
+** smaxw:
+** smax w0, w[01], w[01]
+** ret
+*/
+
+int32_t
+smaxw (int32_t a, int32_t b)
+{
+ return MAX (a, b);
+}
+
+/*
+** smaxx:
+** smax x0, x[01], x[01]
+** ret
+*/
+
+int64_t
+smaxx (int64_t a, int64_t b)
+{
+ return MAX (a, b);
+}
+
diff --git a/gcc/testsuite/gcc.target/aarch64/cssc_5.c b/gcc/testsuite/gcc.target/aarch64/cssc_5.c
new file mode 100644
index 0000000..5149519
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cssc_5.c
@@ -0,0 +1,154 @@
+/* { dg-do compile } */
+/* { dg-additional-options "--save-temps -O1" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <stdint.h>
+
+#pragma GCC target "+cssc"
+
+#define MIN(X, Y) ((X) > (Y) ? (Y) : (X))
+#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
+
+#define FUNC(T, OP, IMM) \
+T \
+T##_##OP##_##IMM (T a) \
+{ \
+ return OP (a, IMM); \
+} \
+
+#define FUNCNEG(T, OP, IMM) \
+T \
+T##_##OP##_m##IMM (T a) \
+{ \
+ return OP (a, - (IMM)); \
+} \
+
+/*
+** uint32_t_MIN_255:
+** umin w0, w0, 255
+** ret
+*/
+
+FUNC (uint32_t, MIN, 255)
+
+/*
+** uint64_t_MIN_255:
+** umin x0, x0, 255
+** ret
+*/
+
+FUNC (uint64_t, MIN, 255)
+
+/*
+** uint32_t_MAX_255:
+** umax w0, w0, 255
+** ret
+*/
+
+FUNC (uint32_t, MAX, 255)
+
+
+/*
+** uint64_t_MAX_255:
+** umax x0, x0, 255
+** ret
+*/
+
+FUNC (uint64_t, MAX, 255)
+
+/*
+** int32_t_MIN_m128:
+** smin w0, w0, -128
+** ret
+*/
+
+FUNCNEG (int32_t, MIN, 128)
+
+/*
+** int32_t_MIN_127:
+** smin w0, w0, 127
+** ret
+*/
+
+FUNC (int32_t, MIN, 127)
+
+/*
+** int64_t_MIN_m128:
+** smin x0, x0, -128
+** ret
+*/
+
+FUNCNEG (int64_t, MIN, 128)
+
+/*
+** int64_t_MIN_127:
+** smin x0, x0, 127
+** ret
+*/
+
+FUNC (int64_t, MIN, 127)
+
+/*
+** int32_t_MAX_m128:
+** smax w0, w0, -128
+** ret
+*/
+
+FUNCNEG (int32_t, MAX, 128)
+
+/*
+** int32_t_MAX_127:
+** smax w0, w0, 127
+** ret
+*/
+
+FUNC (int32_t, MAX, 127)
+
+/*
+** int64_t_MAX_m128:
+** smax x0, x0, -128
+** ret
+*/
+
+FUNCNEG (int64_t, MAX, 128)
+
+/*
+** int64_t_MAX_127:
+** smax x0, x0, 127
+** ret
+*/
+
+FUNC (int64_t, MAX, 127)
+
+/*
+** int32_t_MIN_0:
+** smin w0, w0, 0
+** ret
+*/
+
+FUNC (int32_t, MIN, 0)
+
+/*
+** int64_t_MIN_0:
+** smin x0, x0, 0
+** ret
+*/
+
+FUNC (int64_t, MIN, 0)
+
+/*
+** int32_t_MAX_0:
+** smax w0, w0, 0
+** ret
+*/
+
+FUNC (int32_t, MAX, 0)
+
+/*
+** int64_t_MAX_0:
+** smax x0, x0, 0
+** ret
+*/
+
+FUNC (int64_t, MAX, 0)
+
diff --git a/gcc/testsuite/gcc.target/aarch64/div-by-bitmask.c b/gcc/testsuite/gcc.target/aarch64/div-by-bitmask.c
new file mode 100644
index 0000000..2a53579
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/div-by-bitmask.c
@@ -0,0 +1,61 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O3 -std=c99" } */
+/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */
+
+#include <stdint.h>
+
+#pragma GCC target "+nosve"
+
+/*
+** draw_bitmap1:
+** ...
+** addhn v[0-9]+.8b, v[0-9]+.8h, v[0-9]+.8h
+** addhn v[0-9]+.8b, v[0-9]+.8h, v[0-9]+.8h
+** uaddw v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8b
+** uaddw v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8b
+** uzp2 v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b
+** ...
+*/
+void draw_bitmap1(uint8_t* restrict pixel, uint8_t level, int n)
+{
+ for (int i = 0; i < (n & -16); i+=1)
+ pixel[i] = (pixel[i] * level) / 0xff;
+}
+
+void draw_bitmap2(uint8_t* restrict pixel, uint8_t level, int n)
+{
+ for (int i = 0; i < (n & -16); i+=1)
+ pixel[i] = (pixel[i] * level) / 0xfe;
+}
+
+/*
+** draw_bitmap3:
+** ...
+** addhn v[0-9]+.4h, v[0-9]+.4s, v[0-9]+.4s
+** addhn v[0-9]+.4h, v[0-9]+.4s, v[0-9]+.4s
+** uaddw v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4h
+** uaddw v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4h
+** uzp2 v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h
+** ...
+*/
+void draw_bitmap3(uint16_t* restrict pixel, uint16_t level, int n)
+{
+ for (int i = 0; i < (n & -16); i+=1)
+ pixel[i] = (pixel[i] * level) / 0xffffU;
+}
+
+/*
+** draw_bitmap4:
+** ...
+** addhn v[0-9]+.2s, v[0-9]+.2d, v[0-9]+.2d
+** addhn v[0-9]+.2s, v[0-9]+.2d, v[0-9]+.2d
+** uaddw v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2s
+** uaddw v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2s
+** uzp2 v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
+** ...
+*/
+void draw_bitmap4(uint32_t* restrict pixel, uint32_t level, int n)
+{
+ for (int i = 0; i < (n & -16); i+=1)
+ pixel[i] = (pixel[i] * (uint64_t)level) / 0xffffffffUL;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/if-compare_1.c b/gcc/testsuite/gcc.target/aarch64/if-compare_1.c
new file mode 100644
index 0000000..53bbd77
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/if-compare_1.c
@@ -0,0 +1,47 @@
+/* { dg-do run } */
+/* { dg-additional-options "-O -save-temps" } */
+/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */
+
+extern void abort ();
+
+/*
+**zoo1:
+** cmp w0, w1
+** csel w0, w2, w3, lt
+** and w0, w0, 1
+** ret
+*/
+__attribute((noipa, noinline))
+int zoo1 (int a, int b, int c, int d)
+{
+ return ((a < b) & c) | ((a >= b) & d);
+}
+
+/*
+**zoo2:
+** cmp w0, w1
+** csel w0, w2, w3, lt
+** ret
+*/
+__attribute((noipa, noinline))
+int zoo2 (int a, int b, int c, int d)
+{
+ return (-(a < b) & c) | (-(a >= b) & d);
+}
+
+int main ()
+{
+ if (zoo1 (-3, 3, 5, 8) != 1)
+ abort ();
+
+ if (zoo1 (3, -3, 5, 8) != 0)
+ abort ();
+
+ if (zoo2 (-3, 3, 5, 8) != 5)
+ abort ();
+
+ if (zoo2 (3, -3, 5, 8) != 8)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/if-compare_2.c b/gcc/testsuite/gcc.target/aarch64/if-compare_2.c
new file mode 100644
index 0000000..14988ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/if-compare_2.c
@@ -0,0 +1,96 @@
+/* { dg-do run } */
+/* { dg-additional-options "-O3 -std=c99 -save-temps" } */
+/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */
+
+#pragma GCC target "+nosve"
+
+#include <string.h>
+
+typedef int v4si __attribute__ ((vector_size (16)));
+
+/*
+**foo1:
+** cmgt v0.4s, v1.4s, v0.4s
+** bsl v0.16b, v2.16b, v3.16b
+** ret
+*/
+v4si foo1 (v4si a, v4si b, v4si c, v4si d) {
+ return ((a < b) & c) | ((a >= b) & d);
+}
+
+/*
+**foo2:
+** cmgt v0.4s, v1.4s, v0.4s
+** bsl v0.16b, v3.16b, v2.16b
+** ret
+*/
+v4si foo2 (v4si a, v4si b, v4si c, v4si d) {
+ return (~(a < b) & c) | (~(a >= b) & d);
+}
+
+
+/**
+**bar1:
+**...
+** cmge v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
+** bsl v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b
+** and v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b
+**...
+*/
+void bar1 (int * restrict a, int * restrict b, int * restrict c,
+ int * restrict d, int * restrict res, int n)
+{
+ for (int i = 0; i < (n & -4); i++)
+ res[i] = ((a[i] < b[i]) & c[i]) | ((a[i] >= b[i]) & d[i]);
+}
+
+/**
+**bar2:
+**...
+** cmge v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
+** bsl v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b
+**...
+*/
+void bar2 (int * restrict a, int * restrict b, int * restrict c,
+ int * restrict d, int * restrict res, int n)
+{
+ for (int i = 0; i < (n & -4); i++)
+ res[i] = (-(a[i] < b[i]) & c[i]) | (-(a[i] >= b[i]) & d[i]);
+}
+
+extern void abort ();
+
+int main ()
+{
+
+ v4si a = { -3, -3, -3, -3 };
+ v4si b = { 3, 3, 3, 3 };
+ v4si c = { 5, 5, 5, 5 };
+ v4si d = { 8, 8, 8, 8 };
+
+ v4si res1 = foo1 (a, b, c, d);
+ if (memcmp (&res1, &c, 16UL) != 0)
+ abort ();
+
+ v4si res2 = foo2 (a, b, c, d);
+ if (memcmp (&res2, &d, 16UL) != 0)
+ abort ();
+
+ int ar[4] = { -3, -3, -3, -3 };
+ int br[4] = { 3, 3, 3, 3 };
+ int cr[4] = { 5, 5, 5, 5 };
+ int dr[4] = { 8, 8, 8, 8 };
+
+ int exp1[4] = { 1, 1, 1, 1 };
+ int res3[4];
+ bar1 ((int*)&ar, (int*)&br, (int*)&cr, (int*)&dr, (int*)&res3, 4);
+ if (memcmp (&res3, &exp1, 16UL) != 0)
+ abort ();
+
+ int res4[4];
+ bar2 ((int*)&ar, (int*)&br, (int*)&cr, (int*)&dr, (int*)&res4, 4);
+ if (memcmp (&res4, &cr, 16UL) != 0)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/interleave-init-1.c b/gcc/testsuite/gcc.target/aarch64/interleave-init-1.c
new file mode 100644
index 0000000..ee77504
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/interleave-init-1.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <arm_neon.h>
+
+/*
+** foo:
+** ...
+** dup v[0-9]+\.8h, w[0-9]+
+** dup v[0-9]+\.8h, w[0-9]+
+** zip1 v[0-9]+\.8h, v[0-9]+\.8h, v[0-9]+\.8h
+** ...
+** ret
+*/
+
+int16x8_t foo(int16_t x, int y)
+{
+ int16x8_t v = (int16x8_t) {x, y, x, y, x, y, x, y};
+ return v;
+}
+
+/*
+** foo2:
+** ...
+** dup v[0-9]+\.8h, w[0-9]+
+** movi v[0-9]+\.8h, 0x1
+** zip1 v[0-9]+\.8h, v[0-9]+\.8h, v[0-9]+\.8h
+** ...
+** ret
+*/
+
+int16x8_t foo2(int16_t x)
+{
+ int16x8_t v = (int16x8_t) {x, 1, x, 1, x, 1, x, 1};
+ return v;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/ldapr-sext.c b/gcc/testsuite/gcc.target/aarch64/ldapr-sext.c
new file mode 100644
index 0000000..f57c09d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/ldapr-sext.c
@@ -0,0 +1,67 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -std=c99" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+#include <stdatomic.h>
+
+#pragma GCC target "arch=armv8.4-a"
+
+atomic_ullong u64;
+atomic_llong s64;
+atomic_uint u32;
+atomic_int s32;
+atomic_ushort u16;
+atomic_short s16;
+atomic_uchar u8;
+atomic_schar s8;
+
+#define TEST(name, ldsize, rettype) \
+rettype \
+test_##name (void) \
+{ \
+ return atomic_load_explicit (&ldsize, memory_order_acquire); \
+}
+
+/*
+**test_s8_s64:
+**...
+** ldapursb x0, \[x[0-9]+\]
+** ret
+*/
+
+TEST(s8_s64, s8, long long)
+
+/*
+**test_s16_s64:
+**...
+** ldapursh x0, \[x[0-9]+\]
+** ret
+*/
+
+TEST(s16_s64, s16, long long)
+
+/*
+**test_s32_s64:
+**...
+** ldapursw x0, \[x[0-9]+\]
+** ret
+*/
+
+TEST(s32_s64, s32, long long)
+
+/*
+**test_s8_s32:
+**...
+** ldapursb w0, \[x[0-9]+\]
+** ret
+*/
+
+TEST(s8_s32, s8, int)
+
+/*
+**test_s16_s32:
+**...
+** ldapursh w0, \[x[0-9]+\]
+** ret
+*/
+
+TEST(s16_s32, s16, int)
diff --git a/gcc/testsuite/gcc.target/aarch64/ldapr-zext.c b/gcc/testsuite/gcc.target/aarch64/ldapr-zext.c
new file mode 100644
index 0000000..6f448ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/ldapr-zext.c
@@ -0,0 +1,67 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -std=c99" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+#include <stdatomic.h>
+
+#pragma GCC target "+rcpc"
+
+atomic_ullong u64;
+atomic_llong s64;
+atomic_uint u32;
+atomic_int s32;
+atomic_ushort u16;
+atomic_short s16;
+atomic_uchar u8;
+atomic_schar s8;
+
+#define TEST(name, ldsize, rettype) \
+rettype \
+test_##name (void) \
+{ \
+ return atomic_load_explicit (&ldsize, memory_order_acquire); \
+}
+
+/*
+**test_u8_u64:
+**...
+** ldaprb w0, \[x[0-9]+\]
+** ret
+*/
+
+TEST(u8_u64, u8, unsigned long long)
+
+/*
+**test_u16_u64:
+**...
+** ldaprh w0, \[x[0-9]+\]
+** ret
+*/
+
+TEST(u16_u64, u16, unsigned long long)
+
+/*
+**test_u32_u64:
+**...
+** ldapr w0, \[x[0-9]+\]
+** ret
+*/
+
+TEST(u32_u64, u32, unsigned long long)
+
+/*
+**test_u8_u32:
+**...
+** ldaprb w0, \[x[0-9]+\]
+** ret
+*/
+
+TEST(u8_u32, u8, unsigned)
+
+/*
+**test_u16_u32:
+**...
+** ldaprh w0, \[x[0-9]+\]
+** ret
+*/
+TEST(u16_u32, u16, unsigned)
+
diff --git a/gcc/testsuite/gcc.target/aarch64/ldapr.c b/gcc/testsuite/gcc.target/aarch64/ldapr.c
new file mode 100644
index 0000000..21f6464
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/ldapr.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -std=c99" } */
+#include <stdatomic.h>
+
+#pragma GCC target "+rcpc"
+atomic_ullong u64;
+atomic_llong s64;
+atomic_uint u32;
+atomic_int s32;
+atomic_ushort u16;
+atomic_short s16;
+atomic_uchar u8;
+atomic_schar s8;
+
+#define TEST(size, rettype) \
+rettype \
+test_##size (void) \
+{ \
+ return atomic_load_explicit (&size, memory_order_acquire); \
+} \
+
+TEST(u64, unsigned long long)
+TEST(s64, long long)
+TEST(u32, unsigned int)
+TEST(s32, int)
+TEST(u16, unsigned short)
+TEST(s16, short)
+TEST(u8, unsigned char)
+TEST(s8, signed char)
+
+/* { dg-final { scan-assembler-times "ldapr\tx" 2 } } */
+/* { dg-final { scan-assembler-times "ldapr\tw" 2 } } */
+/* { dg-final { scan-assembler-times "ldaprh\tw" 2 } } */
+/* { dg-final { scan-assembler-times "ldaprb\tw" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/mgeneral-regs_3.c b/gcc/testsuite/gcc.target/aarch64/mgeneral-regs_3.c
index fa629996..4e634f6 100644
--- a/gcc/testsuite/gcc.target/aarch64/mgeneral-regs_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/mgeneral-regs_3.c
@@ -3,9 +3,9 @@
extern void abort (void);
int
-test (int i, ...)
+test (int i, ...) /* { dg-error "'-mgeneral-regs-only' is incompatible with the use of floating-point types" } */
{
- float f = (float) i; /* { dg-error "'-mgeneral-regs-only' is incompatible with the use of floating-point types" } */
- if (f != f) abort ();
+ float f = (float) i;
+ if (f != 0) abort ();
return 2;
}
diff --git a/gcc/testsuite/gcc.target/aarch64/mops_5.c b/gcc/testsuite/gcc.target/aarch64/mops_5.c
new file mode 100644
index 0000000..8a26267
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/mops_5.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv8.6-a+mops" } */
+
+#include <stddef.h>
+
+void g();
+void foo (int a, size_t N, char *__restrict__ in,
+ char *__restrict__ out)
+{
+ if (a != 3)
+ __builtin_memcpy (out, in, N);
+ if (a > 3)
+ g ();
+}
+
+/* { dg-final { scan-assembler-times {cmp\tw0, *} 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/mops_6.c b/gcc/testsuite/gcc.target/aarch64/mops_6.c
new file mode 100644
index 0000000..c6c9a54
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/mops_6.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv8.6-a+mops" } */
+
+#include <stddef.h>
+
+void g();
+void foo (int a, size_t N, char *__restrict__ in,
+ char *__restrict__ out)
+{
+ if (a != 3)
+ __builtin_memmove (out, in, N);
+ if (a > 3)
+ g ();
+}
+
+/* { dg-final { scan-assembler-times {cmp\tw0, *} 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/mops_7.c b/gcc/testsuite/gcc.target/aarch64/mops_7.c
new file mode 100644
index 0000000..79720ca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/mops_7.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv8.6-a+mops" } */
+
+#include <stddef.h>
+
+void g();
+void foo (int a, size_t N, char *__restrict__ out)
+{
+ if (a != 3)
+ __builtin_memset (out, 0, N);
+ if (a > 3)
+ g ();
+}
+
+/* { dg-final { scan-assembler-times {cmp\tw0, *} 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/movk_3.c b/gcc/testsuite/gcc.target/aarch64/movk_3.c
new file mode 100644
index 0000000..9e8c0c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/movk_3.c
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 --save-temps" } */
+
+
+/* 2 MOV */
+void f16 (long *p)
+{
+ p[0] = 0x1234;
+ p[2] = 0x1235;
+}
+
+/* MOV, MOVK and ADD */
+void f32_1 (long *p)
+{
+ p[0] = 0x12345678;
+ p[2] = 0x12345678 + 0xfff;
+}
+
+/* 2 MOV, 2 MOVK */
+void f32_2 (long *p)
+{
+ p[0] = 0x12345678;
+ p[2] = 0x12345678 + 0x555555;
+}
+
+/* MOV, MOVK and ADD */
+void f32_3 (long *p)
+{
+ p[0] = 0x12345678;
+ p[2] = 0x12345678 + 0x999000;
+}
+
+/* MOV, 2 MOVK and ADD */
+void f48_1 (long *p)
+{
+ p[0] = 0x123456789abc;
+ p[2] = 0x123456789abc + 0xfff;
+}
+
+/* MOV, 2 MOVK and 2 ADD */
+void f48_2 (long *p)
+{
+ p[0] = 0x123456789abc;
+ p[2] = 0x123456789abc + 0x666666;
+}
+
+/* 2 MOV, 4 MOVK */
+void f48_3 (long *p)
+{
+ p[0] = 0x123456789abc;
+ p[2] = 0x123456789abc + 0x1666666;
+}
+
+/* { dg-final { scan-assembler-times "mov\tx\[0-9\]+, \[0-9\]+" 10 } } */
+/* { dg-final { scan-assembler-times "movk\tx\[0-9\]+, 0x\[0-9a-f\]+" 12 } } */
+/* { dg-final { scan-assembler-times "add\tx\[0-9\]+, x\[0-9\]+, \[0-9\]+" 5 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/pr92424-2.c b/gcc/testsuite/gcc.target/aarch64/pr92424-2.c
index 0e75657..0a79901 100644
--- a/gcc/testsuite/gcc.target/aarch64/pr92424-2.c
+++ b/gcc/testsuite/gcc.target/aarch64/pr92424-2.c
@@ -1,7 +1,7 @@
/* { dg-do "compile" } */
/* { dg-options "-O1" } */
-/* Test the placement of the .LPFE1 label. */
+/* Test the placement of the .LPFE0 label. */
void
__attribute__ ((target("branch-protection=bti"),
@@ -9,4 +9,4 @@ __attribute__ ((target("branch-protection=bti"),
f10_bti ()
{
}
-/* { dg-final { scan-assembler "f10_bti:\n\thint\t34 // bti c\n.*\.LPFE1:\n\tnop\n.*\tret\n" } } */
+/* { dg-final { scan-assembler "hint\t34 // bti c\n.*\.LPFE0:\n\tnop\n.*\tret\n" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/pr92424-3.c b/gcc/testsuite/gcc.target/aarch64/pr92424-3.c
index 0a1f74d..854bb7f 100644
--- a/gcc/testsuite/gcc.target/aarch64/pr92424-3.c
+++ b/gcc/testsuite/gcc.target/aarch64/pr92424-3.c
@@ -1,7 +1,7 @@
/* { dg-do "compile" } */
/* { dg-options "-O1" } */
-/* Test the placement of the .LPFE1 label. */
+/* Test the placement of the .LPFE0 label. */
void
__attribute__ ((target("branch-protection=bti+pac-ret+leaf"),
@@ -9,4 +9,4 @@ __attribute__ ((target("branch-protection=bti+pac-ret+leaf"),
f10_pac ()
{
}
-/* { dg-final { scan-assembler "f10_pac:\n\thint\t34 // bti c\n.*\.LPFE1:\n\tnop\n.*\thint\t25 // paciasp\n.*\thint\t29 // autiasp\n.*\tret\n" } } */
+/* { dg-final { scan-assembler "hint\t34 // bti c\n.*\.LPFE0:\n\tnop\n.*\thint\t25 // paciasp\n.*\thint\t29 // autiasp\n.*\tret\n" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/pr98776.c b/gcc/testsuite/gcc.target/aarch64/pr98776.c
new file mode 100644
index 0000000..b075b8f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr98776.c
@@ -0,0 +1,11 @@
+/* { dg-do "compile" } */
+/* { dg-options "-O1 -fpatchable-function-entry=1 -fasynchronous-unwind-tables" } */
+
+/* Test the placement of the .LPFE0 label. */
+
+void
+foo (void)
+{
+}
+
+/* { dg-final { scan-assembler "\t\.cfi_startproc\n.*\.LPFE0:\n\tnop\n\tret\n" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/simd/addsub_1.c b/gcc/testsuite/gcc.target/aarch64/simd/addsub_1.c
new file mode 100644
index 0000000..1fb91a3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/simd/addsub_1.c
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_2a_fp16_neon_ok } */
+/* { dg-options "-Ofast" } */
+/* { dg-add-options arm_v8_2a_fp16_neon } */
+/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */
+
+#pragma GCC target "+nosve"
+
+/*
+** f1:
+** ...
+** fneg v[0-9]+.2d, v[0-9]+.2d
+** fadd v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
+** ...
+*/
+void f1 (float *restrict a, float *restrict b, float *res, int n)
+{
+ for (int i = 0; i < (n & -4); i+=2)
+ {
+ res[i+0] = a[i+0] + b[i+0];
+ res[i+1] = a[i+1] - b[i+1];
+ }
+}
+
+/*
+** d1:
+** ...
+** fneg v[0-9]+.4s, v[0-9]+.4s
+** fadd v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h
+** ...
+*/
+void d1 (_Float16 *restrict a, _Float16 *restrict b, _Float16 *res, int n)
+{
+ for (int i = 0; i < (n & -8); i+=2)
+ {
+ res[i+0] = a[i+0] + b[i+0];
+ res[i+1] = a[i+1] - b[i+1];
+ }
+}
+
+/*
+** e1:
+** ...
+** fadd v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d
+** fsub v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d
+** ins v[0-9]+.d\[1\], v[0-9]+.d\[1\]
+** ...
+*/
+void e1 (double *restrict a, double *restrict b, double *res, int n)
+{
+ for (int i = 0; i < (n & -4); i+=2)
+ {
+ res[i+0] = a[i+0] + b[i+0];
+ res[i+1] = a[i+1] - b[i+1];
+ }
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr107920.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr107920.c
new file mode 100644
index 0000000..11448ed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr107920.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fno-tree-ccp -fno-tree-forwprop" } */
+
+#include "arm_sve.h"
+
+svint8_t
+test_s8(int8_t *x)
+{
+ return svld1rq_s8 (svptrue_b8 (), &x[0]);
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/addsub_1.c b/gcc/testsuite/gcc.target/aarch64/sve/addsub_1.c
new file mode 100644
index 0000000..ea7f9d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/addsub_1.c
@@ -0,0 +1,52 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast" } */
+/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */
+
+/*
+** f1:
+** ...
+** fneg z[0-9]+.d, p[0-9]+/m, z[0-9]+.d
+** fadd z[0-9]+.s, z[0-9]+.s, z[0-9]+.s
+** ...
+*/
+void f1 (float *restrict a, float *restrict b, float *res, int n)
+{
+ for (int i = 0; i < (n & -4); i+=2)
+ {
+ res[i+0] = a[i+0] + b[i+0];
+ res[i+1] = a[i+1] - b[i+1];
+ }
+}
+
+/*
+** d1:
+** ...
+** fneg z[0-9]+.s, p[0-9]+/m, z[0-9]+.s
+** fadd z[0-9]+.h, z[0-9]+.h, z[0-9]+.h
+** ...
+*/
+void d1 (_Float16 *restrict a, _Float16 *restrict b, _Float16 *res, int n)
+{
+ for (int i = 0; i < (n & -8); i+=2)
+ {
+ res[i+0] = a[i+0] + b[i+0];
+ res[i+1] = a[i+1] - b[i+1];
+ }
+}
+
+/*
+** e1:
+** ...
+** fsub z[0-9]+.d, z[0-9]+.d, z[0-9]+.d
+** movprfx z[0-9]+.d, p[0-9]+/m, z[0-9]+.d
+** fadd z[0-9]+.d, p[0-9]+/m, z[0-9]+.d, z[0-9]+.d
+** ...
+*/
+void e1 (double *restrict a, double *restrict b, double *res, int n)
+{
+ for (int i = 0; i < (n & -4); i+=2)
+ {
+ res[i+0] = a[i+0] + b[i+0];
+ res[i+1] = a[i+1] - b[i+1];
+ }
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/slp_1.c b/gcc/testsuite/gcc.target/aarch64/sve/slp_1.c
index 07d71a6..e6021c5 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/slp_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/slp_1.c
@@ -30,11 +30,9 @@ vec_slp_##TYPE (TYPE *restrict a, TYPE b, TYPE c, int n) \
TEST_ALL (VEC_PERM)
/* We should use one DUP for each of the 8-, 16- and 32-bit types,
- although we currently use LD1RW for _Float16. We should use two
- DUPs for each of the three 64-bit types. */
+ We should use two DUPs for each of the three 64-bit types. */
/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, [hw]} 2 } } */
-/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.s, [sw]} 2 } } */
-/* { dg-final { scan-assembler-times {\tld1rw\tz[0-9]+\.s, } 1 } } */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.s, [sw]} 3 } } */
/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, [dx]} 9 } } */
/* { dg-final { scan-assembler-times {\tzip1\tz[0-9]+\.d, z[0-9]+\.d, z[0-9]+\.d\n} 3 } } */
/* { dg-final { scan-assembler-not {\tzip2\t} } } */
@@ -53,7 +51,7 @@ TEST_ALL (VEC_PERM)
/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.s} 6 } } */
/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.d} 6 } } */
/* { dg-final { scan-assembler-not {\tldr} } } */
-/* { dg-final { scan-assembler-times {\tstr} 2 } } */
-/* { dg-final { scan-assembler-times {\tstr\th[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-not {\tstr} } } */
+/* { dg-final { scan-assembler-not {\tstr\th[0-9]+} } } */
/* { dg-final { scan-assembler-not {\tuqdec} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/div-by-bitmask_1.c b/gcc/testsuite/gcc.target/aarch64/sve2/div-by-bitmask_1.c
new file mode 100644
index 0000000..e6f5098
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/div-by-bitmask_1.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -std=c99" } */
+/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */
+
+#include <stdint.h>
+
+/*
+** draw_bitmap1:
+** ...
+** mul z[0-9]+.h, p[0-9]+/m, z[0-9]+.h, z[0-9]+.h
+** addhnb z[0-9]+.b, z[0-9]+.h, z[0-9]+.h
+** addhnb z[0-9]+.b, z[0-9]+.h, z[0-9]+.h
+** ...
+*/
+void draw_bitmap1(uint8_t* restrict pixel, uint8_t level, int n)
+{
+ for (int i = 0; i < (n & -16); i+=1)
+ pixel[i] = (pixel[i] * level) / 0xff;
+}
+
+void draw_bitmap2(uint8_t* restrict pixel, uint8_t level, int n)
+{
+ for (int i = 0; i < (n & -16); i+=1)
+ pixel[i] = (pixel[i] * level) / 0xfe;
+}
+
+/*
+** draw_bitmap3:
+** ...
+** mul z[0-9]+.s, p[0-9]+/m, z[0-9]+.s, z[0-9]+.s
+** addhnb z[0-9]+.h, z[0-9]+.s, z[0-9]+.s
+** addhnb z[0-9]+.h, z[0-9]+.s, z[0-9]+.s
+** ...
+*/
+void draw_bitmap3(uint16_t* restrict pixel, uint16_t level, int n)
+{
+ for (int i = 0; i < (n & -16); i+=1)
+ pixel[i] = (pixel[i] * level) / 0xffffU;
+}
+
+/*
+** draw_bitmap4:
+** ...
+** mul z[0-9]+.d, p[0-9]+/m, z[0-9]+.d, z[0-9]+.d
+** addhnb z[0-9]+.s, z[0-9]+.d, z[0-9]+.d
+** addhnb z[0-9]+.s, z[0-9]+.d, z[0-9]+.d
+** ...
+*/
+void draw_bitmap4(uint32_t* restrict pixel, uint32_t level, int n)
+{
+ for (int i = 0; i < (n & -16); i+=1)
+ pixel[i] = (pixel[i] * (uint64_t)level) / 0xffffffffUL;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pr107717.c b/gcc/testsuite/gcc.target/aarch64/sve2/pr107717.c
new file mode 100644
index 0000000..09dc9af
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/pr107717.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O3 -march=armv8-a+sve2" } */
+
+void foo(int n, char *restrict out, char *restrict in) {
+ for (int i=n; i-->0; ) {
+ out[i] += in[i];
+ }
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pr107830-1.c b/gcc/testsuite/gcc.target/aarch64/sve2/pr107830-1.c
new file mode 100644
index 0000000..6d8ee36
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/pr107830-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target fopenmp } */
+/* { dg-additional-options "-Os -fopenmp" } */
+
+void
+f2 (int *a)
+{
+ unsigned int i;
+
+#pragma omp simd
+ for (i = 0; i < 4; ++i)
+ a[i / 3] -= 4;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/pr107830-2.c b/gcc/testsuite/gcc.target/aarch64/sve2/pr107830-2.c
new file mode 100644
index 0000000..4ec45d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/pr107830-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O3 -msve-vector-bits=512" } */
+
+void f(unsigned short *restrict p1, unsigned int *restrict p2)
+{
+ for (int i = 0; i < 16; ++i)
+ {
+ p1[i] /= 0xff;
+ p2[i] += 1;
+ }
+}
+
diff --git a/gcc/testsuite/gcc.target/aarch64/tbz_1.c b/gcc/testsuite/gcc.target/aarch64/tbz_1.c
new file mode 100644
index 0000000..39deb58
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tbz_1.c
@@ -0,0 +1,95 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -std=c99 -fno-unwind-tables -fno-asynchronous-unwind-tables" } */
+/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */
+
+#include <stdbool.h>
+
+void h(void);
+
+/*
+** g1:
+** tbnz w[0-9]+, #?0, .L([0-9]+)
+** ret
+** ...
+*/
+void g1(bool x)
+{
+ if (__builtin_expect (x, 0))
+ h ();
+}
+
+/*
+** g2:
+** tbz w[0-9]+, #?0, .L([0-9]+)
+** b h
+** ...
+*/
+void g2(bool x)
+{
+ if (__builtin_expect (x, 1))
+ h ();
+}
+
+/*
+** g3_ge:
+** tbnz w[0-9]+, #?31, .L[0-9]+
+** b h
+** ...
+*/
+void g3_ge(int x)
+{
+ if (__builtin_expect (x >= 0, 1))
+ h ();
+}
+
+/*
+** g3_gt:
+** cmp w[0-9]+, 0
+** ble .L[0-9]+
+** b h
+** ...
+*/
+void g3_gt(int x)
+{
+ if (__builtin_expect (x > 0, 1))
+ h ();
+}
+
+/*
+** g3_lt:
+** tbz w[0-9]+, #?31, .L[0-9]+
+** b h
+** ...
+*/
+void g3_lt(int x)
+{
+ if (__builtin_expect (x < 0, 1))
+ h ();
+}
+
+/*
+** g3_le:
+** cmp w[0-9]+, 0
+** bgt .L[0-9]+
+** b h
+** ...
+*/
+void g3_le(int x)
+{
+ if (__builtin_expect (x <= 0, 1))
+ h ();
+}
+
+/*
+** g5:
+** mov w[0-9]+, 65279
+** tst w[0-9]+, w[0-9]+
+** beq .L[0-9]+
+** b h
+** ...
+*/
+void g5(int x)
+{
+ if (__builtin_expect (x & 0xfeff, 1))
+ h ();
+}
diff --git a/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c b/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c
index 5685f74..c1221be 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c
@@ -1,5 +1,5 @@
/* This test is executed only if the execution engine supports CMSE instructions. */
-/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=0x00400000" } */
+/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=[cmse_sgstubs]" } */
typedef struct
{
diff --git a/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c b/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c
index 7a794d4..79e9a3e 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c
@@ -1,5 +1,5 @@
/* This test is executed only if the execution engine supports CMSE instructions. */
-/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=0x00400000" } */
+/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=[cmse_sgstubs]" } */
typedef struct
{
diff --git a/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c b/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c
index 5875f8df..d621a80 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c
@@ -1,5 +1,5 @@
/* This test is executed only if the execution engine supports CMSE instructions. */
-/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=0x00400000" } */
+/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=[cmse_sgstubs]" } */
typedef struct
{
diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-20.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-20.c
index 08e89bf..bbea935 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/cmse-20.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-20.c
@@ -1,5 +1,5 @@
/* This test is executed only if the execution engine supports CMSE instructions. */
-/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=0x00400000" } */
+/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=[cmse_sgstubs]" } */
#include <arm_cmse.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse.exp b/gcc/testsuite/gcc.target/arm/cmse/cmse.exp
index 436dd71..1df5d56 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/cmse.exp
+++ b/gcc/testsuite/gcc.target/arm/cmse/cmse.exp
@@ -44,6 +44,17 @@ if {[is-effective-target arm_cmse_hw]} then {
set saved-lto_torture_options ${LTO_TORTURE_OPTIONS}
set LTO_TORTURE_OPTIONS ""
+# Return the start address of the .gnu.sgstubs section.
+proc cmse_sgstubs {} {
+ # Allow to override the location of .gnu.sgstubs section.
+ set tboard [target_info name]
+ if {[board_info $tboard exists cmse_sgstubs]} {
+ return [board_info $tboard cmse_sgstubs]
+ }
+
+ return "0x00400000"
+}
+
# These are for both baseline and mainline.
gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] \
"" $DEFAULT_CFLAGS
diff --git a/gcc/testsuite/gcc.target/arm/cmse/struct-1.c b/gcc/testsuite/gcc.target/arm/cmse/struct-1.c
index 75a99f4..bebd059 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/struct-1.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/struct-1.c
@@ -1,5 +1,5 @@
/* This test is executed only if the execution engine supports CMSE instructions. */
-/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=0x00400000" } */
+/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=[cmse_sgstubs]" } */
typedef struct
{
diff --git a/gcc/testsuite/gcc.target/arm/multilib.exp b/gcc/testsuite/gcc.target/arm/multilib.exp
index 2fa648c..f903f02 100644
--- a/gcc/testsuite/gcc.target/arm/multilib.exp
+++ b/gcc/testsuite/gcc.target/arm/multilib.exp
@@ -450,6 +450,9 @@ if {[multilib_config "aprofile"] } {
{-march=armv8-a -mfpu=crypto-neon-fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
{-march=armv7-a -mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
{-march=armv8-a -mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+ {-mcpu=cortex-x1c -mfpu=auto -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+ {-mcpu=cortex-x1c -mfpu=auto -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+ {-mcpu=cortex-x1c -mfpu=auto -mfloat-abi=soft -mthumb} "thumb/v8-a/nofp"
} {
check_multi_dir $opts $dir
}
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s16.c
index 78ac801..3b95fb1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s16.c
@@ -1,21 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.s16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, int16x8_t b, int16x8_t c, mve_pred16_t p)
{
return vabavq_p_s16 (a, b, c, p);
}
-/* { dg-final { scan-assembler "vabavt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.s16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, int16x8_t b, int16x8_t c, mve_pred16_t p)
{
return vabavq_p (a, b, c, p);
}
-/* { dg-final { scan-assembler "vabavt.s16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.s16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (int16x8_t b, int16x8_t c, mve_pred16_t p)
+{
+ return vabavq_p (1, b, c, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s32.c
index af4e30b..b9f84e5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s32.c
@@ -1,21 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.s32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
{
return vabavq_p_s32 (a, b, c, p);
}
-/* { dg-final { scan-assembler "vabavt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.s32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
{
return vabavq_p (a, b, c, p);
}
-/* { dg-final { scan-assembler "vabavt.s32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.s32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (int32x4_t b, int32x4_t c, mve_pred16_t p)
+{
+ return vabavq_p (1, b, c, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s8.c
index a76b6bd..fa76cd2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s8.c
@@ -1,21 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.s8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, int8x16_t b, int8x16_t c, mve_pred16_t p)
{
return vabavq_p_s8 (a, b, c, p);
}
-/* { dg-final { scan-assembler "vabavt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.s8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, int8x16_t b, int8x16_t c, mve_pred16_t p)
{
return vabavq_p (a, b, c, p);
}
-/* { dg-final { scan-assembler "vabavt.s8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.s8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (int8x16_t b, int8x16_t c, mve_pred16_t p)
+{
+ return vabavq_p (1, b, c, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_u16.c
index 9627a00..93deb66 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_u16.c
@@ -1,21 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.u16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint16x8_t b, uint16x8_t c, mve_pred16_t p)
{
return vabavq_p_u16 (a, b, c, p);
}
-/* { dg-final { scan-assembler "vabavt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.u16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint16x8_t b, uint16x8_t c, mve_pred16_t p)
{
return vabavq_p (a, b, c, p);
}
-/* { dg-final { scan-assembler "vabavt.u16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.u16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint16x8_t b, uint16x8_t c, mve_pred16_t p)
+{
+ return vabavq_p (1, b, c, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_u32.c
index 298c2c3..c11fc70 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_u32.c
@@ -1,21 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.u32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint32x4_t b, uint32x4_t c, mve_pred16_t p)
{
return vabavq_p_u32 (a, b, c, p);
}
-/* { dg-final { scan-assembler "vabavt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.u32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint32x4_t b, uint32x4_t c, mve_pred16_t p)
{
return vabavq_p (a, b, c, p);
}
-/* { dg-final { scan-assembler "vabavt.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.u32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint32x4_t b, uint32x4_t c, mve_pred16_t p)
+{
+ return vabavq_p (1, b, c, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_u8.c
index 7750722..04b9a6e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_u8.c
@@ -1,21 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.u8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint8x16_t b, uint8x16_t c, mve_pred16_t p)
{
return vabavq_p_u8 (a, b, c, p);
}
-/* { dg-final { scan-assembler "vabavt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.u8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint8x16_t b, uint8x16_t c, mve_pred16_t p)
{
return vabavq_p (a, b, c, p);
}
-/* { dg-final { scan-assembler "vabavt.u8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.u8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint8x16_t b, uint8x16_t c, mve_pred16_t p)
+{
+ return vabavq_p (1, b, c, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_s16.c
index c2383f1..d1a1c96 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_s16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabav.s16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, int16x8_t b, int16x8_t c)
{
return vabavq_s16 (a, b, c);
}
-/* { dg-final { scan-assembler "vabav.s16" } } */
+/*
+**foo1:
+** ...
+** vabav.s16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, int16x8_t b, int16x8_t c)
{
return vabavq (a, b, c);
}
-/* { dg-final { scan-assembler "vabav.s16" } } */
+/*
+**foo2:
+** ...
+** vabav.s16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (int16x8_t b, int16x8_t c)
+{
+ return vabavq (1, b, c);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_s32.c
index 7170d01..9ccfc73 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_s32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabav.s32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, int32x4_t b, int32x4_t c)
{
return vabavq_s32 (a, b, c);
}
-/* { dg-final { scan-assembler "vabav.s32" } } */
+/*
+**foo1:
+** ...
+** vabav.s32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, int32x4_t b, int32x4_t c)
{
return vabavq (a, b, c);
}
-/* { dg-final { scan-assembler "vabav.s32" } } */
+/*
+**foo2:
+** ...
+** vabav.s32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (int32x4_t b, int32x4_t c)
+{
+ return vabavq (1, b, c);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_s8.c
index d75ecdb..5184d7a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_s8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabav.s8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, int8x16_t b, int8x16_t c)
{
return vabavq_s8 (a, b, c);
}
-/* { dg-final { scan-assembler "vabav.s8" } } */
+/*
+**foo1:
+** ...
+** vabav.s8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, int8x16_t b, int8x16_t c)
{
return vabavq (a, b, c);
}
-/* { dg-final { scan-assembler "vabav.s8" } } */
+/*
+**foo2:
+** ...
+** vabav.s8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (int8x16_t b, int8x16_t c)
+{
+ return vabavq (1, b, c);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_u16.c
index 40ab94d..c800d79 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_u16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabav.u16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint16x8_t b, uint16x8_t c)
{
return vabavq_u16 (a, b, c);
}
-/* { dg-final { scan-assembler "vabav.u16" } } */
+/*
+**foo1:
+** ...
+** vabav.u16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint16x8_t b, uint16x8_t c)
{
return vabavq (a, b, c);
}
-/* { dg-final { scan-assembler "vabav.u16" } } */
+/*
+**foo2:
+** ...
+** vabav.u16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint16x8_t b, uint16x8_t c)
+{
+ return vabavq (1, b, c);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_u32.c
index 4b9f5c3..b1733ba 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabav.u32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint32x4_t b, uint32x4_t c)
{
return vabavq_u32 (a, b, c);
}
-/* { dg-final { scan-assembler "vabav.u32" } } */
+/*
+**foo1:
+** ...
+** vabav.u32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint32x4_t b, uint32x4_t c)
{
return vabavq (a, b, c);
}
-/* { dg-final { scan-assembler "vabav.u32" } } */
+/*
+**foo2:
+** ...
+** vabav.u32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint32x4_t b, uint32x4_t c)
+{
+ return vabavq (1, b, c);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_u8.c
index 3638e9d..897cd32 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_u8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabav.u8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint8x16_t b, uint8x16_t c)
{
return vabavq_u8 (a, b, c);
}
-/* { dg-final { scan-assembler "vabav.u8" } } */
+/*
+**foo1:
+** ...
+** vabav.u8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint8x16_t b, uint8x16_t c)
{
return vabavq (a, b, c);
}
-/* { dg-final { scan-assembler "vabav.u8" } } */
+/*
+**foo2:
+** ...
+** vabav.u8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint8x16_t b, uint8x16_t c)
+{
+ return vabavq (1, b, c);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f16.c
index b55e826..3385146 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabd.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b)
{
return vabdq_f16 (a, b);
}
-/* { dg-final { scan-assembler "vabd.f16" } } */
+/*
+**foo1:
+** ...
+** vabd.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16x8_t b)
{
return vabdq (a, b);
}
-/* { dg-final { scan-assembler "vabd.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f32.c
index f1a95b1..9a60038 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabd.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b)
{
return vabdq_f32 (a, b);
}
-/* { dg-final { scan-assembler "vabd.f32" } } */
+/*
+**foo1:
+** ...
+** vabd.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32x4_t b)
{
return vabdq (a, b);
}
-/* { dg-final { scan-assembler "vabd.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_f16.c
index f92e671..3584f18 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_f16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t inactive, float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vabdq_m_f16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t inactive, float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vabdq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_f32.c
index 5e30997..8b64f39 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_f32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t inactive, float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vabdq_m_f32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t inactive, float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vabdq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_s16.c
index 3580989..aeb9879 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vabdq_m_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vabdq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_s32.c
index 77d97e1..294c6f1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vabdq_m_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vabdq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_s8.c
index a0004d9..c4c4146 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vabdq_m_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vabdq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_u16.c
index c4dc9a4..4567b0f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_u16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vabdq_m_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vabdq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_u32.c
index 18a64d3..fc58f5c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_u32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vabdq_m_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vabdq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_u8.c
index 494f39c..6c5e2fe 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_m_u8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vabdq_m_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vabdq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_s16.c
index 73773ac..ac300d2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabd.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b)
{
return vabdq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vabd.s16" } } */
+/*
+**foo1:
+** ...
+** vabd.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b)
{
return vabdq (a, b);
}
-/* { dg-final { scan-assembler "vabd.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_s32.c
index 3c552a2..6170a59 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabd.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b)
{
return vabdq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vabd.s32" } } */
+/*
+**foo1:
+** ...
+** vabd.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b)
{
return vabdq (a, b);
}
-/* { dg-final { scan-assembler "vabd.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_s8.c
index f7de6f7..9cf62f9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabd.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b)
{
return vabdq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vabd.s8" } } */
+/*
+**foo1:
+** ...
+** vabd.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vabdq (a, b);
}
-/* { dg-final { scan-assembler "vabd.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_u16.c
index 90d1c87..c283d74 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_u16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabd.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b)
{
return vabdq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vabd.u16" } } */
+/*
+**foo1:
+** ...
+** vabd.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b)
{
return vabdq (a, b);
}
-/* { dg-final { scan-assembler "vabd.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_u32.c
index 405dca5..be9abda 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_u32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabd.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b)
{
return vabdq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vabd.u32" } } */
+/*
+**foo1:
+** ...
+** vabd.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b)
{
return vabdq (a, b);
}
-/* { dg-final { scan-assembler "vabd.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_u8.c
index 2b693c1..227af07 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_u8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabd.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b)
{
return vabdq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vabd.u8" } } */
+/*
+**foo1:
+** ...
+** vabd.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b)
{
return vabdq (a, b);
}
-/* { dg-final { scan-assembler "vabd.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_f16.c
index 9d771a3..ae54ef2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_f16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vabdq_x_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vabdq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_f32.c
index 4988513..d8781db 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_f32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vabdq_x_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vabdq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_s16.c
index 1fa77cc..9d14161 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vabdq_x_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vabdq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_s32.c
index 24a6270..7eb6fad 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_s32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vabdq_x_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vabdq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_s8.c
index f96c2df..8431703 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_s8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vabdq_x_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vabdq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_u16.c
index 820b841..7d2f3dc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_u16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vabdq_x_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vabdq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_u32.c
index 2d81930..b94358f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_u32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vabdq_x_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vabdq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_u8.c
index 7f95685..a88e1e5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_x_u8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vabdq_x_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabdt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabdt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vabdq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f16.c
index 08e141b..d4bc911 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f16.c
@@ -1,13 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabs.f16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a)
{
return vabsq_f16 (a);
}
-/* { dg-final { scan-assembler "vabs.f16" } } */
+
+/*
+**foo1:
+** ...
+** vabs.f16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+float16x8_t
+foo1 (float16x8_t a)
+{
+ return vabsq (a);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f32.c
index 3614a44..9f29558 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f32.c
@@ -1,13 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabs.f32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a)
{
return vabsq_f32 (a);
}
-/* { dg-final { scan-assembler "vabs.f32" } } */
+
+/*
+**foo1:
+** ...
+** vabs.f32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+float32x4_t
+foo1 (float32x4_t a)
+{
+ return vabsq (a);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_f16.c
index 30c14a1..33d1132 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_f16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.f16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t inactive, float16x8_t a, mve_pred16_t p)
{
return vabsq_m_f16 (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabst.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.f16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t inactive, float16x8_t a, mve_pred16_t p)
{
return vabsq_m (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_f32.c
index 652056a..a588f5f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_f32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.f32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t inactive, float32x4_t a, mve_pred16_t p)
{
return vabsq_m_f32 (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabst.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.f32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t inactive, float32x4_t a, mve_pred16_t p)
{
return vabsq_m (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_s16.c
index 2dcf488..360087d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_s16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.s16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, mve_pred16_t p)
{
return vabsq_m_s16 (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabst.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.s16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, mve_pred16_t p)
{
return vabsq_m (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_s32.c
index 183909f..590d020 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_s32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.s32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, mve_pred16_t p)
{
return vabsq_m_s32 (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabst.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.s32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, mve_pred16_t p)
{
return vabsq_m (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_s8.c
index cd17974..518c19fd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_s8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.s8 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, mve_pred16_t p)
{
return vabsq_m_s8 (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabst.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.s8 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, mve_pred16_t p)
{
return vabsq_m (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_s16.c
index 243afeb..6f40447 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_s16.c
@@ -1,21 +1,41 @@
-/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabs.s16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a)
{
return vabsq_s16 (a);
}
-/* { dg-final { scan-assembler "vabs.s16" } } */
+/*
+**foo1:
+** ...
+** vabs.s16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a)
{
return vabsq (a);
}
-/* { dg-final { scan-assembler "vabs.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_s32.c
index d984350..3da8b74 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_s32.c
@@ -1,21 +1,41 @@
-/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabs.s32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a)
{
return vabsq_s32 (a);
}
-/* { dg-final { scan-assembler "vabs.s32" } } */
+/*
+**foo1:
+** ...
+** vabs.s32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a)
{
return vabsq (a);
}
-/* { dg-final { scan-assembler "vabs.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_s8.c
index 93bf152..5fa4ce4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vabs.s8 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a)
{
return vabsq_s8 (a);
}
-/* { dg-final { scan-assembler "vabs.s8" } } */
+/*
+**foo1:
+** ...
+** vabs.s8 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a)
{
return vabsq (a);
}
-/* { dg-final { scan-assembler "vabs.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_f16.c
index d1fc700..fda43ef 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_f16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.f16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, mve_pred16_t p)
{
return vabsq_x_f16 (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabst.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.f16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, mve_pred16_t p)
{
return vabsq_x (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_f32.c
index 0beccac..281e074 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_f32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.f32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, mve_pred16_t p)
{
return vabsq_x_f32 (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabst.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.f32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, mve_pred16_t p)
{
return vabsq_x (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_s16.c
index fd67fd5..93d4ff5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_s16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.s16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, mve_pred16_t p)
{
return vabsq_x_s16 (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabst.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.s16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, mve_pred16_t p)
{
return vabsq_x (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_s32.c
index 22d561d..1ddc8b8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_s32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.s32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, mve_pred16_t p)
{
return vabsq_x_s32 (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabst.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.s32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, mve_pred16_t p)
{
return vabsq_x (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_s8.c
index 6908a6c..0dfcf3e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_x_s8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.s8 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, mve_pred16_t p)
{
return vabsq_x_s8 (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vabst.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabst.s8 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, mve_pred16_t p)
{
return vabsq_x (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_p_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_p_s32.c
index 0991ac1..174f3e3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_p_s32.c
@@ -1,21 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddlvat.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
foo (int64_t a, int32x4_t b, mve_pred16_t p)
{
return vaddlvaq_p_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vaddlvat.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddlvat.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
foo1 (int64_t a, int32x4_t b, mve_pred16_t p)
{
return vaddlvaq_p (a, b, p);
}
-/* { dg-final { scan-assembler "vaddlvat.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_p_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_p_u32.c
index 5af786e..41b9367 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_p_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_p_u32.c
@@ -1,21 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddlvat.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint64_t
foo (uint64_t a, uint32x4_t b, mve_pred16_t p)
{
return vaddlvaq_p_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vaddlvat.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddlvat.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint64_t
foo1 (uint64_t a, uint32x4_t b, mve_pred16_t p)
{
return vaddlvaq_p (a, b, p);
}
-/* { dg-final { scan-assembler "vaddlvat.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddlvat.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint64_t
+foo2 (uint32x4_t b, mve_pred16_t p)
+{
+ return vaddlvaq_p (1, b, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_s32.c
index 78f155f..d692df3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddlva.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
foo (int64_t a, int32x4_t b)
{
return vaddlvaq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vaddlva.s32" } } */
+/*
+**foo1:
+** ...
+** vaddlva.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
foo1 (int64_t a, int32x4_t b)
{
return vaddlvaq (a, b);
}
-/* { dg-final { scan-assembler "vaddlva.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_u32.c
index a7dfa25..4daba29 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvaq_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddlva.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint64_t
foo (uint64_t a, uint32x4_t b)
{
return vaddlvaq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vaddlva.u32" } } */
+/*
+**foo1:
+** ...
+** vaddlva.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint64_t
foo1 (uint64_t a, uint32x4_t b)
{
return vaddlvaq (a, b);
}
-/* { dg-final { scan-assembler "vaddlva.u32" } } */
+/*
+**foo2:
+** ...
+** vaddlva.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint64_t
+foo2 (uint32x4_t b)
+{
+ return vaddlvaq (1, b);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_p_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_p_s32.c
index 8aa1832..df71bf1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_p_s32.c
@@ -1,21 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddlvt.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
foo (int32x4_t a, mve_pred16_t p)
{
return vaddlvq_p_s32 (a, p);
}
-/* { dg-final { scan-assembler "vaddlvt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddlvt.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
foo1 (int32x4_t a, mve_pred16_t p)
{
return vaddlvq_p (a, p);
}
-/* { dg-final { scan-assembler "vaddlvt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_p_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_p_u32.c
index a9cee74..40d6f4c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_p_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_p_u32.c
@@ -1,21 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddlvt.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint64_t
foo (uint32x4_t a, mve_pred16_t p)
{
return vaddlvq_p_u32 (a, p);
}
-/* { dg-final { scan-assembler "vaddlvt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddlvt.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint64_t
foo1 (uint32x4_t a, mve_pred16_t p)
{
return vaddlvq_p (a, p);
}
-/* { dg-final { scan-assembler "vaddlvt.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_s32.c
index 4bd70aa..4c87fb6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_s32.c
@@ -1,21 +1,41 @@
-/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddlv.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
foo (int32x4_t a)
{
return vaddlvq_s32 (a);
}
-/* { dg-final { scan-assembler "vaddlv.s32" } } */
+/*
+**foo1:
+** ...
+** vaddlv.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
foo1 (int32x4_t a)
{
- return vaddlvq_s32 (a);
+ return vaddlvq (a);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vaddlv.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_u32.c
index 2148bd9..3a9037a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddlvq_u32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddlv.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint64_t
foo (uint32x4_t a)
{
- return vaddlvq_u32 (a);
+ return vaddlvq_u32 (a);
}
-/* { dg-final { scan-assembler "vaddlv.u32" } } */
+/*
+**foo1:
+** ...
+** vaddlv.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint64_t
foo1 (uint32x4_t a)
{
- return vaddlvq (a);
+ return vaddlvq (a);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vaddlv.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_f16.c
index 3d1100a..b0e6d5d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_f16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b)
{
return vaddq_f16 (a, b);
}
-/* { dg-final { scan-assembler "vadd.f16" } } */
+/*
+**foo1:
+** ...
+** vadd.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16x8_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_f32.c
index e15e0d1..be459e6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_f32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b)
{
return vaddq_f32 (a, b);
}
-/* { dg-final { scan-assembler "vadd.f32" } } */
+/*
+**foo1:
+** ...
+** vadd.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32x4_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_f16.c
index 51d7020..1631969 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_f16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t inactive, float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vaddq_m_f16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t inactive, float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_f32.c
index 7821bc2..bd00b20 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_f32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t inactive, float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vaddq_m_f32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t inactive, float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_f16.c
index 796bed4..5622365 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_f16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t inactive, float16x8_t a, float16_t b, mve_pred16_t p)
{
return vaddq_m_n_f16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t inactive, float16x8_t a, float16_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo2 (float16x8_t inactive, float16x8_t a, mve_pred16_t p)
+{
+ return vaddq_m (inactive, a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_f32.c
index afa3c4c..e8bdb6a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_f32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t inactive, float32x4_t a, float32_t b, mve_pred16_t p)
{
return vaddq_m_n_f32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t inactive, float32x4_t a, float32_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo2 (float32x4_t inactive, float32x4_t a, mve_pred16_t p)
+{
+ return vaddq_m (inactive, a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_s16.c
index 0ef4337..b1c41e2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vaddq_m_n_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_s32.c
index 46ac88e..1ff3dff 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vaddq_m_n_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_s8.c
index 1867d56..3c7ed0f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vaddq_m_n_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_u16.c
index 1da993b..a8e7b98 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vaddq_m_n_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, uint16x8_t a, mve_pred16_t p)
+{
+ return vaddq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_u32.c
index d7404c9..0cbc89d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vaddq_m_n_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, uint32x4_t a, mve_pred16_t p)
+{
+ return vaddq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_u8.c
index 013e839..db95f28 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vaddq_m_n_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, uint8x16_t a, mve_pred16_t p)
+{
+ return vaddq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_s16.c
index 244c88f..4306e61 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vaddq_m_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_s32.c
index 7a59d75..fad289c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vaddq_m_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_s8.c
index 5b8c74a..0b39c3d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vaddq_m_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_u16.c
index f28e3d7..c7a846a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_u16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vaddq_m_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_u32.c
index aeb836c..bbead60 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_u32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vaddq_m_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_u8.c
index c698df3..3097756 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_m_u8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vaddq_m_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_f16.c
index 024fab5..dbb86b7 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_f16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16_t b)
{
return vaddq_n_f16 (a, b);
}
-/* { dg-final { scan-assembler "vadd.f16" } } */
+/*
+**foo1:
+** ...
+** vadd.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.f16" } } */
+/*
+**foo2:
+** ...
+** vadd.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo2 (float16x8_t a)
+{
+ return vaddq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_f32.c
index 06b1528..61cbe4d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_f32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32_t b)
{
return vaddq_n_f32 (a, b);
}
-/* { dg-final { scan-assembler "vadd.f32" } } */
+/*
+**foo1:
+** ...
+** vadd.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.f32" } } */
+/*
+**foo2:
+** ...
+** vadd.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo2 (float32x4_t a)
+{
+ return vaddq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_s16.c
index 63765f4..237838c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16_t b)
{
return vaddq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vadd.i16" } } */
+/*
+**foo1:
+** ...
+** vadd.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_s32.c
index e462fbf..c2cee5d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32_t b)
{
return vaddq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vadd.i32" } } */
+/*
+**foo1:
+** ...
+** vadd.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_s8.c
index ad7181f..d815eaa 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8_t b)
{
return vaddq_n_s8 (a, b);
}
-/* { dg-final { scan-assembler "vadd.i8" } } */
+/*
+**foo1:
+** ...
+** vadd.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_u16.c
index dac7a9f..35527a6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_u16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16_t b)
{
return vaddq_n_u16 (a, b);
}
-/* { dg-final { scan-assembler "vadd.i16" } } */
+/*
+**foo1:
+** ...
+** vadd.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.i16" } } */
+/*
+**foo2:
+** ...
+** vadd.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t a)
+{
+ return vaddq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_u32.c
index 2f1feb8..66de687 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32_t b)
{
return vaddq_n_u32 (a, b);
}
-/* { dg-final { scan-assembler "vadd.i32" } } */
+/*
+**foo1:
+** ...
+** vadd.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.i32" } } */
+/*
+**foo2:
+** ...
+** vadd.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t a)
+{
+ return vaddq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_u8.c
index 325bdad..9d4f807 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_n_u8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8_t b)
{
return vaddq_n_u8 (a, b);
}
-/* { dg-final { scan-assembler "vadd.i8" } } */
+/*
+**foo1:
+** ...
+** vadd.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.i8" } } */
+/*
+**foo2:
+** ...
+** vadd.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t a)
+{
+ return vaddq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_s16.c
index 31f6cb4..370e433 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b)
{
return vaddq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vadd.i16" } } */
+/*
+**foo1:
+** ...
+** vadd.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_s32.c
index 96aead1..8c3bd33 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b)
{
return vaddq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vadd.i32" } } */
+/*
+**foo1:
+** ...
+** vadd.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_s8.c
index 6676a2e..3d126df 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b)
{
return vaddq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vadd.i8" } } */
+/*
+**foo1:
+** ...
+** vadd.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_u16.c
index 1b19876..e8ed914 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_u16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b)
{
return vaddq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vadd.i16" } } */
+/*
+**foo1:
+** ...
+** vadd.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_u32.c
index 8f5acc6..172ed24 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_u32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b)
{
return vaddq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vadd.i32" } } */
+/*
+**foo1:
+** ...
+** vadd.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_u8.c
index e5be2fa..b60b877 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_u8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vadd.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b)
{
return vaddq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vadd.i8" } } */
+/*
+**foo1:
+** ...
+** vadd.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b)
{
return vaddq (a, b);
}
-/* { dg-final { scan-assembler "vadd.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_f16.c
index bd2a198..e7a3693 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_f16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vaddq_x_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_f32.c
index 5369f4d..f38c6b1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_f32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vaddq_x_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_f16.c
index d2eed8c..e092b28 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_f16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vaddq_x_n_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo2 (float16x8_t a, mve_pred16_t p)
+{
+ return vaddq_x (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_f32.c
index 40d56da..c58a5e5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_f32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vaddq_x_n_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.f32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo2 (float32x4_t a, mve_pred16_t p)
+{
+ return vaddq_x (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_s16.c
index e974cdf..876afc7 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vaddq_x_n_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_s32.c
index a6ac9cc..c25ec00 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vaddq_x_n_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_s8.c
index f5539ef..b638922 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vaddq_x_n_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_u16.c
index f167df1..006a872 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vaddq_x_n_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t a, mve_pred16_t p)
+{
+ return vaddq_x (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_u32.c
index 653c3ee..0cc940b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vaddq_x_n_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t a, mve_pred16_t p)
+{
+ return vaddq_x (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_u8.c
index 0ad65c8..214a8de 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vaddq_x_n_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t a, mve_pred16_t p)
+{
+ return vaddq_x (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_s16.c
index 75b1491..a79531a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vaddq_x_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_s32.c
index 1aadebd..019ed62 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vaddq_x_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_s8.c
index d6b07ce..4f390d1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vaddq_x_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_u16.c
index 5c9abc2..e528a9e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_u16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vaddq_x_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_u32.c
index d55ec73..fa622f0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_u32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vaddq_x_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_u8.c
index bcc058b..8ce1fe3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddq_x_u8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vaddq_x_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vaddt.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_s16.c
index c4bfe34..9522480 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_s16.c
@@ -1,21 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvat.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int32_t a, int16x8_t b, mve_pred16_t p)
{
return vaddvaq_p_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vaddvat.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvat.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int32_t a, int16x8_t b, mve_pred16_t p)
{
return vaddvaq_p (a, b, p);
}
-/* { dg-final { scan-assembler "vaddvat.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_s32.c
index cdc3280..8028181 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_s32.c
@@ -1,21 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvat.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int32_t a, int32x4_t b, mve_pred16_t p)
{
return vaddvaq_p_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vaddvat.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvat.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int32_t a, int32x4_t b, mve_pred16_t p)
{
return vaddvaq_p (a, b, p);
}
-/* { dg-final { scan-assembler "vaddvat.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_s8.c
index d330411..53a9251 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_s8.c
@@ -1,21 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvat.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int32_t a, int8x16_t b, mve_pred16_t p)
{
return vaddvaq_p_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vaddvat.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvat.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int32_t a, int8x16_t b, mve_pred16_t p)
{
return vaddvaq_p (a, b, p);
}
-/* { dg-final { scan-assembler "vaddvat.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_u16.c
index 74d9246..da61820 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_u16.c
@@ -1,21 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvat.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint16x8_t b, mve_pred16_t p)
{
return vaddvaq_p_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vaddvat.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvat.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint16x8_t b, mve_pred16_t p)
{
return vaddvaq_p (a, b, p);
}
-/* { dg-final { scan-assembler "vaddvat.u16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvat.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint16x8_t b, mve_pred16_t p)
+{
+ return vaddvaq_p (1, b, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_u32.c
index e4ec42b..0b7892c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_u32.c
@@ -1,21 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvat.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint32x4_t b, mve_pred16_t p)
{
return vaddvaq_p_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vaddvat.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvat.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint32x4_t b, mve_pred16_t p)
{
return vaddvaq_p (a, b, p);
}
-/* { dg-final { scan-assembler "vaddvat.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvat.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint32x4_t b, mve_pred16_t p)
+{
+ return vaddvaq_p (1, b, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_u8.c
index f9bed83..51cba03 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_p_u8.c
@@ -1,21 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvat.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint8x16_t b, mve_pred16_t p)
{
return vaddvaq_p_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vaddvat.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvat.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint8x16_t b, mve_pred16_t p)
{
return vaddvaq_p (a, b, p);
}
-/* { dg-final { scan-assembler "vaddvat.u8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvat.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint8x16_t b, mve_pred16_t p)
+{
+ return vaddvaq_p (1, b, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_s16.c
index 5f6a8cf..2a4dd6c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddva.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int32_t a, int16x8_t b)
{
return vaddvaq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vaddva.s16" } } */
+/*
+**foo1:
+** ...
+** vaddva.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int32_t a, int16x8_t b)
{
return vaddvaq (a, b);
}
-/* { dg-final { scan-assembler "vaddva.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_s32.c
index 29e27f5..9f1c851 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddva.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int32_t a, int32x4_t b)
{
return vaddvaq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vaddva.s32" } } */
+/*
+**foo1:
+** ...
+** vaddva.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int32_t a, int32x4_t b)
{
return vaddvaq (a, b);
}
-/* { dg-final { scan-assembler "vaddva.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_s8.c
index cac4346..6f77cdb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddva.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int32_t a, int8x16_t b)
{
return vaddvaq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vaddva.s8" } } */
+/*
+**foo1:
+** ...
+** vaddva.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int32_t a, int8x16_t b)
{
return vaddvaq (a, b);
}
-/* { dg-final { scan-assembler "vaddva.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_u16.c
index c943fa5..a3e0e39 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_u16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddva.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint16x8_t b)
{
return vaddvaq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vaddva.u16" } } */
+/*
+**foo1:
+** ...
+** vaddva.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint16x8_t b)
{
return vaddvaq (a, b);
}
-/* { dg-final { scan-assembler "vaddva.u16" } } */
+/*
+**foo2:
+** ...
+** vaddva.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint16x8_t b)
+{
+ return vaddvaq (1, b);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_u32.c
index 0950ff5..e6b2f85 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddva.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint32x4_t b)
{
return vaddvaq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vaddva.u32" } } */
+/*
+**foo1:
+** ...
+** vaddva.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint32x4_t b)
{
return vaddvaq (a, b);
}
-/* { dg-final { scan-assembler "vaddva.u32" } } */
+/*
+**foo2:
+** ...
+** vaddva.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint32x4_t b)
+{
+ return vaddvaq (1, b);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_u8.c
index 2a58225..5bad0ca 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvaq_u8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddva.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint8x16_t b)
{
return vaddvaq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vaddva.u8" } } */
+/*
+**foo1:
+** ...
+** vaddva.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint8x16_t b)
{
return vaddvaq (a, b);
}
-/* { dg-final { scan-assembler "vaddva.u8" } } */
+/*
+**foo2:
+** ...
+** vaddva.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint8x16_t b)
+{
+ return vaddvaq (1, b);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_s16.c
index a786b89..f4e499b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_s16.c
@@ -1,21 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvt.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int16x8_t a, mve_pred16_t p)
{
return vaddvq_p_s16 (a, p);
}
-/* { dg-final { scan-assembler "vaddvt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvt.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int16x8_t a, mve_pred16_t p)
{
return vaddvq_p (a, p);
}
-/* { dg-final { scan-assembler "vaddvt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_s32.c
index c688782..9417d86 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_s32.c
@@ -1,21 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvt.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int32x4_t a, mve_pred16_t p)
{
return vaddvq_p_s32 (a, p);
}
-/* { dg-final { scan-assembler "vaddvt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvt.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int32x4_t a, mve_pred16_t p)
{
return vaddvq_p (a, p);
}
-/* { dg-final { scan-assembler "vaddvt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_s8.c
index 8438448..757bc57 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_s8.c
@@ -1,21 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvt.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int8x16_t a, mve_pred16_t p)
{
return vaddvq_p_s8 (a, p);
}
-/* { dg-final { scan-assembler "vaddvt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvt.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int8x16_t a, mve_pred16_t p)
{
return vaddvq_p (a, p);
}
-/* { dg-final { scan-assembler "vaddvt.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_u16.c
index ec7a5fa..cc9673f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_u16.c
@@ -1,21 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvt.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint16x8_t a, mve_pred16_t p)
{
return vaddvq_p_u16 (a, p);
}
-/* { dg-final { scan-assembler "vaddvt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvt.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint16x8_t a, mve_pred16_t p)
{
return vaddvq_p (a, p);
}
-/* { dg-final { scan-assembler "vaddvt.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_u32.c
index b709688..9ead886 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_u32.c
@@ -1,21 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvt.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32x4_t a, mve_pred16_t p)
{
return vaddvq_p_u32 (a, p);
}
-/* { dg-final { scan-assembler "vaddvt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvt.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32x4_t a, mve_pred16_t p)
{
return vaddvq_p (a, p);
}
-/* { dg-final { scan-assembler "vaddvt.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_u8.c
index 69381b7..45ed62f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_p_u8.c
@@ -1,21 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvt.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint8x16_t a, mve_pred16_t p)
{
return vaddvq_p_u8 (a, p);
}
-/* { dg-final { scan-assembler "vaddvt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vaddvt.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint8x16_t a, mve_pred16_t p)
{
return vaddvq_p (a, p);
}
-/* { dg-final { scan-assembler "vaddvt.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_s16.c
index b4fc11f..468cc81 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_s16.c
@@ -1,21 +1,41 @@
-/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddv.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int16x8_t a)
{
return vaddvq_s16 (a);
}
-/* { dg-final { scan-assembler "vaddv.s16" } } */
+/*
+**foo1:
+** ...
+** vaddv.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int16x8_t a)
{
- return vaddvq_s16 (a);
+ return vaddvq (a);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vaddv.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_s32.c
index 438b46e..791e27b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_s32.c
@@ -1,21 +1,41 @@
-/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddv.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int32x4_t a)
{
return vaddvq_s32 (a);
}
-/* { dg-final { scan-assembler "vaddv.s32" } } */
+/*
+**foo1:
+** ...
+** vaddv.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int32x4_t a)
{
- return vaddvq_s32 (a);
+ return vaddvq (a);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vaddv.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_s8.c
index b60b1f2..3a13efc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_s8.c
@@ -1,21 +1,41 @@
-/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddv.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int8x16_t a)
{
return vaddvq_s8 (a);
}
-/* { dg-final { scan-assembler "vaddv.s8" } } */
+/*
+**foo1:
+** ...
+** vaddv.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int8x16_t a)
{
return vaddvq (a);
}
-/* { dg-final { scan-assembler "vaddv.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_u16.c
index de78212..6aabcdc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_u16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddv.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint16x8_t a)
{
- return vaddvq_u16 (a);
+ return vaddvq_u16 (a);
}
-/* { dg-final { scan-assembler "vaddv.u16" } } */
+/*
+**foo1:
+** ...
+** vaddv.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint16x8_t a)
{
- return vaddvq (a);
+ return vaddvq (a);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vaddv.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_u32.c
index c4672e4..8b5ba81 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_u32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddv.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32x4_t a)
{
- return vaddvq_u32 (a);
+ return vaddvq_u32 (a);
}
-/* { dg-final { scan-assembler "vaddv.u32" } } */
+/*
+**foo1:
+** ...
+** vaddv.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32x4_t a)
{
- return vaddvq (a);
+ return vaddvq (a);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vaddv.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_u8.c
index e4e149c..2576d9c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vaddvq_u8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vaddv.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint8x16_t a)
{
- return vaddvq_u8 (a);
+ return vaddvq_u8 (a);
}
-/* { dg-final { scan-assembler "vaddv.u8" } } */
+/*
+**foo1:
+** ...
+** vaddv.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint8x16_t a)
{
- return vaddvq (a);
+ return vaddvq (a);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vaddv.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u16.c
index a164013..373acbd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u16.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u16 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vcmpcsq_m_n_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u16 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vcmpcsq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u16 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint16x8_t a, mve_pred16_t p)
+{
+ return vcmpcsq_m (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u32.c
index d269ec7..2526365 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u32.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u32 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vcmpcsq_m_n_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u32 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vcmpcsq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u32 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint32x4_t a, mve_pred16_t p)
+{
+ return vcmpcsq_m (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u8.c
index 52c16b3..60120e8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_n_u8.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u8 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vcmpcsq_m_n_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u8 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vcmpcsq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u8 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint8x16_t a, mve_pred16_t p)
+{
+ return vcmpcsq_m (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_u16.c
index e68afa3..fcdc41f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_u16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u16 cs, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vcmpcsq_m_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u16 cs, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vcmpcsq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_u32.c
index 05d1b21..b294c85 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_u32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u32 cs, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vcmpcsq_m_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u32 cs, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vcmpcsq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_u8.c
index 4c8a9d0..00c118a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_m_u8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u8 cs, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vcmpcsq_m_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u8 cs, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vcmpcsq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_n_u16.c
index 4124036..dc63c52 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_n_u16.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.u16 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16_t b)
{
return vcmpcsq_n_u16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u16" } } */
+/*
+**foo1:
+** ...
+** vcmp.u16 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16_t b)
{
return vcmpcsq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u16" } } */
+/*
+**foo2:
+** ...
+** vcmp.u16 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint16x8_t a)
+{
+ return vcmpcsq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_n_u32.c
index 463c1ee..8c5d185 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_n_u32.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.u32 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32_t b)
{
return vcmpcsq_n_u32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u32" } } */
+/*
+**foo1:
+** ...
+** vcmp.u32 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32_t b)
{
return vcmpcsq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u32" } } */
+/*
+**foo2:
+** ...
+** vcmp.u32 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint32x4_t a)
+{
+ return vcmpcsq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_n_u8.c
index 92bc44a..2296f3e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_n_u8.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.u8 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8_t b)
{
return vcmpcsq_n_u8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u8" } } */
+/*
+**foo1:
+** ...
+** vcmp.u8 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8_t b)
{
return vcmpcsq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u8" } } */
+/*
+**foo2:
+** ...
+** vcmp.u8 cs, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint8x16_t a)
+{
+ return vcmpcsq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_u16.c
index 26c7d75..5ae4d0c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_u16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.u16 cs, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16x8_t b)
{
return vcmpcsq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u16" } } */
+/*
+**foo1:
+** ...
+** vcmp.u16 cs, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16x8_t b)
{
return vcmpcsq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_u32.c
index c91b0e1..4695e7e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_u32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.u32 cs, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32x4_t b)
{
return vcmpcsq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u32" } } */
+/*
+**foo1:
+** ...
+** vcmp.u32 cs, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32x4_t b)
{
return vcmpcsq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_u8.c
index 51ddab9..3075050 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpcsq_u8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.u8 cs, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8x16_t b)
{
return vcmpcsq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u8" } } */
+/*
+**foo1:
+** ...
+** vcmp.u8 cs, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8x16_t b)
{
return vcmpcsq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_f16.c
index 556351f..82b24a8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_f16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f16 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16x8_t b)
{
return vcmpeqq_f16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo1:
+** ...
+** vcmp.f16 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16x8_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_f32.c
index 65b2f24..1d7bda0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_f32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f32 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32x4_t b)
{
return vcmpeqq_f32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo1:
+** ...
+** vcmp.f32 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32x4_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_f16.c
index 91b0ffa..0a0406b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_f16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vcmpeqq_m_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_f32.c
index d66e9c8..ba8a946 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_f32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vcmpeqq_m_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_f16.c
index 46b3f44..f095b4a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_f16.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vcmpeqq_m_n_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float16x8_t a, mve_pred16_t p)
+{
+ return vcmpeqq_m (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_f32.c
index 7d672c1..dd244db 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_f32.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vcmpeqq_m_n_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float32x4_t a, mve_pred16_t p)
+{
+ return vcmpeqq_m (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s16.c
index 912d4ad..bbf5326 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vcmpeqq_m_n_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s32.c
index 947c331..b66949b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vcmpeqq_m_n_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s8.c
index e215d65..5730eeb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_s8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vcmpeqq_m_n_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u16.c
index ea4716c..6009e95 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u16.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vcmpeqq_m_n_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint16x8_t a, mve_pred16_t p)
+{
+ return vcmpeqq_m (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u32.c
index 489c6ec..2bce70d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u32.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vcmpeqq_m_n_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint32x4_t a, mve_pred16_t p)
+{
+ return vcmpeqq_m (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u8.c
index e8dfce4..6c6fa8a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_n_u8.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vcmpeqq_m_n_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint8x16_t a, mve_pred16_t p)
+{
+ return vcmpeqq_m (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_s16.c
index 7e4c141..4b5feb2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_s16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vcmpeqq_m_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_s32.c
index 904cfb6..60db456 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_s32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vcmpeqq_m_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_s8.c
index a7e1216..45cdc28 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_s8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vcmpeqq_m_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_u16.c
index 283e1fd..41c3653 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_u16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vcmpeqq_m_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_u32.c
index ad1739b..2e7bf17 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_u32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vcmpeqq_m_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_u8.c
index 595142e..e9d333f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_m_u8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vcmpeqq_m_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vcmpeqq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_f16.c
index f97209d..1d87042 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_f16.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16_t b)
{
return vcmpeqq_n_f16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo1:
+** ...
+** vcmp.f16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo2:
+** ...
+** vcmp.f16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float16x8_t a)
+{
+ return vcmpeqq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_f32.c
index c808432..8b8610b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_f32.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32_t b)
{
return vcmpeqq_n_f32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo1:
+** ...
+** vcmp.f32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo2:
+** ...
+** vcmp.f32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float32x4_t a)
+{
+ return vcmpeqq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_s16.c
index 69f1f53..2f146d9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_s16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16_t b)
{
return vcmpeqq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+/*
+**foo1:
+** ...
+** vcmp.i16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_s32.c
index 06032db..f77743c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_s32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32_t b)
{
return vcmpeqq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+/*
+**foo1:
+** ...
+** vcmp.i32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_s8.c
index 3ebd88b..690ed1b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_s8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i8 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8_t b)
{
return vcmpeqq_n_s8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+/*
+**foo1:
+** ...
+** vcmp.i8 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_u16.c
index 2f6c53a..409c9de 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_u16.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16_t b)
{
return vcmpeqq_n_u16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+/*
+**foo1:
+** ...
+** vcmp.i16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+/*
+**foo2:
+** ...
+** vcmp.i16 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint16x8_t a)
+{
+ return vcmpeqq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_u32.c
index 22fb5be..c3b1736 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_u32.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32_t b)
{
return vcmpeqq_n_u32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+/*
+**foo1:
+** ...
+** vcmp.i32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+/*
+**foo2:
+** ...
+** vcmp.i32 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint32x4_t a)
+{
+ return vcmpeqq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_u8.c
index 79eaeed..3728c73 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_n_u8.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i8 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8_t b)
{
return vcmpeqq_n_u8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+/*
+**foo1:
+** ...
+** vcmp.i8 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+/*
+**foo2:
+** ...
+** vcmp.i8 eq, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint8x16_t a)
+{
+ return vcmpeqq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_s16.c
index 7951ead..24f34a2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_s16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i16 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16x8_t b)
{
return vcmpeqq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+/*
+**foo1:
+** ...
+** vcmp.i16 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16x8_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_s32.c
index 659ccb4..ae5d870 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_s32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i32 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32x4_t b)
{
return vcmpeqq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+/*
+**foo1:
+** ...
+** vcmp.i32 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32x4_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_s8.c
index 9282ec2..81538a9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_s8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i8 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8x16_t b)
{
return vcmpeqq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+/*
+**foo1:
+** ...
+** vcmp.i8 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_u16.c
index 318b7aa..39778cf 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_u16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i16 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16x8_t b)
{
return vcmpeqq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+/*
+**foo1:
+** ...
+** vcmp.i16 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16x8_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_u32.c
index 88e015f..8afd39e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_u32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i32 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32x4_t b)
{
return vcmpeqq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+/*
+**foo1:
+** ...
+** vcmp.i32 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32x4_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_u8.c
index 990a96f..84610a1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpeqq_u8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i8 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8x16_t b)
{
return vcmpeqq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+/*
+**foo1:
+** ...
+** vcmp.i8 eq, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8x16_t b)
{
return vcmpeqq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_f16.c
index eea63a2..f11dc28 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_f16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f16 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16x8_t b)
{
return vcmpgeq_f16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo1:
+** ...
+** vcmp.f16 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16x8_t b)
{
return vcmpgeq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_f32.c
index 64243fe..8eb38db 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_f32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f32 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32x4_t b)
{
return vcmpgeq_f32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo1:
+** ...
+** vcmp.f32 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32x4_t b)
{
return vcmpgeq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_f16.c
index 3588b0a..c3a8df2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_f16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vcmpgeq_m_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vcmpgeq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_f32.c
index 8ed1d22..8069e42 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_f32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vcmpgeq_m_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vcmpgeq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_f16.c
index d106af8..3a9be99 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_f16.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vcmpgeq_m_n_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vcmpgeq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float16x8_t a, mve_pred16_t p)
+{
+ return vcmpgeq_m (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_f32.c
index 1feef8a..a785cfb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_f32.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vcmpgeq_m_n_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vcmpgeq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float32x4_t a, mve_pred16_t p)
+{
+ return vcmpgeq_m (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s16.c
index c0ad38f..0a2544e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vcmpgeq_m_n_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vcmpgeq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s32.c
index 8974ce4..fa45377 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vcmpgeq_m_n_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vcmpgeq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s8.c
index 981aa1b..34d632b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_n_s8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vcmpgeq_m_n_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vcmpgeq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_s16.c
index 587432a..1c5ce78 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_s16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vcmpgeq_m_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vcmpgeq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_s32.c
index e460a8d..3ac4d59 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_s32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vcmpgeq_m_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vcmpgeq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_s8.c
index cde28a3..3c3a584 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_m_s8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vcmpgeq_m_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vcmpgeq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_f16.c
index 907fa5d..4e9a346 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_f16.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f16 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16_t b)
{
return vcmpgeq_n_f16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo1:
+** ...
+** vcmp.f16 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16_t b)
{
return vcmpgeq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo2:
+** ...
+** vcmp.f16 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float16x8_t a)
+{
+ return vcmpgeq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_f32.c
index e4d1406..2cf1d1a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_f32.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f32 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32_t b)
{
return vcmpgeq_n_f32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo1:
+** ...
+** vcmp.f32 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32_t b)
{
return vcmpgeq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo2:
+** ...
+** vcmp.f32 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float32x4_t a)
+{
+ return vcmpgeq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_s16.c
index f4aad09..e0488dc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_s16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s16 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16_t b)
{
return vcmpgeq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+/*
+**foo1:
+** ...
+** vcmp.s16 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16_t b)
{
return vcmpgeq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_s32.c
index 2baa520..b448e8a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_s32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s32 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32_t b)
{
return vcmpgeq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+/*
+**foo1:
+** ...
+** vcmp.s32 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32_t b)
{
return vcmpgeq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_s8.c
index 1dcffcc..9f609b9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_n_s8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s8 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8_t b)
{
return vcmpgeq_n_s8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+/*
+**foo1:
+** ...
+** vcmp.s8 ge, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8_t b)
{
return vcmpgeq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_s16.c
index 817ffb2..c835d99 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_s16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s16 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16x8_t b)
{
return vcmpgeq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+/*
+**foo1:
+** ...
+** vcmp.s16 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16x8_t b)
{
return vcmpgeq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_s32.c
index d608b7f..37d9524 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_s32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s32 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32x4_t b)
{
return vcmpgeq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+/*
+**foo1:
+** ...
+** vcmp.s32 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32x4_t b)
{
return vcmpgeq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_s8.c
index 506e6ce..a752510 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgeq_s8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s8 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8x16_t b)
{
return vcmpgeq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+/*
+**foo1:
+** ...
+** vcmp.s8 ge, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vcmpgeq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_f16.c
index e2bfd7e..d8f151a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_f16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f16 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16x8_t b)
{
return vcmpgtq_f16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo1:
+** ...
+** vcmp.f16 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16x8_t b)
{
return vcmpgtq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_f32.c
index 1b4433f..6f60188 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_f32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f32 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32x4_t b)
{
return vcmpgtq_f32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo1:
+** ...
+** vcmp.f32 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32x4_t b)
{
return vcmpgtq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_f16.c
index def3f90..f724387 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_f16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vcmpgtq_m_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vcmpgtq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_f32.c
index 41a1156..6eebe92 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_f32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vcmpgtq_m_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vcmpgtq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_f16.c
index 80c86f6..be4da4b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_f16.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vcmpgtq_m_n_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vcmpgtq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float16x8_t a, mve_pred16_t p)
+{
+ return vcmpgtq_m (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_f32.c
index 9b7aaad..e824434 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_f32.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vcmpgtq_m_n_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vcmpgtq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float32x4_t a, mve_pred16_t p)
+{
+ return vcmpgtq_m (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s16.c
index c0719d0..12d5540 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vcmpgtq_m_n_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vcmpgtq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s32.c
index 26df8ce..dca726f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vcmpgtq_m_n_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vcmpgtq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s8.c
index f20c50d..07216ac 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_n_s8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vcmpgtq_m_n_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vcmpgtq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_s16.c
index da97abc..bd0ac3d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_s16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vcmpgtq_m_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vcmpgtq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_s32.c
index ab7c218..0c2f3ac 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_s32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vcmpgtq_m_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vcmpgtq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_s8.c
index 13520d1..3f2f28b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_m_s8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vcmpgtq_m_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vcmpgtq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_f16.c
index 98e152c..0339fbc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_f16.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f16 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16_t b)
{
return vcmpgtq_n_f16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo1:
+** ...
+** vcmp.f16 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16_t b)
{
return vcmpgtq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo2:
+** ...
+** vcmp.f16 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float16x8_t a)
+{
+ return vcmpgtq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_f32.c
index 5691e2f..482ac09 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_f32.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f32 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32_t b)
{
return vcmpgtq_n_f32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo1:
+** ...
+** vcmp.f32 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32_t b)
{
return vcmpgtq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo2:
+** ...
+** vcmp.f32 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float32x4_t a)
+{
+ return vcmpgtq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_s16.c
index bc3bdba..9c8611d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_s16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s16 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16_t b)
{
return vcmpgtq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+/*
+**foo1:
+** ...
+** vcmp.s16 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16_t b)
{
return vcmpgtq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_s32.c
index 409a3f9..ef285c9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_s32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s32 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32_t b)
{
return vcmpgtq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+/*
+**foo1:
+** ...
+** vcmp.s32 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32_t b)
{
return vcmpgtq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_s8.c
index 2624307..8cabf98 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_n_s8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s8 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8_t b)
{
return vcmpgtq_n_s8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+/*
+**foo1:
+** ...
+** vcmp.s8 gt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8_t b)
{
return vcmpgtq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_s16.c
index be19e19..da107d4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_s16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s16 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16x8_t b)
{
return vcmpgtq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+/*
+**foo1:
+** ...
+** vcmp.s16 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16x8_t b)
{
return vcmpgtq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_s32.c
index 95f6c70..4508698 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_s32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s32 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32x4_t b)
{
return vcmpgtq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+/*
+**foo1:
+** ...
+** vcmp.s32 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32x4_t b)
{
return vcmpgtq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_s8.c
index 8ba180d..d65d277 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpgtq_s8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s8 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8x16_t b)
{
return vcmpgtq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+/*
+**foo1:
+** ...
+** vcmp.s8 gt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vcmpgtq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u16.c
index 26e5fe3..403ad11 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u16.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u16 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vcmphiq_m_n_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u16 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vcmphiq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u16 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint16x8_t a, mve_pred16_t p)
+{
+ return vcmphiq_m (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u32.c
index 51396b8..a9c9816 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u32.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u32 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vcmphiq_m_n_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u32 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vcmphiq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u32 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint32x4_t a, mve_pred16_t p)
+{
+ return vcmphiq_m (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u8.c
index 475f2e8..16e3af1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_n_u8.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u8 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vcmphiq_m_n_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u8 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vcmphiq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u8 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint8x16_t a, mve_pred16_t p)
+{
+ return vcmphiq_m (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_u16.c
index 98ba895..139f69e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_u16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u16 hi, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vcmphiq_m_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u16 hi, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vcmphiq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_u32.c
index ee561b0..a33aed0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_u32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u32 hi, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vcmphiq_m_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u32 hi, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vcmphiq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_u8.c
index 0c5b29e..18e9b19 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_m_u8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u8 hi, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vcmphiq_m_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.u8 hi, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vcmphiq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_n_u16.c
index d39b755..085b827 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_n_u16.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.u16 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16_t b)
{
return vcmphiq_n_u16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u16" } } */
+/*
+**foo1:
+** ...
+** vcmp.u16 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16_t b)
{
return vcmphiq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u16" } } */
+/*
+**foo2:
+** ...
+** vcmp.u16 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint16x8_t a)
+{
+ return vcmphiq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_n_u32.c
index dbedea9..a62a73f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_n_u32.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.u32 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32_t b)
{
return vcmphiq_n_u32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u32" } } */
+/*
+**foo1:
+** ...
+** vcmp.u32 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32_t b)
{
return vcmphiq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u32" } } */
+/*
+**foo2:
+** ...
+** vcmp.u32 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint32x4_t a)
+{
+ return vcmphiq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_n_u8.c
index 967bb20..f05c9d2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_n_u8.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.u8 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8_t b)
{
return vcmphiq_n_u8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u8" } } */
+/*
+**foo1:
+** ...
+** vcmp.u8 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8_t b)
{
return vcmphiq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u8" } } */
+/*
+**foo2:
+** ...
+** vcmp.u8 hi, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint8x16_t a)
+{
+ return vcmphiq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_u16.c
index f939949..3cff050 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_u16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.u16 hi, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16x8_t b)
{
return vcmphiq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u16" } } */
+/*
+**foo1:
+** ...
+** vcmp.u16 hi, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16x8_t b)
{
return vcmphiq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_u32.c
index becdef0..39f0c12 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_u32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.u32 hi, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32x4_t b)
{
return vcmphiq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u32" } } */
+/*
+**foo1:
+** ...
+** vcmp.u32 hi, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32x4_t b)
{
return vcmphiq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_u8.c
index 933cc69..69103f5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmphiq_u8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.u8 hi, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8x16_t b)
{
return vcmphiq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u8" } } */
+/*
+**foo1:
+** ...
+** vcmp.u8 hi, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8x16_t b)
{
return vcmphiq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_f16.c
index c2e69a5..fb92b67 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_f16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f16 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16x8_t b)
{
return vcmpleq_f16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo1:
+** ...
+** vcmp.f16 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16x8_t b)
{
return vcmpleq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_f32.c
index 923aee0..61ab55d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_f32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f32 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32x4_t b)
{
return vcmpleq_f32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo1:
+** ...
+** vcmp.f32 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32x4_t b)
{
return vcmpleq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_f16.c
index 66a3719..f866469 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_f16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vcmpleq_m_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vcmpleq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_f32.c
index e679b33..5704e6d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_f32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vcmpleq_m_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vcmpleq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_f16.c
index 42049fd..5fa3be1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_f16.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vcmpleq_m_n_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vcmpleq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float16x8_t a, mve_pred16_t p)
+{
+ return vcmpleq_m (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_f32.c
index c68bd4e..cbab960 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_f32.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vcmpleq_m_n_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vcmpleq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float32x4_t a, mve_pred16_t p)
+{
+ return vcmpleq_m (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s16.c
index 0cdc144..d16b5c4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vcmpleq_m_n_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vcmpleq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s32.c
index a955af8..e9504fa 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vcmpleq_m_n_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vcmpleq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s8.c
index d9951e4..10709a8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_n_s8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vcmpleq_m_n_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vcmpleq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_s16.c
index f16aff8..59102a6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_s16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vcmpleq_m_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vcmpleq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_s32.c
index 2c4e659..42d7d7f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_s32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vcmpleq_m_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vcmpleq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_s8.c
index 69b88cf..3d1407b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_m_s8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vcmpleq_m_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vcmpleq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_f16.c
index 3fa3c5e..4f62764 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_f16.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f16 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16_t b)
{
return vcmpleq_n_f16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo1:
+** ...
+** vcmp.f16 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16_t b)
{
return vcmpleq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo2:
+** ...
+** vcmp.f16 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float16x8_t a)
+{
+ return vcmpleq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_f32.c
index 8349de7..e71dcb8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_f32.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f32 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32_t b)
{
return vcmpleq_n_f32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo1:
+** ...
+** vcmp.f32 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32_t b)
{
return vcmpleq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo2:
+** ...
+** vcmp.f32 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float32x4_t a)
+{
+ return vcmpleq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_s16.c
index 5ecae57..6aad8de9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_s16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s16 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16_t b)
{
return vcmpleq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+/*
+**foo1:
+** ...
+** vcmp.s16 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16_t b)
{
return vcmpleq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_s32.c
index 02320e7..fedc87f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_s32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s32 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32_t b)
{
return vcmpleq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+/*
+**foo1:
+** ...
+** vcmp.s32 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32_t b)
{
return vcmpleq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_s8.c
index a0ac973..066dd80 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_n_s8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s8 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8_t b)
{
return vcmpleq_n_s8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+/*
+**foo1:
+** ...
+** vcmp.s8 le, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8_t b)
{
return vcmpleq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_s16.c
index 2fb4acd..00872c3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_s16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s16 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16x8_t b)
{
return vcmpleq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+/*
+**foo1:
+** ...
+** vcmp.s16 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16x8_t b)
{
return vcmpleq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_s32.c
index 2ae998e..8f595a0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_s32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s32 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32x4_t b)
{
return vcmpleq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+/*
+**foo1:
+** ...
+** vcmp.s32 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32x4_t b)
{
return vcmpleq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_s8.c
index da06b019..a827b9b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpleq_s8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s8 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8x16_t b)
{
return vcmpleq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+/*
+**foo1:
+** ...
+** vcmp.s8 le, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vcmpleq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_f16.c
index eab80b2..15855e1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_f16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f16 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16x8_t b)
{
return vcmpltq_f16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo1:
+** ...
+** vcmp.f16 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16x8_t b)
{
return vcmpltq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_f32.c
index f17d164..d11c9e2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_f32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f32 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32x4_t b)
{
return vcmpltq_f32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo1:
+** ...
+** vcmp.f32 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32x4_t b)
{
return vcmpltq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_f16.c
index 93c36f3..efb525c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_f16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vcmpltq_m_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vcmpltq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_f32.c
index a17f0b0..6c78820 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_f32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vcmpltq_m_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vcmpltq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_f16.c
index 45d0f51..2b29d72 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_f16.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vcmpltq_m_n_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vcmpltq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float16x8_t a, mve_pred16_t p)
+{
+ return vcmpltq_m (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_f32.c
index 16e37cc..0c89d29 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_f32.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vcmpltq_m_n_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vcmpltq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float32x4_t a, mve_pred16_t p)
+{
+ return vcmpltq_m (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s16.c
index d0e322f..34984fa 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vcmpltq_m_n_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vcmpltq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s32.c
index 7ec7963..bb7c0a2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vcmpltq_m_n_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vcmpltq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s8.c
index 22434e8..035ce45 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_n_s8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vcmpltq_m_n_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vcmpltq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_s16.c
index 359c064..9776a4a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_s16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vcmpltq_m_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s16 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vcmpltq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_s32.c
index 3df7e89..6a74598 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_s32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vcmpltq_m_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s32 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vcmpltq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_s8.c
index 1055c2b..ca08e1d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_m_s8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vcmpltq_m_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.s8 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vcmpltq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_f16.c
index 2d55af2..c6fdb08 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_f16.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f16 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16_t b)
{
return vcmpltq_n_f16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo1:
+** ...
+** vcmp.f16 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16_t b)
{
return vcmpltq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo2:
+** ...
+** vcmp.f16 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float16x8_t a)
+{
+ return vcmpltq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_f32.c
index 2590ca8..4f1ac3c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_f32.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f32 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32_t b)
{
return vcmpltq_n_f32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo1:
+** ...
+** vcmp.f32 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32_t b)
{
return vcmpltq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo2:
+** ...
+** vcmp.f32 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float32x4_t a)
+{
+ return vcmpltq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_s16.c
index 169f6ad..4c9d1d3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_s16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s16 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16_t b)
{
return vcmpltq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+/*
+**foo1:
+** ...
+** vcmp.s16 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16_t b)
{
return vcmpltq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_s32.c
index 534047c..632c4ae 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_s32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s32 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32_t b)
{
return vcmpltq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+/*
+**foo1:
+** ...
+** vcmp.s32 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32_t b)
{
return vcmpltq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_s8.c
index da659f1..1eabc2e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_n_s8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s8 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8_t b)
{
return vcmpltq_n_s8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+/*
+**foo1:
+** ...
+** vcmp.s8 lt, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8_t b)
{
return vcmpltq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_s16.c
index da4c90a..8511719 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_s16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s16 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16x8_t b)
{
return vcmpltq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+/*
+**foo1:
+** ...
+** vcmp.s16 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16x8_t b)
{
return vcmpltq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_s32.c
index 5dc218a..11379cf 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_s32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s32 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32x4_t b)
{
return vcmpltq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+/*
+**foo1:
+** ...
+** vcmp.s32 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32x4_t b)
{
return vcmpltq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_s8.c
index ea5853c..686ccd8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpltq_s8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.s8 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8x16_t b)
{
return vcmpltq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+/*
+**foo1:
+** ...
+** vcmp.s8 lt, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vcmpltq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_f16.c
index 8d1c609..20d722c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_f16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f16 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16x8_t b)
{
return vcmpneq_f16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo1:
+** ...
+** vcmp.f16 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16x8_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_f32.c
index 860bd69..1e4dcde 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_f32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f32 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32x4_t b)
{
return vcmpneq_f32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo1:
+** ...
+** vcmp.f32 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32x4_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_f16.c
index a4e62de..bafb7e8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_f16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vcmpneq_m_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_f32.c
index b18a2e5..168633d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_f32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vcmpneq_m_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_f16.c
index c127b3a..3b7951f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_f16.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vcmpneq_m_n_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float16x8_t a, mve_pred16_t p)
+{
+ return vcmpneq_m (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_f32.c
index a8423d4..47b972c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_f32.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vcmpneq_m_n_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.f32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float32x4_t a, mve_pred16_t p)
+{
+ return vcmpneq_m (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s16.c
index 63ee1c3..b16c644 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vcmpneq_m_n_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s32.c
index 10f6d44..2f80570 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vcmpneq_m_n_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s8.c
index 66e5d15..4637bd1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_s8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vcmpneq_m_n_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u16.c
index ffe6ff9..90b2353 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u16.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vcmpneq_m_n_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint16x8_t a, mve_pred16_t p)
+{
+ return vcmpneq_m (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u32.c
index 55e796a..c8b0c95 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u32.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vcmpneq_m_n_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint32x4_t a, mve_pred16_t p)
+{
+ return vcmpneq_m (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u8.c
index 3c8bd16..d458b9a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_n_u8.c
@@ -1,22 +1,71 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vcmpneq_m_n_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint8x16_t a, mve_pred16_t p)
+{
+ return vcmpneq_m (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_s16.c
index d3e1ce0..ea83993 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_s16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vcmpneq_m_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_s32.c
index f5602ff..817060f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_s32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vcmpneq_m_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_s8.c
index 84b8b16..9c0473d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_s8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vcmpneq_m_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_u16.c
index 3c89437..4f10b5a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_u16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vcmpneq_m_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i16 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_u32.c
index 980cc41..ba440459 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_u32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vcmpneq_m_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i32 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_u8.c
index 2615dcb..ffe091b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_m_u8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vcmpneq_m_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vcmpt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vcmpt.i8 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vcmpneq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_f16.c
index e9e2a9c..e36d8a9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_f16.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float16x8_t a, float16_t b)
{
return vcmpneq_n_f16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo1:
+** ...
+** vcmp.f16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float16x8_t a, float16_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f16" } } */
+/*
+**foo2:
+** ...
+** vcmp.f16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float16x8_t a)
+{
+ return vcmpneq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_f32.c
index eb64b17..7262503 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_f32.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.f32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (float32x4_t a, float32_t b)
{
return vcmpneq_n_f32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo1:
+** ...
+** vcmp.f32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (float32x4_t a, float32_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.f32" } } */
+/*
+**foo2:
+** ...
+** vcmp.f32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (float32x4_t a)
+{
+ return vcmpneq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_s16.c
index 14689242..2e39b66 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_s16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16_t b)
{
return vcmpneq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+/*
+**foo1:
+** ...
+** vcmp.i16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_s32.c
index 53418ff..9471935 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_s32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32_t b)
{
return vcmpneq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+/*
+**foo1:
+** ...
+** vcmp.i32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_s8.c
index fa405c2..7d3d4dd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_s8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i8 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8_t b)
{
return vcmpneq_n_s8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+/*
+**foo1:
+** ...
+** vcmp.i8 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_u16.c
index cc8540b..71d878d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_u16.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16_t b)
{
return vcmpneq_n_u16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+/*
+**foo1:
+** ...
+** vcmp.i16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+/*
+**foo2:
+** ...
+** vcmp.i16 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint16x8_t a)
+{
+ return vcmpneq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_u32.c
index 07c9b1a..3f997e8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_u32.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32_t b)
{
return vcmpneq_n_u32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+/*
+**foo1:
+** ...
+** vcmp.i32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+/*
+**foo2:
+** ...
+** vcmp.i32 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint32x4_t a)
+{
+ return vcmpneq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_u8.c
index eac5e96..9917a95 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_n_u8.c
@@ -1,21 +1,59 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i8 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8_t b)
{
return vcmpneq_n_u8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+/*
+**foo1:
+** ...
+** vcmp.i8 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+/*
+**foo2:
+** ...
+** vcmp.i8 ne, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
+mve_pred16_t
+foo2 (uint8x16_t a)
+{
+ return vcmpneq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_s16.c
index 6b04ce7..a3b0572 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_s16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i16 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int16x8_t a, int16x8_t b)
{
return vcmpneq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+/*
+**foo1:
+** ...
+** vcmp.i16 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int16x8_t a, int16x8_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_s32.c
index cfb98d7..c6bf6ca 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_s32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i32 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int32x4_t a, int32x4_t b)
{
return vcmpneq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+/*
+**foo1:
+** ...
+** vcmp.i32 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int32x4_t a, int32x4_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_s8.c
index ae69be4..99b343b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_s8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i8 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (int8x16_t a, int8x16_t b)
{
return vcmpneq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+/*
+**foo1:
+** ...
+** vcmp.i8 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_u16.c
index 51059f2..d676d9b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_u16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i16 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint16x8_t a, uint16x8_t b)
{
return vcmpneq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+/*
+**foo1:
+** ...
+** vcmp.i16 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint16x8_t a, uint16x8_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_u32.c
index 42e4a3f..56c3996 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_u32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i32 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint32x4_t a, uint32x4_t b)
{
return vcmpneq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+/*
+**foo1:
+** ...
+** vcmp.i32 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint32x4_t a, uint32x4_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_u8.c
index addacc1..f906574 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcmpneq_u8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vcmp.i8 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo (uint8x16_t a, uint8x16_t b)
{
return vcmpneq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+/*
+**foo1:
+** ...
+** vcmp.i8 ne, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+** vmrs (?:ip|fp|r[0-9]+), p0(?: @.*|)
+** ...
+*/
mve_pred16_t
foo1 (uint8x16_t a, uint8x16_t b)
{
return vcmpneq (a, b);
}
-/* { dg-final { scan-assembler "vcmp.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f16.c
index fb3601e..0458bb1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f16.c
@@ -1,13 +1,42 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
float16x8_t
foo (uint64_t a, uint64_t b)
{
return vcreateq_f16 (a, b);
}
-/* { dg-final { scan-assembler "vmov" } } */
+/*
+**foo1:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
+float16x8_t
+foo1 ()
+{
+ return vcreateq_f16 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f32.c
index 4f4da62..af782b5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f32.c
@@ -1,13 +1,42 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
float32x4_t
foo (uint64_t a, uint64_t b)
{
return vcreateq_f32 (a, b);
}
-/* { dg-final { scan-assembler "vmov" } } */
+/*
+**foo1:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
+float32x4_t
+foo1 ()
+{
+ return vcreateq_f32 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s16.c
index 103be63..8a3e918 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s16.c
@@ -1,13 +1,42 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
int16x8_t
foo (uint64_t a, uint64_t b)
{
return vcreateq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vmov" } } */
+/*
+**foo1:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
+int16x8_t
+foo1 ()
+{
+ return vcreateq_s16 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s32.c
index 96f7a97..5e385df 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s32.c
@@ -1,13 +1,42 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
int32x4_t
foo (uint64_t a, uint64_t b)
{
return vcreateq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vmov" } } */
+/*
+**foo1:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
+int32x4_t
+foo1 ()
+{
+ return vcreateq_s32 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s64.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s64.c
index 74c5545..df90168 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s64.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s64.c
@@ -1,13 +1,42 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
int64x2_t
foo (uint64_t a, uint64_t b)
{
return vcreateq_s64 (a, b);
}
-/* { dg-final { scan-assembler "vmov" } } */
+/*
+**foo1:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
+int64x2_t
+foo1 ()
+{
+ return vcreateq_s64 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s8.c
index 03c50a0..e853395 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s8.c
@@ -1,13 +1,42 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
int8x16_t
foo (uint64_t a, uint64_t b)
{
return vcreateq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vmov" } } */
+/*
+**foo1:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
+int8x16_t
+foo1 ()
+{
+ return vcreateq_s8 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u16.c
index 411cec8..bf4a137 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u16.c
@@ -1,13 +1,42 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
uint16x8_t
foo (uint64_t a, uint64_t b)
{
return vcreateq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vmov" } } */
+/*
+**foo1:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
+uint16x8_t
+foo1 ()
+{
+ return vcreateq_u16 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u32.c
index 8bc8f60..efb58dd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u32.c
@@ -1,13 +1,42 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
uint32x4_t
foo (uint64_t a, uint64_t b)
{
return vcreateq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vmov" } } */
+/*
+**foo1:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
+uint32x4_t
+foo1 ()
+{
+ return vcreateq_u32 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u64.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u64.c
index e74641c..91dd885 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u64.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u64.c
@@ -1,13 +1,42 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
uint64x2_t
foo (uint64_t a, uint64_t b)
{
return vcreateq_u64 (a, b);
}
-/* { dg-final { scan-assembler "vmov" } } */
+/*
+**foo1:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
+uint64x2_t
+foo1 ()
+{
+ return vcreateq_u64 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u8.c
index de79f47..d5d0011 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_u8.c
@@ -1,13 +1,42 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
uint8x16_t
foo (uint64_t a, uint64_t b)
{
return vcreateq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vmov" } } */
+/*
+**foo1:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
+uint8x16_t
+foo1 ()
+{
+ return vcreateq_u8 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u16.c
index 7332711..86e6e0e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint32_t a, mve_pred16_t p)
{
return vddupq_m_n_u16 (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint32_t a, mve_pred16_t p)
{
return vddupq_m (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, mve_pred16_t p)
+{
+ return vddupq_m (inactive, 1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u32.c
index 54ad91f..c5aa532 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32_t a, mve_pred16_t p)
{
- return vddupq_m_n_u32 (inactive, a, 4, p);
+ return vddupq_m_n_u32 (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32_t a, mve_pred16_t p)
{
- return vddupq_m (inactive, a, 4, p);
+ return vddupq_m (inactive, a, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, mve_pred16_t p)
+{
+ return vddupq_m (inactive, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u8.c
index 3746b5d..e326a00 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint32_t a, mve_pred16_t p)
{
- return vddupq_m_n_u8 (inactive, a, 4, p);
+ return vddupq_m_n_u8 (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint32_t a, mve_pred16_t p)
{
- return vddupq_m (inactive, a, 4, p);
+ return vddupq_m (inactive, a, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, mve_pred16_t p)
+{
+ return vddupq_m (inactive, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_wb_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_wb_u16.c
index 8b5d9e8..2a90741 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_wb_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_wb_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint32_t *a, mve_pred16_t p)
{
return vddupq_m_wb_u16 (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint32_t *a, mve_pred16_t p)
{
return vddupq_m (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, mve_pred16_t p)
+{
+ return vddupq_m (inactive, 1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_wb_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_wb_u32.c
index 7a8c363..ffaf373 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_wb_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_wb_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32_t *a, mve_pred16_t p)
{
- return vddupq_m_wb_u32 (inactive, a, 4, p);
+ return vddupq_m_wb_u32 (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32_t *a, mve_pred16_t p)
{
- return vddupq_m (inactive, a, 4, p);
+ return vddupq_m (inactive, a, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, mve_pred16_t p)
+{
+ return vddupq_m (inactive, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_wb_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_wb_u8.c
index 45784a5..ae7a4e25 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_wb_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_wb_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint32_t *a, mve_pred16_t p)
{
- return vddupq_m_wb_u8 (inactive, a, 4, p);
+ return vddupq_m_wb_u8 (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint32_t *a, mve_pred16_t p)
{
- return vddupq_m (inactive, a, 4, p);
+ return vddupq_m (inactive, a, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, mve_pred16_t p)
+{
+ return vddupq_m (inactive, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_n_u16.c
index 4684e2a..dbaf372 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_n_u16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vddup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint32_t a)
{
- return vddupq_n_u16 (a, 4);
+ return vddupq_n_u16 (a, 1);
}
-/* { dg-final { scan-assembler "vddup.u16" } } */
+/*
+**foo1:
+** ...
+** vddup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint32_t a)
{
- return vddupq_u16 (a, 4);
+ return vddupq_u16 (a, 1);
+}
+
+/*
+**foo2:
+** ...
+** vddup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 ()
+{
+ return vddupq_u16 (1, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vddup.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_n_u32.c
index aeaa83e..cf93254 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_n_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vddup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32_t a)
{
return vddupq_n_u32 (a, 1);
}
-/* { dg-final { scan-assembler "vddup.u32" } } */
+/*
+**foo1:
+** ...
+** vddup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32_t a)
{
return vddupq_u32 (a, 1);
}
-/* { dg-final { scan-assembler "vddup.u32" } } */
+/*
+**foo2:
+** ...
+** vddup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 ()
+{
+ return vddupq_u32 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_n_u8.c
index 255a9f8..6008888 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_n_u8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vddup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint32_t a)
{
return vddupq_n_u8 (a, 1);
}
-/* { dg-final { scan-assembler "vddup.u8" } } */
+/*
+**foo1:
+** ...
+** vddup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint32_t a)
{
return vddupq_u8 (a, 1);
}
-/* { dg-final { scan-assembler "vddup.u8" } } */
+/*
+**foo2:
+** ...
+** vddup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 ()
+{
+ return vddupq_u8 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_wb_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_wb_u16.c
index 40fc6cf..6c54e32 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_wb_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_wb_u16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vddup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint32_t *a)
{
- return vddupq_wb_u16 (a, 4);
+ return vddupq_wb_u16 (a, 1);
}
-/* { dg-final { scan-assembler "vddup.u16" } } */
+/*
+**foo1:
+** ...
+** vddup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint32_t *a)
{
- return vddupq_u16 (a, 4);
+ return vddupq_u16 (a, 1);
+}
+
+/*
+**foo2:
+** ...
+** vddup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 ()
+{
+ return vddupq_u16 (1, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vddup.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_wb_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_wb_u32.c
index 09b5b1f..a8de90f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_wb_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_wb_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vddup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32_t *a)
{
return vddupq_wb_u32 (a, 1);
}
-/* { dg-final { scan-assembler "vddup.u32" } } */
+/*
+**foo1:
+** ...
+** vddup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32_t *a)
{
return vddupq_u32 (a, 1);
}
-/* { dg-final { scan-assembler "vddup.u32" } } */
+/*
+**foo2:
+** ...
+** vddup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 ()
+{
+ return vddupq_u32 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_wb_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_wb_u8.c
index 00dfa90..5a90e06 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_wb_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_wb_u8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vddup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint32_t *a)
{
return vddupq_wb_u8 (a, 1);
}
-/* { dg-final { scan-assembler "vddup.u8" } } */
+/*
+**foo1:
+** ...
+** vddup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint32_t *a)
{
return vddupq_u8 (a, 1);
}
-/* { dg-final { scan-assembler "vddup.u8" } } */
+/*
+**foo2:
+** ...
+** vddup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 ()
+{
+ return vddupq_u8 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_n_u16.c
index 5b0fc0b..12e13ad 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint32_t a, mve_pred16_t p)
{
return vddupq_x_n_u16 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint32_t a, mve_pred16_t p)
{
return vddupq_x_u16 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (mve_pred16_t p)
+{
+ return vddupq_x_u16 (1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_n_u32.c
index 66def99..ebe7270 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32_t a, mve_pred16_t p)
{
- return vddupq_x_n_u32 (a, 4, p);
+ return vddupq_x_n_u32 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32_t a, mve_pred16_t p)
{
- return vddupq_x_u32 (a, 4, p);
+ return vddupq_x_u32 (a, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (mve_pred16_t p)
+{
+ return vddupq_x_u32 (1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_n_u8.c
index 8ac322e..d53d45f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint32_t a, mve_pred16_t p)
{
- return vddupq_x_n_u8 (a, 4, p);
+ return vddupq_x_n_u8 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint32_t a, mve_pred16_t p)
{
- return vddupq_x_u8 (a, 4, p);
+ return vddupq_x_u8 (a, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (mve_pred16_t p)
+{
+ return vddupq_x_u8 (1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_wb_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_wb_u16.c
index 030048f..dab65e0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_wb_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_wb_u16.c
@@ -1,25 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
-uint32_t *a;
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
-foo (mve_pred16_t p)
+foo (uint32_t *a, mve_pred16_t p)
{
- return vddupq_x_wb_u16 (a, 2, p);
+ return vddupq_x_wb_u16 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
-foo1 (mve_pred16_t p)
+foo1 (uint32_t *a, mve_pred16_t p)
{
- return vddupq_x_u16 (a, 2, p);
+ return vddupq_x_u16 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (mve_pred16_t p)
+{
+ return vddupq_x_u16 (1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_wb_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_wb_u32.c
index 95bf28e..c7abcae 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_wb_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_wb_u32.c
@@ -1,25 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
-uint32_t *a;
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
-foo (mve_pred16_t p)
+foo (uint32_t *a, mve_pred16_t p)
{
- return vddupq_x_wb_u32 (a, 8, p);
+ return vddupq_x_wb_u32 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
-foo1 (mve_pred16_t p)
+foo1 (uint32_t *a, mve_pred16_t p)
{
- return vddupq_x_u32 (a, 8, p);
+ return vddupq_x_u32 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (mve_pred16_t p)
+{
+ return vddupq_x_u32 (1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_wb_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_wb_u8.c
index 2fe81dd..d2c299d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_wb_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_x_wb_u8.c
@@ -1,25 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
-uint32_t *a;
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
-foo (mve_pred16_t p)
+foo (uint32_t *a, mve_pred16_t p)
{
- return vddupq_x_wb_u8 (a, 8, p);
+ return vddupq_x_wb_u8 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
-foo1 (mve_pred16_t p)
+foo1 (uint32_t *a, mve_pred16_t p)
{
- return vddupq_x_u8 (a, 8, p);
+ return vddupq_x_u8 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (mve_pred16_t p)
+{
+ return vddupq_x_u8 (1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_f16.c
index 0b749be..df7438b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_f16.c
@@ -1,22 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t inactive, float16_t a, mve_pred16_t p)
{
return vdupq_m_n_f16 (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t inactive, float16_t a, mve_pred16_t p)
{
return vdupq_m (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo2 (float16x8_t inactive, mve_pred16_t p)
+{
+ return vdupq_m (inactive, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_f32.c
index 9cca531..6397b902 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_f32.c
@@ -1,22 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t inactive, float32_t a, mve_pred16_t p)
{
return vdupq_m_n_f32 (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t inactive, float32_t a, mve_pred16_t p)
{
return vdupq_m (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo2 (float32x4_t inactive, mve_pred16_t p)
+{
+ return vdupq_m (inactive, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s16.c
index b521f13..bf05c73 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16_t a, mve_pred16_t p)
{
return vdupq_m_n_s16 (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16_t a, mve_pred16_t p)
{
return vdupq_m (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s32.c
index 96aa195..71789bb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32_t a, mve_pred16_t p)
{
return vdupq_m_n_s32 (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32_t a, mve_pred16_t p)
{
return vdupq_m (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s8.c
index f1d2220..48c4fbd1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_s8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8_t a, mve_pred16_t p)
{
return vdupq_m_n_s8 (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8_t a, mve_pred16_t p)
{
return vdupq_m (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_u16.c
index 39d0c9f..511be48 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_u16.c
@@ -1,22 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16_t a, mve_pred16_t p)
{
return vdupq_m_n_u16 (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16_t a, mve_pred16_t p)
{
return vdupq_m (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, mve_pred16_t p)
+{
+ return vdupq_m (inactive, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_u32.c
index fc10717..f3a2c25 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_u32.c
@@ -1,22 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32_t a, mve_pred16_t p)
{
return vdupq_m_n_u32 (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32_t a, mve_pred16_t p)
{
return vdupq_m (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, mve_pred16_t p)
+{
+ return vdupq_m (inactive, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_u8.c
index 9fd3bc4..a99d8f3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_u8.c
@@ -1,22 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8_t a, mve_pred16_t p)
{
return vdupq_m_n_u8 (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8_t a, mve_pred16_t p)
{
return vdupq_m (inactive, a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, mve_pred16_t p)
+{
+ return vdupq_m (inactive, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_f16.c
index 62bfc19..4411219 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_f16.c
@@ -1,13 +1,40 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vdup.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16_t a)
{
return vdupq_n_f16 (a);
}
-/* { dg-final { scan-assembler "vdup.16" } } */
+/*
+**foo1:
+** ...
+** vdup.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo1 ()
+{
+ return vdupq_n_f16 (1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_f32.c
index f5ad228..059e3e4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_f32.c
@@ -1,13 +1,40 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vdup.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32_t a)
{
return vdupq_n_f32 (a);
}
-/* { dg-final { scan-assembler "vdup.32" } } */
+/*
+**foo1:
+** ...
+** vdup.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo1 ()
+{
+ return vdupq_n_f32 (1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s16.c
index 1378522..d8ba299 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s16.c
@@ -1,13 +1,28 @@
-/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vdup.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16_t a)
{
return vdupq_n_s16 (a);
}
-/* { dg-final { scan-assembler "vdup.16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s32.c
index 43affe8..a81c6d1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s32.c
@@ -1,13 +1,28 @@
-/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vdup.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32_t a)
{
return vdupq_n_s32 (a);
}
-/* { dg-final { scan-assembler "vdup.32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s8.c
index 3f934dc..b0bac4f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_s8.c
@@ -1,13 +1,28 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vdup.8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8_t a)
{
return vdupq_n_s8 (a);
}
-/* { dg-final { scan-assembler "vdup.8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u16.c
index 9326864..55e0a60 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u16.c
@@ -1,13 +1,40 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vdup.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16_t a)
{
- return vdupq_n_u16 (a);
+ return vdupq_n_u16 (a);
+}
+
+/*
+**foo1:
+** ...
+** vdup.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo1 ()
+{
+ return vdupq_n_u16 (1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vdup.16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u32.c
index 276e9dd..bf73bc1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u32.c
@@ -1,13 +1,40 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vdup.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32_t a)
{
- return vdupq_n_u32 (a);
+ return vdupq_n_u32 (a);
+}
+
+/*
+**foo1:
+** ...
+** vdup.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo1 ()
+{
+ return vdupq_n_u32 (1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vdup.32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u8.c
index d0361c1..48cbdb2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_n_u8.c
@@ -1,13 +1,40 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vdup.8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8_t a)
{
- return vdupq_n_u8 (a);
+ return vdupq_n_u8 (a);
+}
+
+/*
+**foo1:
+** ...
+** vdup.8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo1 ()
+{
+ return vdupq_n_u8 (1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vdup.8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_f16.c
index c91ee62..7821e36 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_f16.c
@@ -1,14 +1,48 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16_t a, mve_pred16_t p)
{
return vdupq_x_n_f16 (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo1 (mve_pred16_t p)
+{
+ return vdupq_x_n_f16 (1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_f32.c
index c2b3905..af82b3eb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_f32.c
@@ -1,14 +1,48 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32_t a, mve_pred16_t p)
{
return vdupq_x_n_f32 (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo1 (mve_pred16_t p)
+{
+ return vdupq_x_n_f32 (1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s16.c
index cc8a5bf..6756502 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s16.c
@@ -1,14 +1,32 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16_t a, mve_pred16_t p)
{
return vdupq_x_n_s16 (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s32.c
index b3ed3eb..b04afb3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s32.c
@@ -1,14 +1,32 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32_t a, mve_pred16_t p)
{
return vdupq_x_n_s32 (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s8.c
index 3be865d..b23facd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_s8.c
@@ -1,14 +1,32 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8_t a, mve_pred16_t p)
{
return vdupq_x_n_s8 (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_u16.c
index d01338a..62dc42c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_u16.c
@@ -1,14 +1,48 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16_t a, mve_pred16_t p)
{
return vdupq_x_n_u16 (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo1 (mve_pred16_t p)
+{
+ return vdupq_x_n_u16 (1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_u32.c
index 8fa7d45..098fdfb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_u32.c
@@ -1,14 +1,48 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32_t a, mve_pred16_t p)
{
return vdupq_x_n_u32 (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo1 (mve_pred16_t p)
+{
+ return vdupq_x_n_u32 (1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_u8.c
index 96ad899..02a4253 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_x_n_u8.c
@@ -1,14 +1,48 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8_t a, mve_pred16_t p)
{
return vdupq_x_n_u8 (a, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdupt.8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdupt.8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo1 (mve_pred16_t p)
+{
+ return vdupq_x_n_u8 (1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u16.c
index 5303fd7..dc4dbb9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_m (inactive, a, b, 1, p);
+ return vdwdupq_m_n_u16 (inactive, a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
{
return vdwdupq_m (inactive, a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, mve_pred16_t p)
+{
+ return vdwdupq_m (inactive, 1, 1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u32.c
index 9f22bd7..edfc4c4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_m (inactive, a, b, 4, p);
+ return vdwdupq_m_n_u32 (inactive, a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_m (inactive, a, b, 4, p);
+ return vdwdupq_m (inactive, a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, mve_pred16_t p)
+{
+ return vdwdupq_m (inactive, 1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u8.c
index 0591e73..009048f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_m (inactive, a, b, 4, p);
+ return vdwdupq_m_n_u8 (inactive, a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_m (inactive, a, b, 4, p);
+ return vdwdupq_m (inactive, a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, mve_pred16_t p)
+{
+ return vdwdupq_m (inactive, 1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u16.c
index e4e7b47..b24e7a2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
-foo (uint16x8_t inactive, uint32_t * a, uint32_t b, mve_pred16_t p)
+foo (uint16x8_t inactive, uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_m (inactive, a, b, 8, p);
+ return vdwdupq_m_wb_u16 (inactive, a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
-foo1 (uint16x8_t inactive, uint32_t * a, uint32_t b, mve_pred16_t p)
+foo1 (uint16x8_t inactive, uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_m (inactive, a, b, 8, p);
+ return vdwdupq_m (inactive, a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, mve_pred16_t p)
+{
+ return vdwdupq_m (inactive, 1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u32.c
index 42917dc..75c4145 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
-foo (uint32x4_t inactive, uint32_t * a, uint32_t b, mve_pred16_t p)
+foo (uint32x4_t inactive, uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_m (inactive, a, b, 1, p);
+ return vdwdupq_m_wb_u32 (inactive, a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
-foo1 (uint32x4_t inactive, uint32_t * a, uint32_t b, mve_pred16_t p)
+foo1 (uint32x4_t inactive, uint32_t *a, uint32_t b, mve_pred16_t p)
{
return vdwdupq_m (inactive, a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, mve_pred16_t p)
+{
+ return vdwdupq_m (inactive, 1, 1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u8.c
index 32c3153..90d6467 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
-foo (uint8x16_t inactive, uint32_t * a, uint32_t b, mve_pred16_t p)
+foo (uint8x16_t inactive, uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_m (inactive, a, b, 2, p);
+ return vdwdupq_m_wb_u8 (inactive, a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
-foo1 (uint8x16_t inactive, uint32_t * a, uint32_t b, mve_pred16_t p)
+foo1 (uint8x16_t inactive, uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_m (inactive, a, b, 2, p);
+ return vdwdupq_m (inactive, a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, mve_pred16_t p)
+{
+ return vdwdupq_m (inactive, 1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_n_u16.c
index 725a6e4..6235b14 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_n_u16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vdwdup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint32_t a, uint32_t b)
{
- return vdwdupq_n_u16 (a, b, 2);
+ return vdwdupq_n_u16 (a, b, 1);
}
-/* { dg-final { scan-assembler "vdwdup.u16" } } */
+/*
+**foo1:
+** ...
+** vdwdup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint32_t a, uint32_t b)
{
- return vdwdupq_u16 (a, b, 2);
+ return vdwdupq_u16 (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** vdwdup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 ()
+{
+ return vdwdupq_u16 (1, 1, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vdwdup.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_n_u32.c
index 6ceaadb..b6ce427 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_n_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vdwdup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32_t a, uint32_t b)
{
- return vdwdupq_n_u32 (a, b, 8);
+ return vdwdupq_n_u32 (a, b, 1);
}
-/* { dg-final { scan-assembler "vdwdup.u32" } } */
+/*
+**foo1:
+** ...
+** vdwdup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32_t a, uint32_t b)
{
- return vdwdupq_u32 (a, b, 8);
+ return vdwdupq_u32 (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** vdwdup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 ()
+{
+ return vdwdupq_u32 (1, 1, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vdwdup.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_n_u8.c
index a1712e4..bec1eb5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_n_u8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vdwdup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint32_t a, uint32_t b)
{
- return vdwdupq_n_u8 (a, b, 4);
+ return vdwdupq_n_u8 (a, b, 1);
}
-/* { dg-final { scan-assembler "vdwdup.u8" } } */
+/*
+**foo1:
+** ...
+** vdwdup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint32_t a, uint32_t b)
{
- return vdwdupq_u8 (a, b, 4);
+ return vdwdupq_u8 (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** vdwdup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 ()
+{
+ return vdwdupq_u8 (1, 1, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vdwdup.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_wb_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_wb_u16.c
index 0164ea9..87af2b6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_wb_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_wb_u16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vdwdup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint32_t *a, uint32_t b)
{
- return vdwdupq_wb_u16 (a, b, 2);
+ return vdwdupq_wb_u16 (a, b, 1);
}
-/* { dg-final { scan-assembler "vdwdup.u16" } } */
+/*
+**foo1:
+** ...
+** vdwdup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint32_t *a, uint32_t b)
{
- return vdwdupq_u16 (a, b, 2);
+ return vdwdupq_u16 (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** vdwdup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 ()
+{
+ return vdwdupq_u16 (1, 1, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vdwdup.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_wb_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_wb_u32.c
index 7681371..ec136dc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_wb_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_wb_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vdwdup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32_t *a, uint32_t b)
{
- return vdwdupq_wb_u32 (a, b, 8);
+ return vdwdupq_wb_u32 (a, b, 1);
}
-/* { dg-final { scan-assembler "vdwdup.u32" } } */
+/*
+**foo1:
+** ...
+** vdwdup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32_t *a, uint32_t b)
{
- return vdwdupq_u32 (a, b, 8);
+ return vdwdupq_u32 (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** vdwdup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 ()
+{
+ return vdwdupq_u32 (1, 1, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vdwdup.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_wb_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_wb_u8.c
index 6f60bb0..3653d00 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_wb_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_wb_u8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vdwdup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint32_t *a, uint32_t b)
{
- return vdwdupq_wb_u8 (a, b, 4);
+ return vdwdupq_wb_u8 (a, b, 1);
}
-/* { dg-final { scan-assembler "vdwdup.u8" } } */
+/*
+**foo1:
+** ...
+** vdwdup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint32_t *a, uint32_t b)
{
- return vdwdupq_u8 (a, b, 4);
+ return vdwdupq_u8 (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** vdwdup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 ()
+{
+ return vdwdupq_u8 (1, 1, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vdwdup.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u16.c
index ce97526..e9ef2df 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint32_t a, uint32_t b, mve_pred16_t p)
{
return vdwdupq_x_n_u16 (a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint32_t a, uint32_t b, mve_pred16_t p)
{
return vdwdupq_x_u16 (a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (mve_pred16_t p)
+{
+ return vdwdupq_x_u16 (1, 1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u32.c
index 9ed75d2..6cc1582 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32_t a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_x_n_u32 (a, b, 4, p);
+ return vdwdupq_x_n_u32 (a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32_t a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_x_u32 (a, b, 4, p);
+ return vdwdupq_x_u32 (a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (mve_pred16_t p)
+{
+ return vdwdupq_x_u32 (1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u8.c
index 3705094..3216d25 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint32_t a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_x_n_u8 (a, b, 4, p);
+ return vdwdupq_x_n_u8 (a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint32_t a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_x_u8 (a, b, 4, p);
+ return vdwdupq_x_u8 (a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (mve_pred16_t p)
+{
+ return vdwdupq_x_u8 (1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u16.c
index caf744d..e9d994c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
-foo (uint32_t * a, uint32_t b, mve_pred16_t p)
+foo (uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_x_wb_u16 (a, b, 8, p);
+ return vdwdupq_x_wb_u16 (a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
-foo1 (uint32_t * a, uint32_t b, mve_pred16_t p)
+foo1 (uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_x_u16 (a, b, 8, p);
+ return vdwdupq_x_u16 (a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (mve_pred16_t p)
+{
+ return vdwdupq_x_u16 (1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u32.c
index 8c8be86..07438b0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
-foo (uint32_t * a, uint32_t b, mve_pred16_t p)
+foo (uint32_t *a, uint32_t b, mve_pred16_t p)
{
return vdwdupq_x_wb_u32 (a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
-foo1 (uint32_t * a, uint32_t b, mve_pred16_t p)
+foo1 (uint32_t *a, uint32_t b, mve_pred16_t p)
{
return vdwdupq_x_u32 (a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (mve_pred16_t p)
+{
+ return vdwdupq_x_u32 (1, 1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u8.c
index 1c6ef4e..9628022 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
-foo (uint32_t * a, uint32_t b, mve_pred16_t p)
+foo (uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_x_wb_u8 (a, b, 2, p);
+ return vdwdupq_x_wb_u8 (a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
-foo1 (uint32_t * a, uint32_t b, mve_pred16_t p)
+foo1 (uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return vdwdupq_x_u8 (a, b, 2, p);
+ return vdwdupq_x_u8 (a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (mve_pred16_t p)
+{
+ return vdwdupq_x_u8 (1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f16.c
index 06d2d11..7f427bd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vfmast.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
-foo (float16x8_t a, float16x8_t b, float16_t c, mve_pred16_t p)
+foo (float16x8_t m1, float16x8_t m2, float16_t add, mve_pred16_t p)
{
- return vfmasq_m_n_f16 (a, b, c, p);
+ return vfmasq_m_n_f16 (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vfmast.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vfmast.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
-foo1 (float16x8_t a, float16x8_t b, float16_t c, mve_pred16_t p)
+foo1 (float16x8_t m1, float16x8_t m2, float16_t add, mve_pred16_t p)
{
- return vfmasq_m (a, b, c, p);
+ return vfmasq_m (m1, m2, add, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vfmast.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo2 (float16x8_t m1, float16x8_t m2, mve_pred16_t p)
+{
+ return vfmasq_m (m1, m2, 1.1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vfmast.f16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f32.c
index bf1773d..99a1069 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vfmast.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
-foo (float32x4_t a, float32x4_t b, float32_t c, mve_pred16_t p)
+foo (float32x4_t m1, float32x4_t m2, float32_t add, mve_pred16_t p)
{
- return vfmasq_m_n_f32 (a, b, c, p);
+ return vfmasq_m_n_f32 (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vfmast.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vfmast.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
-foo1 (float32x4_t a, float32x4_t b, float32_t c, mve_pred16_t p)
+foo1 (float32x4_t m1, float32x4_t m2, float32_t add, mve_pred16_t p)
{
- return vfmasq_m (a, b, c, p);
+ return vfmasq_m (m1, m2, add, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vfmast.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo2 (float32x4_t m1, float32x4_t m2, mve_pred16_t p)
+{
+ return vfmasq_m (m1, m2, 1.1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vfmast.f32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s16.c
index e90af963..dbcc3b3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vhaddq_m_n_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vhaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s32.c
index fcce85f..134409e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vhaddq_m_n_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vhaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s8.c
index 56558b7..fb295f2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vhaddq_m_n_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vhaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_u16.c
index d7ee0fe..2ed1262 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vhaddq_m_n_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vhaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, uint16x8_t a, mve_pred16_t p)
+{
+ return vhaddq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_u32.c
index 1117b98..852fe64 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vhaddq_m_n_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vhaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, uint32x4_t a, mve_pred16_t p)
+{
+ return vhaddq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_u8.c
index 90c6659..5700f7e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vhaddq_m_n_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vhaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, uint8x16_t a, mve_pred16_t p)
+{
+ return vhaddq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_s16.c
index e8b8728..fce31da 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vhaddq_m_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vhaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_s32.c
index ddcfd11..dbc1b83 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vhaddq_m_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vhaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_s8.c
index ef5fcd0..32e6beb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vhaddq_m_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vhaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_u16.c
index d7b9aaa..d824bd3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_u16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vhaddq_m_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vhaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_u32.c
index c8d7f6c..5f033d2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_u32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vhaddq_m_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vhaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_u8.c
index 9792941..f3ea63f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_u8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vhaddq_m_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vhaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_s16.c
index d0d77f5..20a999d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_s16.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhadd.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16_t b)
{
return vhaddq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vhadd.s16" } } */
+/*
+**foo1:
+** ...
+** vhadd.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16_t b)
{
return vhaddq (a, b);
}
-/* { dg-final { scan-assembler "vhadd.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_s32.c
index a8b4f34..986cb8d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_s32.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhadd.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32_t b)
{
return vhaddq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vhadd.s32" } } */
+/*
+**foo1:
+** ...
+** vhadd.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32_t b)
{
return vhaddq (a, b);
}
-/* { dg-final { scan-assembler "vhadd.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_s8.c
index 2459ba0..57a4b36 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_s8.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhadd.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8_t b)
{
return vhaddq_n_s8 (a, b);
}
-/* { dg-final { scan-assembler "vhadd.s8" } } */
+/*
+**foo1:
+** ...
+** vhadd.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8_t b)
{
return vhaddq (a, b);
}
-/* { dg-final { scan-assembler "vhadd.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_u16.c
index cd681e7..abed33b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_u16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhadd.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16_t b)
{
return vhaddq_n_u16 (a, b);
}
-/* { dg-final { scan-assembler "vhadd.u16" } } */
+/*
+**foo1:
+** ...
+** vhadd.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16_t b)
{
return vhaddq (a, b);
}
-/* { dg-final { scan-assembler "vhadd.u16" } } */
+/*
+**foo2:
+** ...
+** vhadd.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t a)
+{
+ return vhaddq (a, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_u32.c
index d2cb7f6..5e5204f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_u32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhadd.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32_t b)
{
return vhaddq_n_u32 (a, b);
}
-/* { dg-final { scan-assembler "vhadd.u32" } } */
+/*
+**foo1:
+** ...
+** vhadd.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32_t b)
{
return vhaddq (a, b);
}
-/* { dg-final { scan-assembler "vhadd.u32" } } */
+/*
+**foo2:
+** ...
+** vhadd.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t a)
+{
+ return vhaddq (a, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_u8.c
index 509e174..b35221e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_n_u8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhadd.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8_t b)
{
return vhaddq_n_u8 (a, b);
}
-/* { dg-final { scan-assembler "vhadd.u8" } } */
+/*
+**foo1:
+** ...
+** vhadd.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8_t b)
{
return vhaddq (a, b);
}
-/* { dg-final { scan-assembler "vhadd.u8" } } */
+/*
+**foo2:
+** ...
+** vhadd.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t a)
+{
+ return vhaddq (a, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_s16.c
index 47afc59..310964f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_s16.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhadd.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b)
{
return vhaddq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vhadd.s16" } } */
+/*
+**foo1:
+** ...
+** vhadd.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b)
{
return vhaddq (a, b);
}
-/* { dg-final { scan-assembler "vhadd.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_s32.c
index fdc6476..d822264 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_s32.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhadd.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b)
{
return vhaddq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vhadd.s32" } } */
+/*
+**foo1:
+** ...
+** vhadd.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b)
{
return vhaddq (a, b);
}
-/* { dg-final { scan-assembler "vhadd.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_s8.c
index 3321765..85b2fee 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_s8.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhadd.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b)
{
return vhaddq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vhadd.s8" } } */
+/*
+**foo1:
+** ...
+** vhadd.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vhaddq (a, b);
}
-/* { dg-final { scan-assembler "vhadd.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_u16.c
index ad46355..2da0aa0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_u16.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhadd.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b)
{
return vhaddq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vhadd.u16" } } */
+/*
+**foo1:
+** ...
+** vhadd.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b)
{
return vhaddq (a, b);
}
-/* { dg-final { scan-assembler "vhadd.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_u32.c
index 7477585..49b865a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_u32.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhadd.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b)
{
return vhaddq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vhadd.u32" } } */
+/*
+**foo1:
+** ...
+** vhadd.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b)
{
return vhaddq (a, b);
}
-/* { dg-final { scan-assembler "vhadd.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_u8.c
index 9edf8e5..5ecd3cb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_u8.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhadd.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b)
{
return vhaddq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vhadd.u8" } } */
+/*
+**foo1:
+** ...
+** vhadd.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b)
{
return vhaddq (a, b);
}
-/* { dg-final { scan-assembler "vhadd.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_s16.c
index 5a93021..a4e277d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_s16.c
@@ -1,23 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vhaddq_x_n_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vhaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_s32.c
index 0a4ef00..c79b88d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_s32.c
@@ -1,23 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vhaddq_x_n_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vhaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_s8.c
index ae6c27a..6189353 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_s8.c
@@ -1,23 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vhaddq_x_n_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vhaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_u16.c
index ddc99a8..146d226 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_u16.c
@@ -1,23 +1,57 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vhaddq_x_n_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vhaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t a, mve_pred16_t p)
+{
+ return vhaddq_x (a, 1, p);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_u32.c
index dce9bc2..b70014f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_u32.c
@@ -1,23 +1,57 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vhaddq_x_n_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vhaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t a, mve_pred16_t p)
+{
+ return vhaddq_x (a, 1, p);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_u8.c
index 262c593..03978df 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_n_u8.c
@@ -1,23 +1,57 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vhaddq_x_n_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vhaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t a, mve_pred16_t p)
+{
+ return vhaddq_x (a, 1, p);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_s16.c
index 65df009..c3c7875 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_s16.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vhaddq_x_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vhaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_s32.c
index 7ff76e7..a1ab196 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_s32.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vhaddq_x_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vhaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_s8.c
index 23f545c..061ae89 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_s8.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vhaddq_x_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vhaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_u16.c
index 97674c1..0ee8852 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_u16.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vhaddq_x_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vhaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_u32.c
index b6404ce..0a0e512 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_u32.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vhaddq_x_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vhaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_u8.c
index 7c2d74a..c495641 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_x_u8.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vhaddq_x_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhaddt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhaddt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vhaddq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s16.c
index 27dcb7b..0f9eb59 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vhsubq_m_n_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vhsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s32.c
index 75ae735..5b41bf1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vhsubq_m_n_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vhsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s8.c
index 84cdeb42..48e8878 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vhsubq_m_n_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vhsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_u16.c
index bc6610c..3d73146 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vhsubq_m_n_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vhsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, uint16x8_t a, mve_pred16_t p)
+{
+ return vhsubq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_u32.c
index e94bfc9..f6509a5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vhsubq_m_n_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vhsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, uint32x4_t a, mve_pred16_t p)
+{
+ return vhsubq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_u8.c
index c2a5674..db75b38 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vhsubq_m_n_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vhsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, uint8x16_t a, mve_pred16_t p)
+{
+ return vhsubq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_s16.c
index 9f62a38..d8f3f3c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vhsubq_m_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vhsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_s32.c
index 486ae6b..94252c8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vhsubq_m_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vhsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_s8.c
index 9faaa4f..d4f6c24 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vhsubq_m_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vhsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_u16.c
index aa5838c..a921ba6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_u16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vhsubq_m_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vhsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_u32.c
index 00282ad..73a544f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_u32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vhsubq_m_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vhsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_u8.c
index 187d5bc..fd2aa22 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_u8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vhsubq_m_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vhsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_s16.c
index ce76648..af4f534 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_s16.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhsub.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16_t b)
{
return vhsubq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vhsub.s16" } } */
+/*
+**foo1:
+** ...
+** vhsub.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16_t b)
{
return vhsubq (a, b);
}
-/* { dg-final { scan-assembler "vhsub.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_s32.c
index 1d820ff..941d380 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_s32.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhsub.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32_t b)
{
return vhsubq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vhsub.s32" } } */
+/*
+**foo1:
+** ...
+** vhsub.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32_t b)
{
return vhsubq (a, b);
}
-/* { dg-final { scan-assembler "vhsub.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_s8.c
index 90110b7..9ceb4ef 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_s8.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhsub.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8_t b)
{
return vhsubq_n_s8 (a, b);
}
-/* { dg-final { scan-assembler "vhsub.s8" } } */
+/*
+**foo1:
+** ...
+** vhsub.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8_t b)
{
return vhsubq (a, b);
}
-/* { dg-final { scan-assembler "vhsub.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_u16.c
index e744ef5..037ed2c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_u16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhsub.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16_t b)
{
return vhsubq_n_u16 (a, b);
}
-/* { dg-final { scan-assembler "vhsub.u16" } } */
+/*
+**foo1:
+** ...
+** vhsub.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16_t b)
{
return vhsubq (a, b);
}
-/* { dg-final { scan-assembler "vhsub.u16" } } */
+/*
+**foo2:
+** ...
+** vhsub.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t a)
+{
+ return vhsubq (a, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_u32.c
index b1ce3f0..f51eb10 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_u32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhsub.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32_t b)
{
return vhsubq_n_u32 (a, b);
}
-/* { dg-final { scan-assembler "vhsub.u32" } } */
+/*
+**foo1:
+** ...
+** vhsub.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32_t b)
{
return vhsubq (a, b);
}
-/* { dg-final { scan-assembler "vhsub.u32" } } */
+/*
+**foo2:
+** ...
+** vhsub.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t a)
+{
+ return vhsubq (a, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_u8.c
index 68872a8..24dd45d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_n_u8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhsub.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8_t b)
{
return vhsubq_n_u8 (a, b);
}
-/* { dg-final { scan-assembler "vhsub.u8" } } */
+/*
+**foo1:
+** ...
+** vhsub.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8_t b)
{
return vhsubq (a, b);
}
-/* { dg-final { scan-assembler "vhsub.u8" } } */
+/*
+**foo2:
+** ...
+** vhsub.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t a)
+{
+ return vhsubq (a, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_s16.c
index 03bd6d5..0f275d4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_s16.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhsub.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b)
{
return vhsubq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vhsub.s16" } } */
+/*
+**foo1:
+** ...
+** vhsub.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b)
{
return vhsubq (a, b);
}
-/* { dg-final { scan-assembler "vhsub.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_s32.c
index 515acb8..21aeb9d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_s32.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhsub.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b)
{
return vhsubq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vhsub.s32" } } */
+/*
+**foo1:
+** ...
+** vhsub.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b)
{
return vhsubq (a, b);
}
-/* { dg-final { scan-assembler "vhsub.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_s8.c
index 41fb258..b3ee943 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_s8.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhsub.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b)
{
return vhsubq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vhsub.s8" } } */
+/*
+**foo1:
+** ...
+** vhsub.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vhsubq (a, b);
}
-/* { dg-final { scan-assembler "vhsub.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_u16.c
index dda1877..690ef2d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_u16.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhsub.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b)
{
return vhsubq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vhsub.u16" } } */
+/*
+**foo1:
+** ...
+** vhsub.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b)
{
return vhsubq (a, b);
}
-/* { dg-final { scan-assembler "vhsub.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_u32.c
index 86a5576..cfe1257 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_u32.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhsub.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b)
{
return vhsubq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vhsub.u32" } } */
+/*
+**foo1:
+** ...
+** vhsub.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b)
{
return vhsubq (a, b);
}
-/* { dg-final { scan-assembler "vhsub.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_u8.c
index d339ca0..1926bc3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_u8.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vhsub.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b)
{
return vhsubq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vhsub.u8" } } */
+/*
+**foo1:
+** ...
+** vhsub.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b)
{
return vhsubq (a, b);
}
-/* { dg-final { scan-assembler "vhsub.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_s16.c
index 09da5c2..fcda4c5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_s16.c
@@ -1,23 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vhsubq_x_n_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vhsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_s32.c
index f3c0329..5563722 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_s32.c
@@ -1,23 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vhsubq_x_n_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vhsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_s8.c
index 1d86f7d..ecfe188 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_s8.c
@@ -1,23 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vhsubq_x_n_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vhsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_u16.c
index df6b7ea..bf3d6c3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_u16.c
@@ -1,23 +1,57 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vhsubq_x_n_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vhsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t a, mve_pred16_t p)
+{
+ return vhsubq_x (a, 1, p);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_u32.c
index bea6f2d..4ae75b0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_u32.c
@@ -1,23 +1,57 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vhsubq_x_n_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vhsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t a, mve_pred16_t p)
+{
+ return vhsubq_x (a, 1, p);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_u8.c
index e1fafd7..edfa421 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_n_u8.c
@@ -1,23 +1,57 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vhsubq_x_n_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vhsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t a, mve_pred16_t p)
+{
+ return vhsubq_x (a, 1, p);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_s16.c
index c9d3ffb..bd2771b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_s16.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vhsubq_x_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vhsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_s32.c
index 36343cf..0ea40df 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_s32.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vhsubq_x_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vhsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_s8.c
index d1b134f..90ee94d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_s8.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vhsubq_x_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vhsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_u16.c
index 4da0fb3..d700741 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_u16.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vhsubq_x_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vhsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_u32.c
index dfb0a6d..f43c962 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_u32.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vhsubq_x_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vhsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_u8.c
index d549892..a0908ba 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_x_u8.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vhsubq_x_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vhsubt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vhsubt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vhsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u16.c
index 822d411..397be9f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint32_t a, mve_pred16_t p)
{
- return vidupq_m_n_u16 (inactive, a, 4, p);
+ return vidupq_m_n_u16 (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint32_t a, mve_pred16_t p)
{
- return vidupq_m (inactive, a, 4, p);
+ return vidupq_m (inactive, a, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, mve_pred16_t p)
+{
+ return vidupq_m (inactive, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u32.c
index c01826e..02b38cc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32_t a, mve_pred16_t p)
{
return vidupq_m_n_u32 (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32_t a, mve_pred16_t p)
{
return vidupq_m (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, mve_pred16_t p)
+{
+ return vidupq_m (inactive, 1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u8.c
index e269665..f44aa21 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint32_t a, mve_pred16_t p)
{
return vidupq_m_n_u8 (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint32_t a, mve_pred16_t p)
{
return vidupq_m (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, mve_pred16_t p)
+{
+ return vidupq_m (inactive, 1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_wb_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_wb_u16.c
index 8d21bc7..19d0460 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_wb_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_wb_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint32_t *a, mve_pred16_t p)
{
- return vidupq_m_wb_u16 (inactive, a, 4, p);
+ return vidupq_m_wb_u16 (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint32_t *a, mve_pred16_t p)
{
- return vidupq_m (inactive, a, 4, p);
+ return vidupq_m (inactive, a, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, mve_pred16_t p)
+{
+ return vidupq_m (inactive, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_wb_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_wb_u32.c
index e7bc06c..36a8ac3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_wb_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_wb_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32_t *a, mve_pred16_t p)
{
return vidupq_m_wb_u32 (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32_t *a, mve_pred16_t p)
{
return vidupq_m (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, mve_pred16_t p)
+{
+ return vidupq_m (inactive, 1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_wb_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_wb_u8.c
index a8a2f9a..7569530 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_wb_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_wb_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint32_t *a, mve_pred16_t p)
{
return vidupq_m_wb_u8 (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint32_t *a, mve_pred16_t p)
{
return vidupq_m (inactive, a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, mve_pred16_t p)
+{
+ return vidupq_m (inactive, 1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_n_u16.c
index c59ca1e..6b5d881 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_n_u16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vidup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint32_t a)
{
- return vidupq_n_u16 (a, 4);
+ return vidupq_n_u16 (a, 1);
}
-/* { dg-final { scan-assembler "vidup.u16" } } */
+/*
+**foo1:
+** ...
+** vidup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint32_t a)
{
- return vidupq_u16 (a, 4);
+ return vidupq_u16 (a, 1);
+}
+
+/*
+**foo2:
+** ...
+** vidup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 ()
+{
+ return vidupq_u16 (1, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vidup.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_n_u32.c
index 7e835e0..0b829a4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_n_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vidup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32_t a)
{
return vidupq_n_u32 (a, 1);
}
-/* { dg-final { scan-assembler "vidup.u32" } } */
+/*
+**foo1:
+** ...
+** vidup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32_t a)
{
return vidupq_u32 (a, 1);
}
-/* { dg-final { scan-assembler "vidup.u32" } } */
+/*
+**foo2:
+** ...
+** vidup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 ()
+{
+ return vidupq_u32 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_n_u8.c
index 06d1a1a..1252375 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_n_u8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vidup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint32_t a)
{
return vidupq_n_u8 (a, 1);
}
-/* { dg-final { scan-assembler "vidup.u8" } } */
+/*
+**foo1:
+** ...
+** vidup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint32_t a)
{
return vidupq_u8 (a, 1);
}
-/* { dg-final { scan-assembler "vidup.u8" } } */
+/*
+**foo2:
+** ...
+** vidup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 ()
+{
+ return vidupq_u8 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_wb_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_wb_u16.c
index 1cb0ded..83d9cc2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_wb_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_wb_u16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vidup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint32_t *a)
{
- return vidupq_wb_u16 (a, 4);
+ return vidupq_wb_u16 (a, 1);
}
-/* { dg-final { scan-assembler "vidup.u16" } } */
+/*
+**foo1:
+** ...
+** vidup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint32_t *a)
{
- return vidupq_u16 (a, 4);
+ return vidupq_u16 (a, 1);
+}
+
+/*
+**foo2:
+** ...
+** vidup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 ()
+{
+ return vidupq_u16 (1, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vidup.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_wb_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_wb_u32.c
index e5d9c53..d73face 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_wb_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_wb_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vidup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32_t *a)
{
return vidupq_wb_u32 (a, 1);
}
-/* { dg-final { scan-assembler "vidup.u32" } } */
+/*
+**foo1:
+** ...
+** vidup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32_t *a)
{
return vidupq_u32 (a, 1);
}
-/* { dg-final { scan-assembler "vidup.u32" } } */
+/*
+**foo2:
+** ...
+** vidup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 ()
+{
+ return vidupq_u32 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_wb_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_wb_u8.c
index 57e1bb4..75187b0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_wb_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_wb_u8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vidup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint32_t *a)
{
return vidupq_wb_u8 (a, 1);
}
-/* { dg-final { scan-assembler "vidup.u8" } } */
+/*
+**foo1:
+** ...
+** vidup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint32_t *a)
{
return vidupq_u8 (a, 1);
}
-/* { dg-final { scan-assembler "vidup.u8" } } */
+/*
+**foo2:
+** ...
+** vidup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 ()
+{
+ return vidupq_u8 (1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_n_u16.c
index bdf8ec2..5df5035 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint32_t a, mve_pred16_t p)
{
- return vidupq_x_n_u16 (a, 4, p);
+ return vidupq_x_n_u16 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint32_t a, mve_pred16_t p)
{
- return vidupq_x_u16 (a, 4, p);
+ return vidupq_x_u16 (a, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (mve_pred16_t p)
+{
+ return vidupq_x_u16 (1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_n_u32.c
index 8be549c..02c6d77 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32_t a, mve_pred16_t p)
{
return vidupq_x_n_u32 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32_t a, mve_pred16_t p)
{
return vidupq_x_u32 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (mve_pred16_t p)
+{
+ return vidupq_x_u32 (1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_n_u8.c
index 1e19750..3a1d3c0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint32_t a, mve_pred16_t p)
{
return vidupq_x_n_u8 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint32_t a, mve_pred16_t p)
{
return vidupq_x_u8 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (mve_pred16_t p)
+{
+ return vidupq_x_u8 (1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_wb_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_wb_u16.c
index 31197a7..31ddde4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_wb_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_wb_u16.c
@@ -1,25 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
-uint32_t *a;
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
-foo (mve_pred16_t p)
+foo (uint32_t *a, mve_pred16_t p)
{
- return vidupq_x_wb_u16 (a, 8, p);
+ return vidupq_x_wb_u16 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
-foo1 (mve_pred16_t p)
+foo1 (uint32_t *a, mve_pred16_t p)
{
- return vidupq_x_u16 (a, 8, p);
+ return vidupq_x_u16 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (mve_pred16_t p)
+{
+ return vidupq_x_u16 (1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_wb_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_wb_u32.c
index cef56f1..c819346 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_wb_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_wb_u32.c
@@ -1,25 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
-uint32_t *a;
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
-foo (mve_pred16_t p)
+foo (uint32_t *a, mve_pred16_t p)
{
- return vidupq_x_wb_u32 (a, 2, p);
+ return vidupq_x_wb_u32 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
-foo1 (mve_pred16_t p)
+foo1 (uint32_t *a, mve_pred16_t p)
{
- return vidupq_x_u32 (a, 2, p);
+ return vidupq_x_u32 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (mve_pred16_t p)
+{
+ return vidupq_x_u32 (1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_wb_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_wb_u8.c
index 0403ba1..f7a6289 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_wb_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_x_wb_u8.c
@@ -1,25 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
-uint32_t * a;
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
-foo (mve_pred16_t p)
+foo (uint32_t *a, mve_pred16_t p)
{
- return vidupq_x_wb_u8 (a, 2, p);
+ return vidupq_x_wb_u8 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
-foo1 (mve_pred16_t p)
+foo1 (uint32_t *a, mve_pred16_t p)
{
- return vidupq_x_u8 (a, 2, p);
+ return vidupq_x_u8 (a, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (mve_pred16_t p)
+{
+ return vidupq_x_u8 (1, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u16.c
index 0f999cc..d96a890 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_m_n_u16 (inactive, a, b, 2, p);
+ return viwdupq_m_n_u16 (inactive, a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_m (inactive, a, b, 2, p);
+ return viwdupq_m (inactive, a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, mve_pred16_t p)
+{
+ return viwdupq_m (inactive, 1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u32.c
index f79c91e..ca1ac6e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_m_n_u32 (inactive, a, b, 4, p);
+ return viwdupq_m_n_u32 (inactive, a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_m (inactive, a, b, 4, p);
+ return viwdupq_m (inactive, a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, mve_pred16_t p)
+{
+ return viwdupq_m (inactive, 1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u8.c
index c0fee9f..9590e02 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_m_n_u8 (inactive, a, b, 8, p);
+ return viwdupq_m_n_u8 (inactive, a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_m (inactive, a, b, 8, p);
+ return viwdupq_m (inactive, a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, mve_pred16_t p)
+{
+ return viwdupq_m (inactive, 1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u16.c
index 468ba17..84733f9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_m_wb_u16 (inactive, a, b, 2, p);
+ return viwdupq_m_wb_u16 (inactive, a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_m (inactive, a, b, 2, p);
+ return viwdupq_m (inactive, a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, mve_pred16_t p)
+{
+ return viwdupq_m (inactive, 1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u32.c
index e919030..a175744 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_m_wb_u32 (inactive, a, b, 4, p);
+ return viwdupq_m_wb_u32 (inactive, a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_m (inactive, a, b, 4, p);
+ return viwdupq_m (inactive, a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, mve_pred16_t p)
+{
+ return viwdupq_m (inactive, 1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u8.c
index 309ce95..7240b6e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_m_wb_u8 (inactive, a, b, 8, p);
+ return viwdupq_m_wb_u8 (inactive, a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_m (inactive, a, b, 8, p);
+ return viwdupq_m (inactive, a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, mve_pred16_t p)
+{
+ return viwdupq_m (inactive, 1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_n_u16.c
index 599d907..a5eb309 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_n_u16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** viwdup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint32_t a, uint32_t b)
{
- return viwdupq_n_u16 (a, b, 2);
+ return viwdupq_n_u16 (a, b, 1);
}
-/* { dg-final { scan-assembler "viwdup.u16" } } */
+/*
+**foo1:
+** ...
+** viwdup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint32_t a, uint32_t b)
{
- return viwdupq_u16 (a, b, 2);
+ return viwdupq_u16 (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** viwdup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 ()
+{
+ return viwdupq_u16 (1, 1, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "viwdup.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_n_u32.c
index 7c2af74..63f6bdf 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_n_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** viwdup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32_t a, uint32_t b)
{
- return viwdupq_n_u32 (a, b, 4);
+ return viwdupq_n_u32 (a, b, 1);
}
-/* { dg-final { scan-assembler "viwdup.u32" } } */
+/*
+**foo1:
+** ...
+** viwdup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32_t a, uint32_t b)
{
- return viwdupq_u32 (a, b, 4);
+ return viwdupq_u32 (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** viwdup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 ()
+{
+ return viwdupq_u32 (1, 1, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "viwdup.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_n_u8.c
index 4ff6079..65d1062 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_n_u8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** viwdup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint32_t a, uint32_t b)
{
return viwdupq_n_u8 (a, b, 1);
}
-/* { dg-final { scan-assembler "viwdup.u8" } } */
+/*
+**foo1:
+** ...
+** viwdup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint32_t a, uint32_t b)
{
return viwdupq_u8 (a, b, 1);
}
-/* { dg-final { scan-assembler "viwdup.u8" } } */
+/*
+**foo2:
+** ...
+** viwdup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 ()
+{
+ return viwdupq_u8 (1, 1, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_wb_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_wb_u16.c
index 1e5ce88d..eaa496b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_wb_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_wb_u16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** viwdup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
-foo (uint32_t * a, uint32_t b)
+foo (uint32_t *a, uint32_t b)
{
- return viwdupq_wb_u16 (a, b, 4);
+ return viwdupq_wb_u16 (a, b, 1);
}
-/* { dg-final { scan-assembler "viwdup.u16" } } */
+/*
+**foo1:
+** ...
+** viwdup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
-foo1 (uint32_t * a, uint32_t b)
+foo1 (uint32_t *a, uint32_t b)
{
- return viwdupq_u16 (a, b, 4);
+ return viwdupq_u16 (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** viwdup.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 ()
+{
+ return viwdupq_u16 (1, 1, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "viwdup.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_wb_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_wb_u32.c
index 0c076f7..c1912d7 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_wb_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_wb_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** viwdup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
-foo (uint32_t * a, uint32_t b)
+foo (uint32_t *a, uint32_t b)
{
- return viwdupq_wb_u32 (a, b, 8);
+ return viwdupq_wb_u32 (a, b, 1);
}
-/* { dg-final { scan-assembler "viwdup.u32" } } */
+/*
+**foo1:
+** ...
+** viwdup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
-foo1 (uint32_t * a, uint32_t b)
+foo1 (uint32_t *a, uint32_t b)
{
- return viwdupq_u32 (a, b, 8);
+ return viwdupq_u32 (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** viwdup.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 ()
+{
+ return viwdupq_u32 (1, 1, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "viwdup.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_wb_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_wb_u8.c
index 9e5118b..f0d66a9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_wb_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_wb_u8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** viwdup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
-foo (uint32_t * a, uint32_t b)
+foo (uint32_t *a, uint32_t b)
{
- return viwdupq_wb_u8 (a, b, 2);
+ return viwdupq_wb_u8 (a, b, 1);
}
-/* { dg-final { scan-assembler "viwdup.u8" } } */
+/*
+**foo1:
+** ...
+** viwdup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
-foo1 (uint32_t * a, uint32_t b)
+foo1 (uint32_t *a, uint32_t b)
{
- return viwdupq_u8 (a, b, 2);
+ return viwdupq_u8 (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** viwdup.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 ()
+{
+ return viwdupq_u8 (1, 1, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "viwdup.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_n_u16.c
index fdaf6be..7f8cc38 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint32_t a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_x_n_u16 (a, b, 2, p);
+ return viwdupq_x_n_u16 (a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint32_t a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_x_u16 (a, b, 2, p);
+ return viwdupq_x_u16 (a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (mve_pred16_t p)
+{
+ return viwdupq_x_u16 (1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_n_u32.c
index affc616..f97b599 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32_t a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_x_n_u32 (a, b, 4, p);
+ return viwdupq_x_n_u32 (a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32_t a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_x_u32 (a, b, 4, p);
+ return viwdupq_x_u32 (a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (mve_pred16_t p)
+{
+ return viwdupq_x_u32 (1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_n_u8.c
index 8137c62..c0ceead 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint32_t a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_x_n_u8 (a, b, 8, p);
+ return viwdupq_x_n_u8 (a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint32_t a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_x_u8 (a, b, 8, p);
+ return viwdupq_x_u8 (a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (mve_pred16_t p)
+{
+ return viwdupq_x_u8 (1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u16.c
index d7aa141..265aef4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
-foo (uint32_t * a, uint32_t b, mve_pred16_t p)
+foo (uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_x_wb_u16 (a, b, 8, p);
+ return viwdupq_x_wb_u16 (a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
-foo1 (uint32_t * a, uint32_t b, mve_pred16_t p)
+foo1 (uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_x_u16 (a, b, 8, p);
+ return viwdupq_x_u16 (a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (mve_pred16_t p)
+{
+ return viwdupq_x_u16 (1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u32.c
index 7fe5696..585e410 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
-foo (uint32_t * a, uint32_t b, mve_pred16_t p)
+foo (uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_x_wb_u32 (a, b, 2, p);
+ return viwdupq_x_wb_u32 (a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
-foo1 (uint32_t * a, uint32_t b, mve_pred16_t p)
+foo1 (uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_x_u32 (a, b, 2, p);
+ return viwdupq_x_u32 (a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u32 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (mve_pred16_t p)
+{
+ return viwdupq_x_u32 (1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u8.c
index 8e3ecef..ca39081 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
-foo (uint32_t * a, uint32_t b, mve_pred16_t p)
+foo (uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_x_wb_u8 (a, b, 4, p);
+ return viwdupq_x_wb_u8 (a, b, 1, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
-foo1 (uint32_t * a, uint32_t b, mve_pred16_t p)
+foo1 (uint32_t *a, uint32_t b, mve_pred16_t p)
{
- return viwdupq_x_u8 (a, b, 4, p);
+ return viwdupq_x_u8 (a, b, 1, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u8 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (mve_pred16_t p)
+{
+ return viwdupq_x_u8 (1, 1, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_f32.c
index f3219e2..1e57ca4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_f32.c
@@ -11,7 +11,7 @@ foo (uint32x4_t * addr, mve_pred16_t p)
}
/* { dg-final { scan-assembler "vldrw.32\tq\[0-9\]+, \\\[r\[0-9\]+\\\]" } } */
-/* { dg-final { scan-assembler "vmsr\t P0, r\[0-9\]+.*" } } */
+/* { dg-final { scan-assembler "vmsr\tp0, r\[0-9\]+.*" } } */
/* { dg-final { scan-assembler "vpst" } } */
/* { dg-final { scan-assembler "vldrwt.u32\tq\[0-9\]+, \\\[q\[0-9\]+, #\[0-9\]+\\\]!" } } */
/* { dg-final { scan-assembler "vstrw.32\tq\[0-9\]+, \\\[r\[0-9\]+\\\]" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_s32.c
index 4d093d2..f8d77fd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_s32.c
@@ -11,7 +11,7 @@ foo (uint32x4_t * addr, mve_pred16_t p)
}
/* { dg-final { scan-assembler "vldrw.32\tq\[0-9\]+, \\\[r\[0-9\]+\\\]" } } */
-/* { dg-final { scan-assembler "vmsr\t P0, r\[0-9\]+.*" } } */
+/* { dg-final { scan-assembler "vmsr\tp0, r\[0-9\]+.*" } } */
/* { dg-final { scan-assembler "vpst" } } */
/* { dg-final { scan-assembler "vldrwt.u32\tq\[0-9\]+, \\\[q\[0-9\]+, #\[0-9\]+\\\]!" } } */
/* { dg-final { scan-assembler "vstrw.32\tq\[0-9\]+, \\\[r\[0-9\]+\\\]" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_u32.c
index e796522..8a0e109 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_u32.c
@@ -11,7 +11,7 @@ foo (uint32x4_t * addr, mve_pred16_t p)
}
/* { dg-final { scan-assembler "vldrw.32\tq\[0-9\]+, \\\[r\[0-9\]+\\\]" } } */
-/* { dg-final { scan-assembler "vmsr\t P0, r\[0-9\]+.*" } } */
+/* { dg-final { scan-assembler "vmsr\tp0, r\[0-9\]+.*" } } */
/* { dg-final { scan-assembler "vpst" } } */
/* { dg-final { scan-assembler "vldrwt.u32\tq\[0-9\]+, \\\[q\[0-9\]+, #\[0-9\]+\\\]!" } } */
/* { dg-final { scan-assembler "vstrw.32\tq\[0-9\]+, \\\[r\[0-9\]+\\\]" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_m_s16.c
index 48d2132..6d01117 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_m_s16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxat.s16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vmaxaq_m_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxat.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxat.s16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vmaxaq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_m_s32.c
index 4927381..f8f960a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_m_s32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxat.s32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vmaxaq_m_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxat.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxat.s32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vmaxaq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_m_s8.c
index 5ecdb2c..69313d5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_m_s8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxat.s8 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vmaxaq_m_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxat.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxat.s8 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vmaxaq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_s16.c
index f9a9f89..aefe76a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxa.s16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, int16x8_t b)
{
return vmaxaq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vmaxa.s16" } } */
+/*
+**foo1:
+** ...
+** vmaxa.s16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, int16x8_t b)
{
return vmaxaq (a, b);
}
-/* { dg-final { scan-assembler "vmaxa.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_s32.c
index efe2fc1..f5e018e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxa.s32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, int32x4_t b)
{
return vmaxaq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vmaxa.s32" } } */
+/*
+**foo1:
+** ...
+** vmaxa.s32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, int32x4_t b)
{
return vmaxaq (a, b);
}
-/* { dg-final { scan-assembler "vmaxa.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_s8.c
index 5c2e35f..186b92a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxaq_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxa.s8 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, int8x16_t b)
{
return vmaxaq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vmaxa.s8" } } */
+/*
+**foo1:
+** ...
+** vmaxa.s8 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, int8x16_t b)
{
return vmaxaq (a, b);
}
-/* { dg-final { scan-assembler "vmaxa.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_p_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_p_s16.c
index 74ffad4..10478e9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_p_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_p_s16.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxavt.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo (uint16_t a, int16x8_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (uint16_t a, int16x8_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxavt.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo1 (uint16_t a, int16x8_t b, mve_pred16_t p)
{
return vmaxavq_p (a, b, p);
}
-
-int16_t
-foo2 (uint8_t a, int16x8_t b, mve_pred16_t p)
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxavt.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint16_t
+foo2 (int16x8_t b, mve_pred16_t p)
{
- return vmaxavq_p (a, b, p);
+ return vmaxavq_p (1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxavt.s16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_p_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_p_s32.c
index 40800b0..d43afbc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_p_s32.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxavt.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, int32x4_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (uint32_t a, int32x4_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxavt.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, int32x4_t b, mve_pred16_t p)
{
return vmaxavq_p (a, b, p);
}
-
-int32_t
-foo2 (uint16_t a, int32x4_t b, mve_pred16_t p)
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxavt.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (int32x4_t b, mve_pred16_t p)
{
- return vmaxavq_p (a, b, p);
+ return vmaxavq_p (1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxavt.s32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_p_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_p_s8.c
index 7638737..beb34db 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_p_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_p_s8.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxavt.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo (uint8_t a, int8x16_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (uint8_t a, int8x16_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxavt.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo1 (uint8_t a, int8x16_t b, mve_pred16_t p)
{
return vmaxavq_p (a, b, p);
}
-
-int8_t
-foo2 (uint32_t a, int8x16_t b, mve_pred16_t p)
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxavt.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint8_t
+foo2 (int8x16_t b, mve_pred16_t p)
{
- return vmaxavq_p (a, b, p);
+ return vmaxavq_p (1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxavt.s8" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_s16.c
index 0dca149..b997f30 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_s16.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxav.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo (uint16_t a, int16x8_t b)
{
@@ -11,18 +22,32 @@ foo (uint16_t a, int16x8_t b)
}
+/*
+**foo1:
+** ...
+** vmaxav.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo1 (uint16_t a, int16x8_t b)
{
return vmaxavq (a, b);
}
-
-int16_t
-foo2 (uint8_t a, int16x8_t b)
+/*
+**foo2:
+** ...
+** vmaxav.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint16_t
+foo2 (int16x8_t b)
{
- return vmaxavq (a, b);
+ return vmaxavq (1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxav.s16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_s32.c
index f419a77..e969f57 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_s32.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxav.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, int32x4_t b)
{
@@ -11,18 +22,32 @@ foo (uint32_t a, int32x4_t b)
}
+/*
+**foo1:
+** ...
+** vmaxav.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, int32x4_t b)
{
return vmaxavq (a, b);
}
-
-int32_t
-foo2 (uint16_t a, int32x4_t b)
+/*
+**foo2:
+** ...
+** vmaxav.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (int32x4_t b)
{
- return vmaxavq (a, b);
+ return vmaxavq (1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxav.s32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_s8.c
index 214ad88..e668c37 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxavq_s8.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxav.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo (uint8_t a, int8x16_t b)
{
@@ -11,18 +22,32 @@ foo (uint8_t a, int8x16_t b)
}
+/*
+**foo1:
+** ...
+** vmaxav.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo1 (uint8_t a, int8x16_t b)
{
return vmaxavq (a, b);
}
-
-int8_t
-foo2 (uint32_t a, int8x16_t b)
+/*
+**foo2:
+** ...
+** vmaxav.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint8_t
+foo2 (int8x16_t b)
{
- return vmaxavq (a, b);
+ return vmaxavq (1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxav.s8" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_f16.c
index f197071..1f6902e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_f16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxnma.f16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b)
{
return vmaxnmaq_f16 (a, b);
}
-/* { dg-final { scan-assembler "vmaxnma.f16" } } */
+/*
+**foo1:
+** ...
+** vmaxnma.f16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16x8_t b)
{
return vmaxnmaq (a, b);
}
-/* { dg-final { scan-assembler "vmaxnma.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_f32.c
index 94fc3a2..dc79d1b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_f32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxnma.f32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b)
{
return vmaxnmaq_f32 (a, b);
}
-/* { dg-final { scan-assembler "vmaxnma.f32" } } */
+/*
+**foo1:
+** ...
+** vmaxnma.f32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32x4_t b)
{
return vmaxnmaq (a, b);
}
-/* { dg-final { scan-assembler "vmaxnma.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f16.c
index b2e82f5..aa6d3a5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmat.f16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vmaxnmaq_m_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxnmat.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmat.f16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vmaxnmaq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f32.c
index 8fa7344..8637c6e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmat.f32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vmaxnmaq_m_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxnmat.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmat.f32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vmaxnmaq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_f16.c
index 6d8cf19..7e3708c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_f16.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxnmav.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo (float16_t a, float16x8_t b)
{
@@ -11,18 +22,32 @@ foo (float16_t a, float16x8_t b)
}
+/*
+**foo1:
+** ...
+** vmaxnmav.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo1 (float16_t a, float16x8_t b)
{
return vmaxnmavq (a, b);
}
-
+/*
+**foo2:
+** ...
+** vmaxnmav.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
-foo2 (float32_t a, float16x8_t b)
+foo2 (float16x8_t b)
{
- return vmaxnmavq (a, b);
+ return vmaxnmavq (1.1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxnmav.f16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_f32.c
index ef79030..5f63fa5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_f32.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxnmav.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo (float32_t a, float32x4_t b)
{
@@ -11,18 +22,32 @@ foo (float32_t a, float32x4_t b)
}
+/*
+**foo1:
+** ...
+** vmaxnmav.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo1 (float32_t a, float32x4_t b)
{
return vmaxnmavq (a, b);
}
-
+/*
+**foo2:
+** ...
+** vmaxnmav.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
-foo2 (float16_t a, float32x4_t b)
+foo2 (float32x4_t b)
{
- return vmaxnmavq (a, b);
+ return vmaxnmavq (1.1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxnmav.f32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f16.c
index f7f39f5..1cc89f8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f16.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmavt.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo (float16_t a, float16x8_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (float16_t a, float16x8_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmavt.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo1 (float16_t a, float16x8_t b, mve_pred16_t p)
{
return vmaxnmavq_p (a, b, p);
}
-
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmavt.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
-foo2 (float32_t a, float16x8_t b, mve_pred16_t p)
+foo2 (float16x8_t b, mve_pred16_t p)
{
- return vmaxnmavq_p (a, b, p);
+ return vmaxnmavq_p (1.1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxnmavt.f16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f32.c
index 341f625..339be11 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f32.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmavt.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo (float32_t a, float32x4_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (float32_t a, float32x4_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmavt.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo1 (float32_t a, float32x4_t b, mve_pred16_t p)
{
return vmaxnmavq_p (a, b, p);
}
-
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmavt.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
-foo2 (float16_t a, float32x4_t b, mve_pred16_t p)
+foo2 (float32x4_t b, mve_pred16_t p)
{
- return vmaxnmavq_p (a, b, p);
+ return vmaxnmavq_p (1.1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxnmavt.f32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_f16.c
index 59a8070..2c2ac3c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_f16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxnm.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b)
{
return vmaxnmq_f16 (a, b);
}
-/* { dg-final { scan-assembler "vmaxnm.f16" } } */
+/*
+**foo1:
+** ...
+** vmaxnm.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16x8_t b)
{
return vmaxnmq (a, b);
}
-/* { dg-final { scan-assembler "vmaxnm.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_f32.c
index 5db42bd..18f4f081 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_f32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxnm.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b)
{
return vmaxnmq_f32 (a, b);
}
-/* { dg-final { scan-assembler "vmaxnm.f32" } } */
+/*
+**foo1:
+** ...
+** vmaxnm.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32x4_t b)
{
return vmaxnmq (a, b);
}
-/* { dg-final { scan-assembler "vmaxnm.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_m_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_m_f16.c
index 4668fd0..5cf0d72 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_m_f16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t inactive, float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vmaxnmq_m_f16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxnmt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t inactive, float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vmaxnmq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxnmt.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_m_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_m_f32.c
index 9e8ccbc..4a10383 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_m_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_m_f32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t inactive, float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vmaxnmq_m_f32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxnmt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t inactive, float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vmaxnmq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxnmt.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_x_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_x_f16.c
index ecca606..c52bfce 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_x_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_x_f16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vmaxnmq_x_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxnmt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vmaxnmq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_x_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_x_f32.c
index c3965dd..a940a08 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_x_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmq_x_f32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vmaxnmq_x_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxnmt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vmaxnmq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_f16.c
index 80bd1d4..d2a6744 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_f16.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxnmv.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo (float16_t a, float16x8_t b)
{
@@ -11,18 +22,32 @@ foo (float16_t a, float16x8_t b)
}
+/*
+**foo1:
+** ...
+** vmaxnmv.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo1 (float16_t a, float16x8_t b)
{
return vmaxnmvq (a, b);
}
-
+/*
+**foo2:
+** ...
+** vmaxnmv.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
-foo2 (float32_t a, float16x8_t b)
+foo2 (float16x8_t b)
{
- return vmaxnmvq (a, b);
+ return vmaxnmvq (1.1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxnmv.f16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_f32.c
index bb2fc46..b566206 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_f32.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxnmv.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo (float32_t a, float32x4_t b)
{
@@ -11,18 +22,32 @@ foo (float32_t a, float32x4_t b)
}
+/*
+**foo1:
+** ...
+** vmaxnmv.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo1 (float32_t a, float32x4_t b)
{
return vmaxnmvq (a, b);
}
-
+/*
+**foo2:
+** ...
+** vmaxnmv.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
-foo2 (float16_t a, float32x4_t b)
+foo2 (float32x4_t b)
{
- return vmaxnmvq (a, b);
+ return vmaxnmvq (1.1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxnmv.f32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f16.c
index 3efe203..9c4df6b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f16.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmvt.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo (float16_t a, float16x8_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (float16_t a, float16x8_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmvt.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo1 (float16_t a, float16x8_t b, mve_pred16_t p)
{
return vmaxnmvq_p (a, b, p);
}
-
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmvt.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
-foo2 (float32_t a, float16x8_t b, mve_pred16_t p)
+foo2 (float16x8_t b, mve_pred16_t p)
{
- return vmaxnmvq_p (a, b, p);
+ return vmaxnmvq_p (1.1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxnmvt.f16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f32.c
index 6c13247..fa4b583 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f32.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmvt.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo (float32_t a, float32x4_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (float32_t a, float32x4_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmvt.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo1 (float32_t a, float32x4_t b, mve_pred16_t p)
{
return vmaxnmvq_p (a, b, p);
}
-
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxnmvt.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
-foo2 (float16_t a, float32x4_t b, mve_pred16_t p)
+foo2 (float32x4_t b, mve_pred16_t p)
{
- return vmaxnmvq_p (a, b, p);
+ return vmaxnmvq_p (1.1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxnmvt.f32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_s16.c
index 2791ed4..5ae4d8a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vmaxq_m_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vmaxq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_s32.c
index 27f7d5d..6963a98 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vmaxq_m_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vmaxq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_s8.c
index 23b7569..e706430 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vmaxq_m_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vmaxq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_u16.c
index 61e51e3..41117d4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_u16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vmaxq_m_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vmaxq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_u32.c
index 23df7ee..9ce6f83 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_u32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vmaxq_m_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vmaxq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_u8.c
index 138d5c8..fcd90fb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_m_u8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vmaxq_m_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vmaxq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_s16.c
index a42fc82..7c532dc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmax.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b)
{
return vmaxq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vmax.s16" } } */
+/*
+**foo1:
+** ...
+** vmax.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b)
{
return vmaxq (a, b);
}
-/* { dg-final { scan-assembler "vmax.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_s32.c
index 14c094a..e8e3a4e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmax.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b)
{
return vmaxq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vmax.s32" } } */
+/*
+**foo1:
+** ...
+** vmax.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b)
{
return vmaxq (a, b);
}
-/* { dg-final { scan-assembler "vmax.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_s8.c
index 0540a27..ad529c0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmax.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b)
{
return vmaxq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vmax.s8" } } */
+/*
+**foo1:
+** ...
+** vmax.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vmaxq (a, b);
}
-/* { dg-final { scan-assembler "vmax.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_u16.c
index 6b9b5a7..04d8c64 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_u16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmax.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b)
{
return vmaxq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vmax.u16" } } */
+/*
+**foo1:
+** ...
+** vmax.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b)
{
return vmaxq (a, b);
}
-/* { dg-final { scan-assembler "vmax.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_u32.c
index 3112302..d68ae2b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_u32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmax.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b)
{
return vmaxq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vmax.u32" } } */
+/*
+**foo1:
+** ...
+** vmax.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b)
{
return vmaxq (a, b);
}
-/* { dg-final { scan-assembler "vmax.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_u8.c
index b1baa50..944353e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_u8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmax.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b)
{
return vmaxq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vmax.u8" } } */
+/*
+**foo1:
+** ...
+** vmax.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b)
{
return vmaxq (a, b);
}
-/* { dg-final { scan-assembler "vmax.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_s16.c
index 9d92f2c..843a4cc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_s16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vmaxq_x_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vmaxq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_s32.c
index 200fd4b..ff81a39 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_s32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vmaxq_x_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vmaxq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_s8.c
index 2fe7525..6856374 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_s8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vmaxq_x_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vmaxq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_u16.c
index 967622e..85c21e6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_u16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vmaxq_x_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vmaxq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_u32.c
index 56b5d8f..b45d7bd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_u32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vmaxq_x_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vmaxq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_u8.c
index 1816f95..de8b2d4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxq_x_u8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vmaxq_x_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmaxt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vmaxq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_s16.c
index 657efc5..ac29f91 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_s16.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxvt.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int16_t
foo (int16_t a, int16x8_t b, mve_pred16_t p)
{
@@ -11,18 +26,24 @@ foo (int16_t a, int16x8_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxvt.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int16_t
foo1 (int16_t a, int16x8_t b, mve_pred16_t p)
{
return vmaxvq_p (a, b, p);
}
-
-int16_t
-foo2 (int8_t a, int16x8_t b, mve_pred16_t p)
-{
- return vmaxvq_p (a, b, p);
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxvt.s16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_s32.c
index 5882351..4290484 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_s32.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxvt.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int32_t a, int32x4_t b, mve_pred16_t p)
{
@@ -11,18 +26,24 @@ foo (int32_t a, int32x4_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxvt.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int32_t a, int32x4_t b, mve_pred16_t p)
{
return vmaxvq_p (a, b, p);
}
-
-int32_t
-foo2 (int16_t a, int32x4_t b, mve_pred16_t p)
-{
- return vmaxvq_p (a, b, p);
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxvt.s32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_s8.c
index 3737ecd..6a9b1ce 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_s8.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxvt.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int8_t
foo (int8_t a, int8x16_t b, mve_pred16_t p)
{
@@ -11,18 +26,24 @@ foo (int8_t a, int8x16_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxvt.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int8_t
foo1 (int8_t a, int8x16_t b, mve_pred16_t p)
{
return vmaxvq_p (a, b, p);
}
-
-int8_t
-foo2 (int32_t a, int8x16_t b, mve_pred16_t p)
-{
- return vmaxvq_p (a, b, p);
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxvt.s8" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_u16.c
index 348cf39..3cc1dbb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_u16.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxvt.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo (uint16_t a, uint16x8_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (uint16_t a, uint16x8_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxvt.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo1 (uint16_t a, uint16x8_t b, mve_pred16_t p)
{
return vmaxvq_p (a, b, p);
}
-
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxvt.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
-foo2 (uint32_t a, uint16x8_t b, mve_pred16_t p)
+foo2 (uint16x8_t b, mve_pred16_t p)
{
- return vmaxvq_p (a, b, p);
+ return vmaxvq_p (1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxvt.u16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_u32.c
index f2e9762..99264f3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_u32.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxvt.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint32x4_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (uint32_t a, uint32x4_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxvt.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint32x4_t b, mve_pred16_t p)
{
return vmaxvq_p (a, b, p);
}
-
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxvt.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo2 (uint8_t a, uint32x4_t b, mve_pred16_t p)
+foo2 (uint32x4_t b, mve_pred16_t p)
{
- return vmaxvq_p (a, b, p);
+ return vmaxvq_p (1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxvt.u32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_u8.c
index 7df5b63..6aac76b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_p_u8.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxvt.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo (uint8_t a, uint8x16_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (uint8_t a, uint8x16_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxvt.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo1 (uint8_t a, uint8x16_t b, mve_pred16_t p)
{
return vmaxvq_p (a, b, p);
}
-
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmaxvt.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
-foo2 (uint16_t a, uint8x16_t b, mve_pred16_t p)
+foo2 (uint8x16_t b, mve_pred16_t p)
{
- return vmaxvq_p (a, b, p);
+ return vmaxvq_p (1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxvt.u8" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_s16.c
index 8412452..18938d8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_s16.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxv.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int16_t
foo (int16_t a, int16x8_t b)
{
@@ -11,18 +22,20 @@ foo (int16_t a, int16x8_t b)
}
+/*
+**foo1:
+** ...
+** vmaxv.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int16_t
foo1 (int16_t a, int16x8_t b)
{
return vmaxvq (a, b);
}
-
-int16_t
-foo2 (int8_t a, int16x8_t b)
-{
- return vmaxvq (a, b);
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxv.s16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_s32.c
index 09f4909..26ee10b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_s32.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxv.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int32_t a, int32x4_t b)
{
@@ -11,18 +22,20 @@ foo (int32_t a, int32x4_t b)
}
+/*
+**foo1:
+** ...
+** vmaxv.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int32_t a, int32x4_t b)
{
return vmaxvq (a, b);
}
-
-int32_t
-foo2 (int16_t a, int32x4_t b)
-{
- return vmaxvq (a, b);
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxv.s32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_s8.c
index a087bbc..b5bbfc3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_s8.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxv.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int8_t
foo (int8_t a, int8x16_t b)
{
@@ -11,18 +22,20 @@ foo (int8_t a, int8x16_t b)
}
+/*
+**foo1:
+** ...
+** vmaxv.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int8_t
foo1 (int8_t a, int8x16_t b)
{
return vmaxvq (a, b);
}
-
-int8_t
-foo2 (int32_t a, int8x16_t b)
-{
- return vmaxvq (a, b);
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxv.s8" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_u16.c
index 47fe0d1..f806cfa 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_u16.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxv.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo (uint16_t a, uint16x8_t b)
{
@@ -11,18 +22,32 @@ foo (uint16_t a, uint16x8_t b)
}
+/*
+**foo1:
+** ...
+** vmaxv.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo1 (uint16_t a, uint16x8_t b)
{
return vmaxvq (a, b);
}
-
+/*
+**foo2:
+** ...
+** vmaxv.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
-foo2 (uint32_t a, uint16x8_t b)
+foo2 (uint16x8_t b)
{
- return vmaxvq (a, b);
+ return vmaxvq (1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxv.u16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_u32.c
index aa723da..b46dc06 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_u32.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxv.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint32x4_t b)
{
@@ -11,18 +22,32 @@ foo (uint32_t a, uint32x4_t b)
}
+/*
+**foo1:
+** ...
+** vmaxv.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint32x4_t b)
{
return vmaxvq (a, b);
}
-
+/*
+**foo2:
+** ...
+** vmaxv.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo2 (uint8_t a, uint32x4_t b)
+foo2 (uint32x4_t b)
{
- return vmaxvq (a, b);
+ return vmaxvq (1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxv.u32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_u8.c
index 3aae785..1a64f55 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmaxvq_u8.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmaxv.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo (uint8_t a, uint8x16_t b)
{
@@ -11,18 +22,32 @@ foo (uint8_t a, uint8x16_t b)
}
+/*
+**foo1:
+** ...
+** vmaxv.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo1 (uint8_t a, uint8x16_t b)
{
return vmaxvq (a, b);
}
-
+/*
+**foo2:
+** ...
+** vmaxv.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
-foo2 (uint16_t a, uint8x16_t b)
+foo2 (uint8x16_t b)
{
- return vmaxvq (a, b);
+ return vmaxvq (1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vmaxv.u8" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_m_s16.c
index 0324110..50a98bf 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_m_s16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminat.s16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vminaq_m_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vminat.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminat.s16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vminaq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_m_s32.c
index a2886d4..3870cf5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_m_s32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminat.s32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vminaq_m_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vminat.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminat.s32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vminaq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_m_s8.c
index 95eb038..74a3122 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_m_s8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminat.s8 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vminaq_m_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vminat.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminat.s8 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vminaq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_s16.c
index 3a157e0..f78ee9d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmina.s16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, int16x8_t b)
{
return vminaq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vmina.s16" } } */
+/*
+**foo1:
+** ...
+** vmina.s16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, int16x8_t b)
{
return vminaq (a, b);
}
-/* { dg-final { scan-assembler "vmina.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_s32.c
index 5c732c6..cbe18e0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmina.s32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, int32x4_t b)
{
return vminaq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vmina.s32" } } */
+/*
+**foo1:
+** ...
+** vmina.s32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, int32x4_t b)
{
return vminaq (a, b);
}
-/* { dg-final { scan-assembler "vmina.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_s8.c
index 2e4dad1..e803095 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminaq_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmina.s8 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, int8x16_t b)
{
return vminaq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vmina.s8" } } */
+/*
+**foo1:
+** ...
+** vmina.s8 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, int8x16_t b)
{
return vminaq (a, b);
}
-/* { dg-final { scan-assembler "vmina.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_p_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_p_s16.c
index 9303ae0..ff77b8e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_p_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_p_s16.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminavt.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo (uint16_t a, int16x8_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (uint16_t a, int16x8_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminavt.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo1 (uint16_t a, int16x8_t b, mve_pred16_t p)
{
return vminavq_p (a, b, p);
}
-
-int16_t
-foo2 (uint8_t a, int16x8_t b, mve_pred16_t p)
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminavt.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint16_t
+foo2 (int16x8_t b, mve_pred16_t p)
{
- return vminavq_p (a, b, p);
+ return vminavq_p (1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminavt.s16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_p_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_p_s32.c
index 36247f6..4c1433d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_p_s32.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminavt.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, int32x4_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (uint32_t a, int32x4_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminavt.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, int32x4_t b, mve_pred16_t p)
{
return vminavq_p (a, b, p);
}
-
-int32_t
-foo2 (uint16_t a, int32x4_t b, mve_pred16_t p)
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminavt.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (int32x4_t b, mve_pred16_t p)
{
- return vminavq_p (a, b, p);
+ return vminavq_p (1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminavt.s32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_p_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_p_s8.c
index d336161..ef923f8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_p_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_p_s8.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminavt.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo (uint8_t a, int8x16_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (uint8_t a, int8x16_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminavt.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo1 (uint8_t a, int8x16_t b, mve_pred16_t p)
{
return vminavq_p (a, b, p);
}
-
-int8_t
-foo2 (uint32_t a, int8x16_t b, mve_pred16_t p)
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminavt.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint8_t
+foo2 (int8x16_t b, mve_pred16_t p)
{
- return vminavq_p (a, b, p);
+ return vminavq_p (1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminavt.s8" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_s16.c
index 17e4edc..3f66002 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_s16.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminav.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo (uint16_t a, int16x8_t b)
{
@@ -11,18 +22,32 @@ foo (uint16_t a, int16x8_t b)
}
+/*
+**foo1:
+** ...
+** vminav.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo1 (uint16_t a, int16x8_t b)
{
return vminavq (a, b);
}
-
-int16_t
-foo2 (uint8_t a, int16x8_t b)
+/*
+**foo2:
+** ...
+** vminav.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint16_t
+foo2 (int16x8_t b)
{
- return vminavq (a, b);
+ return vminavq (1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminav.s16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_s32.c
index 032d02b..69daa32 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_s32.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminav.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, int32x4_t b)
{
@@ -11,18 +22,32 @@ foo (uint32_t a, int32x4_t b)
}
+/*
+**foo1:
+** ...
+** vminav.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, int32x4_t b)
{
return vminavq (a, b);
}
-
-int32_t
-foo2 (uint16_t a, int32x4_t b)
+/*
+**foo2:
+** ...
+** vminav.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (int32x4_t b)
{
- return vminavq (a, b);
+ return vminavq (1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminav.s32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_s8.c
index 2a2bb3d6..95fb6cf 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminavq_s8.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminav.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo (uint8_t a, int8x16_t b)
{
@@ -11,18 +22,32 @@ foo (uint8_t a, int8x16_t b)
}
+/*
+**foo1:
+** ...
+** vminav.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo1 (uint8_t a, int8x16_t b)
{
return vminavq (a, b);
}
-
-int8_t
-foo2 (uint32_t a, int8x16_t b)
+/*
+**foo2:
+** ...
+** vminav.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint8_t
+foo2 (int8x16_t b)
{
- return vminavq (a, b);
+ return vminavq (1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminav.s8" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_f16.c
index cf32186..19c736c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_f16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminnma.f16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b)
{
return vminnmaq_f16 (a, b);
}
-/* { dg-final { scan-assembler "vminnma.f16" } } */
+/*
+**foo1:
+** ...
+** vminnma.f16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16x8_t b)
{
return vminnmaq (a, b);
}
-/* { dg-final { scan-assembler "vminnma.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_f32.c
index 1c3f19c..8dc7ea9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_f32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminnma.f32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b)
{
return vminnmaq_f32 (a, b);
}
-/* { dg-final { scan-assembler "vminnma.f32" } } */
+/*
+**foo1:
+** ...
+** vminnma.f32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32x4_t b)
{
return vminnmaq (a, b);
}
-/* { dg-final { scan-assembler "vminnma.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_m_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_m_f16.c
index 4423903..c57b384 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_m_f16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmat.f16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vminnmaq_m_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vminnmat.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmat.f16 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vminnmaq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_m_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_m_f32.c
index 683f40a..8c51328 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_m_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmaq_m_f32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmat.f32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vminnmaq_m_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vminnmat.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmat.f32 q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vminnmaq_m (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_f16.c
index fadb23e..79503f2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_f16.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminnmav.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo (float16_t a, float16x8_t b)
{
@@ -11,18 +22,32 @@ foo (float16_t a, float16x8_t b)
}
+/*
+**foo1:
+** ...
+** vminnmav.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo1 (float16_t a, float16x8_t b)
{
return vminnmavq (a, b);
}
-
+/*
+**foo2:
+** ...
+** vminnmav.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
-foo2 (float32_t a, float16x8_t b)
+foo2 (float16x8_t b)
{
- return vminnmavq (a, b);
+ return vminnmavq (1.1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminnmav.f16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_f32.c
index 84714a9..34dd9dd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_f32.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminnmav.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo (float32_t a, float32x4_t b)
{
@@ -11,18 +22,32 @@ foo (float32_t a, float32x4_t b)
}
+/*
+**foo1:
+** ...
+** vminnmav.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo1 (float32_t a, float32x4_t b)
{
return vminnmavq (a, b);
}
-
+/*
+**foo2:
+** ...
+** vminnmav.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
-foo2 (float16_t a, float32x4_t b)
+foo2 (float32x4_t b)
{
- return vminnmavq (a, b);
+ return vminnmavq (1.1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminnmav.f32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_p_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_p_f16.c
index c79fa30..ae7931f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_p_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_p_f16.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmavt.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo (float16_t a, float16x8_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (float16_t a, float16x8_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmavt.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo1 (float16_t a, float16x8_t b, mve_pred16_t p)
{
return vminnmavq_p (a, b, p);
}
-
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmavt.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
-foo2 (float32_t a, float16x8_t b, mve_pred16_t p)
+foo2 (float16x8_t b, mve_pred16_t p)
{
- return vminnmavq_p (a, b, p);
+ return vminnmavq_p (1.1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminnmavt.f16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_p_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_p_f32.c
index bea04c7..2d6aad6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_p_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmavq_p_f32.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmavt.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo (float32_t a, float32x4_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (float32_t a, float32x4_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmavt.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo1 (float32_t a, float32x4_t b, mve_pred16_t p)
{
return vminnmavq_p (a, b, p);
}
-
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmavt.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
-foo2 (float16_t a, float32x4_t b, mve_pred16_t p)
+foo2 (float32x4_t b, mve_pred16_t p)
{
- return vminnmavq_p (a, b, p);
+ return vminnmavq_p (1.1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminnmavt.f32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_f16.c
index 18d4a4c..251d35e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_f16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminnm.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b)
{
return vminnmq_f16 (a, b);
}
-/* { dg-final { scan-assembler "vminnm.f16" } } */
+/*
+**foo1:
+** ...
+** vminnm.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16x8_t b)
{
return vminnmq (a, b);
}
-/* { dg-final { scan-assembler "vminnm.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_f32.c
index 34144ca..7d77e215 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_f32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminnm.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b)
{
return vminnmq_f32 (a, b);
}
-/* { dg-final { scan-assembler "vminnm.f32" } } */
+/*
+**foo1:
+** ...
+** vminnm.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32x4_t b)
{
return vminnmq (a, b);
}
-/* { dg-final { scan-assembler "vminnm.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_m_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_m_f16.c
index e5533d2..fb74199 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_m_f16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t inactive, float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vminnmq_m_f16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vminnmt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t inactive, float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vminnmq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vminnmt.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_m_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_m_f32.c
index 382d16c..fa3c47c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_m_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_m_f32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t inactive, float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vminnmq_m_f32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vminnmt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t inactive, float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vminnmq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vminnmt.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_x_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_x_f16.c
index 04d606c..632dcaa 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_x_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_x_f16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vminnmq_x_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vminnmt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vminnmq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_x_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_x_f32.c
index 87cd970..5c29068 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_x_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmq_x_f32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vminnmq_x_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vminnmt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vminnmq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_f16.c
index 0eb3a4a..2ef5020 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_f16.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminnmv.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo (float16_t a, float16x8_t b)
{
@@ -11,18 +22,32 @@ foo (float16_t a, float16x8_t b)
}
+/*
+**foo1:
+** ...
+** vminnmv.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo1 (float16_t a, float16x8_t b)
{
return vminnmvq (a, b);
}
-
+/*
+**foo2:
+** ...
+** vminnmv.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
-foo2 (float32_t a, float16x8_t b)
+foo2 (float16x8_t b)
{
- return vminnmvq (a, b);
+ return vminnmvq (1.1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminnmv.f16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_f32.c
index f318350..1a65fca 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_f32.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminnmv.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo (float32_t a, float32x4_t b)
{
@@ -11,18 +22,32 @@ foo (float32_t a, float32x4_t b)
}
+/*
+**foo1:
+** ...
+** vminnmv.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo1 (float32_t a, float32x4_t b)
{
return vminnmvq (a, b);
}
-
+/*
+**foo2:
+** ...
+** vminnmv.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
-foo2 (float16_t a, float32x4_t b)
+foo2 (float32x4_t b)
{
- return vminnmvq (a, b);
+ return vminnmvq (1.1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminnmv.f32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_p_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_p_f16.c
index 16f6ac5..8cb6190 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_p_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_p_f16.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmvt.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo (float16_t a, float16x8_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (float16_t a, float16x8_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmvt.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
foo1 (float16_t a, float16x8_t b, mve_pred16_t p)
{
return vminnmvq_p (a, b, p);
}
-
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmvt.f16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float16_t
-foo2 (float32_t a, float16x8_t b, mve_pred16_t p)
+foo2 (float16x8_t b, mve_pred16_t p)
{
- return vminnmvq_p (a, b, p);
+ return vminnmvq_p (1.1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminnmvt.f16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_p_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_p_f32.c
index a8e4f9f..93bad1e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_p_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminnmvq_p_f32.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmvt.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo (float32_t a, float32x4_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (float32_t a, float32x4_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmvt.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
foo1 (float32_t a, float32x4_t b, mve_pred16_t p)
{
return vminnmvq_p (a, b, p);
}
-
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminnmvt.f32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
float32_t
-foo2 (float16_t a, float32x4_t b, mve_pred16_t p)
+foo2 (float32x4_t b, mve_pred16_t p)
{
- return vminnmvq_p (a, b, p);
+ return vminnmvq_p (1.1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminnmvt.f32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_s16.c
index f257ddc..1b3bbe1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vminq_m_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vminq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_s32.c
index 957da71..b45cc91 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vminq_m_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vminq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_s8.c
index fea8bfd..fa7c43b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vminq_m_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vminq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_u16.c
index 7cc19a7..65dbf13 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_u16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vminq_m_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vminq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_u32.c
index 301fbfc..256ee84 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_u32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vminq_m_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vminq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_u8.c
index 7a65b35..9399ac4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_m_u8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vminq_m_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vminq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_s16.c
index d46a3c4..8d3a948 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmin.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b)
{
return vminq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vmin.s16" } } */
+/*
+**foo1:
+** ...
+** vmin.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b)
{
return vminq (a, b);
}
-/* { dg-final { scan-assembler "vmin.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_s32.c
index 601e918..51970d6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmin.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b)
{
return vminq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vmin.s32" } } */
+/*
+**foo1:
+** ...
+** vmin.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b)
{
return vminq (a, b);
}
-/* { dg-final { scan-assembler "vmin.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_s8.c
index e2ae234..d5e671f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmin.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b)
{
return vminq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vmin.s8" } } */
+/*
+**foo1:
+** ...
+** vmin.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vminq (a, b);
}
-/* { dg-final { scan-assembler "vmin.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_u16.c
index 3cac573..ade8c01 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_u16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmin.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b)
{
return vminq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vmin.u16" } } */
+/*
+**foo1:
+** ...
+** vmin.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b)
{
return vminq (a, b);
}
-/* { dg-final { scan-assembler "vmin.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_u32.c
index ca3ef24..bb15d1b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_u32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmin.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b)
{
return vminq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vmin.u32" } } */
+/*
+**foo1:
+** ...
+** vmin.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b)
{
return vminq (a, b);
}
-/* { dg-final { scan-assembler "vmin.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_u8.c
index b7ef4db..ff9b232 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_u8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmin.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b)
{
return vminq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vmin.u8" } } */
+/*
+**foo1:
+** ...
+** vmin.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b)
{
return vminq (a, b);
}
-/* { dg-final { scan-assembler "vmin.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_s16.c
index af93c78..6ae37c5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_s16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vminq_x_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vminq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_s32.c
index 76f0831..395907d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_s32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vminq_x_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vminq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_s8.c
index fdd6e94..16f6ef3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_s8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vminq_x_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vminq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_u16.c
index 9842954..c25dc74 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_u16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vminq_x_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vminq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_u32.c
index 741e450..bf2764d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_u32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vminq_x_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vminq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_u8.c
index 13743fc..f4a3553 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminq_x_u8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vminq_x_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmint.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmint.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vminq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_s16.c
index 91bb63f..6562d6a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_s16.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminvt.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int16_t
foo (int16_t a, int16x8_t b, mve_pred16_t p)
{
@@ -11,18 +26,24 @@ foo (int16_t a, int16x8_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminvt.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int16_t
foo1 (int16_t a, int16x8_t b, mve_pred16_t p)
{
return vminvq_p (a, b, p);
}
-
-int16_t
-foo2 (int8_t a, int16x8_t b, mve_pred16_t p)
-{
- return vminvq_p (a, b, p);
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminvt.s16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_s32.c
index a846701..6e3715e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_s32.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminvt.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int32_t a, int32x4_t b, mve_pred16_t p)
{
@@ -11,18 +26,24 @@ foo (int32_t a, int32x4_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminvt.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int32_t a, int32x4_t b, mve_pred16_t p)
{
return vminvq_p (a, b, p);
}
-
-int32_t
-foo2 (int16_t a, int32x4_t b, mve_pred16_t p)
-{
- return vminvq_p (a, b, p);
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminvt.s32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_s8.c
index 716d414..dc06d0f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_s8.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminvt.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int8_t
foo (int8_t a, int8x16_t b, mve_pred16_t p)
{
@@ -11,18 +26,24 @@ foo (int8_t a, int8x16_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminvt.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int8_t
foo1 (int8_t a, int8x16_t b, mve_pred16_t p)
{
return vminvq_p (a, b, p);
}
-
-int8_t
-foo2 (int32_t a, int8x16_t b, mve_pred16_t p)
-{
- return vminvq_p (a, b, p);
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminvt.s8" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_u16.c
index cc7f8fe..16cc419 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_u16.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminvt.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo (uint16_t a, uint16x8_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (uint16_t a, uint16x8_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminvt.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo1 (uint16_t a, uint16x8_t b, mve_pred16_t p)
{
return vminvq_p (a, b, p);
}
-
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminvt.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
-foo2 (uint32_t a, uint16x8_t b, mve_pred16_t p)
+foo2 (uint16x8_t b, mve_pred16_t p)
{
- return vminvq_p (a, b, p);
+ return vminvq_p (1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminvt.u16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_u32.c
index 6bde0be..bef29dc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_u32.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminvt.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint32x4_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (uint32_t a, uint32x4_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminvt.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint32x4_t b, mve_pred16_t p)
{
return vminvq_p (a, b, p);
}
-
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminvt.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo2 (uint8_t a, uint32x4_t b, mve_pred16_t p)
+foo2 (uint32x4_t b, mve_pred16_t p)
{
- return vminvq_p (a, b, p);
+ return vminvq_p (1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminvt.u32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_u8.c
index bb89490..42beaee 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_p_u8.c
@@ -1,9 +1,24 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminvt.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo (uint8_t a, uint8x16_t b, mve_pred16_t p)
{
@@ -11,18 +26,40 @@ foo (uint8_t a, uint8x16_t b, mve_pred16_t p)
}
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminvt.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo1 (uint8_t a, uint8x16_t b, mve_pred16_t p)
{
return vminvq_p (a, b, p);
}
-
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vminvt.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
-foo2 (uint16_t a, uint8x16_t b, mve_pred16_t p)
+foo2 (uint8x16_t b, mve_pred16_t p)
{
- return vminvq_p (a, b, p);
+ return vminvq_p (1, b, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminvt.u8" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_s16.c
index 6d589aa..9fc314d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_s16.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminv.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int16_t
foo (int16_t a, int16x8_t b)
{
@@ -11,17 +22,20 @@ foo (int16_t a, int16x8_t b)
}
+/*
+**foo1:
+** ...
+** vminv.s16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int16_t
foo1 (int16_t a, int16x8_t b)
{
return vminvq (a, b);
}
-int16_t
-foo2 (int8_t a, int16x8_t b)
-{
- return vminvq (a, b);
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminv.s16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_s32.c
index 7c727d6..3546b69 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_s32.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminv.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo (int32_t a, int32x4_t b)
{
@@ -11,17 +22,20 @@ foo (int32_t a, int32x4_t b)
}
+/*
+**foo1:
+** ...
+** vminv.s32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
foo1 (int32_t a, int32x4_t b)
{
return vminvq (a, b);
}
-int32_t
-foo2 (int8_t a, int32x4_t b)
-{
- return vminvq (a, b);
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminv.s32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_s8.c
index 7630948..e512a7d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_s8.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminv.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int8_t
foo (int8_t a, int8x16_t b)
{
@@ -11,17 +22,20 @@ foo (int8_t a, int8x16_t b)
}
+/*
+**foo1:
+** ...
+** vminv.s8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
int8_t
foo1 (int8_t a, int8x16_t b)
{
return vminvq (a, b);
}
-int8_t
-foo2 (int32_t a, int8x16_t b)
-{
- return vminvq (a, b);
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminv.s8" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_u16.c
index 698975f..29746c3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_u16.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminv.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo (uint16_t a, uint16x8_t b)
{
@@ -11,18 +22,32 @@ foo (uint16_t a, uint16x8_t b)
}
+/*
+**foo1:
+** ...
+** vminv.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint16_t
foo1 (uint16_t a, uint16x8_t b)
{
return vminvq (a, b);
}
-
-uint8_t
-foo2 (uint32_t a, uint16x8_t b)
+/*
+**foo2:
+** ...
+** vminv.u16 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint16_t
+foo2 (uint16x8_t b)
{
- return vminvq (a, b);
+ return vminvq (1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminv.u16" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_u32.c
index 7489f81..d12764d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_u32.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminv.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo (uint32_t a, uint32x4_t b)
{
@@ -11,17 +22,32 @@ foo (uint32_t a, uint32x4_t b)
}
+/*
+**foo1:
+** ...
+** vminv.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
foo1 (uint32_t a, uint32x4_t b)
{
return vminvq (a, b);
}
+/*
+**foo2:
+** ...
+** vminv.u32 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo2 (uint16_t a, uint32x4_t b)
+foo2 (uint32x4_t b)
{
- return vminvq (a, b);
+ return vminvq (1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminv.u32" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_u8.c
index aa2b986..6017511 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vminvq_u8.c
@@ -1,9 +1,20 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vminv.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo (uint8_t a, uint8x16_t b)
{
@@ -11,18 +22,32 @@ foo (uint8_t a, uint8x16_t b)
}
+/*
+**foo1:
+** ...
+** vminv.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
uint8_t
foo1 (uint8_t a, uint8x16_t b)
{
return vminvq (a, b);
}
-
-uint16_t
-foo2 (uint32_t a, uint8x16_t b)
+/*
+**foo2:
+** ...
+** vminv.u8 (?:ip|fp|r[0-9]+), q[0-9]+(?: @.*|)
+** ...
+*/
+uint8_t
+foo2 (uint8x16_t b)
{
- return vminvq (a, b);
+ return vminvq (1, b);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler-not "__ARM_undef" } } */
-/* { dg-final { scan-assembler-times "vminv.u8" 3 } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s16.c
index e458204..258adfa 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.s16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo (int32_t a, int16x8_t b, int16x8_t c, mve_pred16_t p)
+foo (int32_t add, int16x8_t m1, int16x8_t m2, mve_pred16_t p)
{
- return vmladavaq_p_s16 (a, b, c, p);
+ return vmladavaq_p_s16 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vmladavat.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.s16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo1 (int32_t a, int16x8_t b, int16x8_t c, mve_pred16_t p)
+foo1 (int32_t add, int16x8_t m1, int16x8_t m2, mve_pred16_t p)
{
- return vmladavaq_p (a, b, c, p);
+ return vmladavaq_p (add, m1, m2, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmladavat.s16" } } */
-/* { dg-final { scan-assembler "vmladavat.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s32.c
index e354478..78d3333 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.s32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo (int32_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
+foo (int32_t add, int32x4_t m1, int32x4_t m2, mve_pred16_t p)
{
- return vmladavaq_p_s32 (a, b, c, p);
+ return vmladavaq_p_s32 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vmladavat.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.s32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo1 (int32_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
+foo1 (int32_t add, int32x4_t m1, int32x4_t m2, mve_pred16_t p)
{
- return vmladavaq_p (a, b, c, p);
+ return vmladavaq_p (add, m1, m2, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmladavat.s32" } } */
-/* { dg-final { scan-assembler "vmladavat.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s8.c
index 1d4ca722..1529e94 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.s8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo (int32_t a, int8x16_t b, int8x16_t c, mve_pred16_t p)
+foo (int32_t add, int8x16_t m1, int8x16_t m2, mve_pred16_t p)
{
- return vmladavaq_p_s8 (a, b, c, p);
+ return vmladavaq_p_s8 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vmladavat.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.s8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo1 (int32_t a, int8x16_t b, int8x16_t c, mve_pred16_t p)
+foo1 (int32_t add, int8x16_t m1, int8x16_t m2, mve_pred16_t p)
{
- return vmladavaq_p (a, b, c, p);
+ return vmladavaq_p (add, m1, m2, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmladavat.s8" } } */
-/* { dg-final { scan-assembler "vmladavat.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_u16.c
index 91a11c8..3266c3a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_u16.c
@@ -1,22 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.u16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo (uint32_t a, uint16x8_t b, uint16x8_t c, mve_pred16_t p)
+foo (uint32_t add, uint16x8_t m1, uint16x8_t m2, mve_pred16_t p)
{
- return vmladavaq_p_u16 (a, b, c, p);
+ return vmladavaq_p_u16 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vmladavat.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.u16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo1 (uint32_t a, uint16x8_t b, uint16x8_t c, mve_pred16_t p)
+foo1 (uint32_t add, uint16x8_t m1, uint16x8_t m2, mve_pred16_t p)
{
- return vmladavaq_p (a, b, c, p);
+ return vmladavaq_p (add, m1, m2, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.u16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint16x8_t m1, uint16x8_t m2, mve_pred16_t p)
+{
+ return vmladavaq_p (1, m1, m2, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmladavat.u16" } } */
-/* { dg-final { scan-assembler "vmladavat.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_u32.c
index 0efe8d0..a555e5f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_u32.c
@@ -1,22 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.u32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo (uint32_t a, uint32x4_t b, uint32x4_t c, mve_pred16_t p)
+foo (uint32_t add, uint32x4_t m1, uint32x4_t m2, mve_pred16_t p)
{
- return vmladavaq_p_u32 (a, b, c, p);
+ return vmladavaq_p_u32 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vmladavat.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.u32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo1 (uint32_t a, uint32x4_t b, uint32x4_t c, mve_pred16_t p)
+foo1 (uint32_t add, uint32x4_t m1, uint32x4_t m2, mve_pred16_t p)
{
- return vmladavaq_p (a, b, c, p);
+ return vmladavaq_p (add, m1, m2, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.u32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint32x4_t m1, uint32x4_t m2, mve_pred16_t p)
+{
+ return vmladavaq_p (1, m1, m2, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmladavat.u32" } } */
-/* { dg-final { scan-assembler "vmladavat.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_u8.c
index a8da9b0..4f9596f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_u8.c
@@ -1,22 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.u8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo (uint32_t a, uint8x16_t b, uint8x16_t c, mve_pred16_t p)
+foo (uint32_t add, uint8x16_t m1, uint8x16_t m2, mve_pred16_t p)
{
- return vmladavaq_p_u8 (a, b, c, p);
+ return vmladavaq_p_u8 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vmladavat.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.u8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo1 (uint32_t a, uint8x16_t b, uint8x16_t c, mve_pred16_t p)
+foo1 (uint32_t add, uint8x16_t m1, uint8x16_t m2, mve_pred16_t p)
{
- return vmladavaq_p (a, b, c, p);
+ return vmladavaq_p (add, m1, m2, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.u8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint8x16_t m1, uint8x16_t m2, mve_pred16_t p)
+{
+ return vmladavaq_p (1, m1, m2, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmladavat.u8" } } */
-/* { dg-final { scan-assembler "vmladavat.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_s16.c
index a45ea90..9f7c0ee 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmladava.s16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo (int32_t a, int16x8_t b, int16x8_t c)
+foo (int32_t add, int16x8_t m1, int16x8_t m2)
{
- return vmladavaq_s16 (a, b, c);
+ return vmladavaq_s16 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vmladava.s16" } } */
+/*
+**foo1:
+** ...
+** vmladava.s16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo1 (int32_t a, int16x8_t b, int16x8_t c)
+foo1 (int32_t add, int16x8_t m1, int16x8_t m2)
{
- return vmladavaq (a, b, c);
+ return vmladavaq (add, m1, m2);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmladava.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_s32.c
index 6533add..012a069 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmladava.s32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo (int32_t a, int32x4_t b, int32x4_t c)
+foo (int32_t add, int32x4_t m1, int32x4_t m2)
{
- return vmladavaq_s32 (a, b, c);
+ return vmladavaq_s32 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vmladava.s32" } } */
+/*
+**foo1:
+** ...
+** vmladava.s32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo1 (int32_t a, int32x4_t b, int32x4_t c)
+foo1 (int32_t add, int32x4_t m1, int32x4_t m2)
{
- return vmladavaq (a, b, c);
+ return vmladavaq (add, m1, m2);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmladava.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_s8.c
index 6fed506..f41230f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmladava.s8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo (int32_t a, int8x16_t b, int8x16_t c)
+foo (int32_t add, int8x16_t m1, int8x16_t m2)
{
- return vmladavaq_s8 (a, b, c);
+ return vmladavaq_s8 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vmladava.s8" } } */
+/*
+**foo1:
+** ...
+** vmladava.s8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo1 (int32_t a, int8x16_t b, int8x16_t c)
+foo1 (int32_t add, int8x16_t m1, int8x16_t m2)
{
- return vmladavaq (a, b, c);
+ return vmladavaq (add, m1, m2);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmladava.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_u16.c
index 3c5f689..62a3c0e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_u16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmladava.u16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo (uint32_t a, uint16x8_t b, uint16x8_t c)
+foo (uint32_t add, uint16x8_t m1, uint16x8_t m2)
{
- return vmladavaq_u16 (a, b, c);
+ return vmladavaq_u16 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vmladava.u16" } } */
+/*
+**foo1:
+** ...
+** vmladava.u16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo1 (uint32_t a, uint16x8_t b, uint16x8_t c)
+foo1 (uint32_t add, uint16x8_t m1, uint16x8_t m2)
{
- return vmladavaq (a, b, c);
+ return vmladavaq (add, m1, m2);
+}
+
+/*
+**foo2:
+** ...
+** vmladava.u16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint16x8_t m1, uint16x8_t m2)
+{
+ return vmladavaq (1, m1, m2);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmladava.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_u32.c
index 6172f82..a186953 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmladava.u32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo (uint32_t a, uint32x4_t b, uint32x4_t c)
+foo (uint32_t add, uint32x4_t m1, uint32x4_t m2)
{
- return vmladavaq_u32 (a, b, c);
+ return vmladavaq_u32 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vmladava.u32" } } */
+/*
+**foo1:
+** ...
+** vmladava.u32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo1 (uint32_t a, uint32x4_t b, uint32x4_t c)
+foo1 (uint32_t add, uint32x4_t m1, uint32x4_t m2)
{
- return vmladavaq (a, b, c);
+ return vmladavaq (add, m1, m2);
+}
+
+/*
+**foo2:
+** ...
+** vmladava.u32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint32x4_t m1, uint32x4_t m2)
+{
+ return vmladavaq (1, m1, m2);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmladava.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_u8.c
index 2aff555..0df9199 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_u8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmladava.u8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo (uint32_t a, uint8x16_t b, uint8x16_t c)
+foo (uint32_t add, uint8x16_t m1, uint8x16_t m2)
{
- return vmladavaq_u8 (a, b, c);
+ return vmladavaq_u8 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vmladava.u8" } } */
+/*
+**foo1:
+** ...
+** vmladava.u8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32_t
-foo1 (uint32_t a, uint8x16_t b, uint8x16_t c)
+foo1 (uint32_t add, uint8x16_t m1, uint8x16_t m2)
{
- return vmladavaq (a, b, c);
+ return vmladavaq (add, m1, m2);
+}
+
+/*
+**foo2:
+** ...
+** vmladava.u8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32_t
+foo2 (uint8x16_t m1, uint8x16_t m2)
+{
+ return vmladavaq (1, m1, m2);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmladava.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_p_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_p_s16.c
index 838717e..f201d5f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_p_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_p_s16.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavaxt.s16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo (int32_t a, int16x8_t b, int16x8_t c, mve_pred16_t p)
+foo (int32_t add, int16x8_t m1, int16x8_t m2, mve_pred16_t p)
{
- return vmladavaxq_p_s16 (a, b, c, p);
+ return vmladavaxq_p_s16 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vmladavaxt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavaxt.s16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo1 (int32_t a, int16x8_t b, int16x8_t c, mve_pred16_t p)
+foo1 (int32_t add, int16x8_t m1, int16x8_t m2, mve_pred16_t p)
{
- return vmladavaxq_p (a, b, c, p);
+ return vmladavaxq_p (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vmladavaxt.s16" } } */
-/* { dg-final { scan-assembler "vmladavaxt.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_p_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_p_s32.c
index a50c5ec..c90647a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_p_s32.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavaxt.s32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo (int32_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
+foo (int32_t add, int32x4_t m1, int32x4_t m2, mve_pred16_t p)
{
- return vmladavaxq_p_s32 (a, b, c, p);
+ return vmladavaxq_p_s32 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vmladavaxt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavaxt.s32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo1 (int32_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
+foo1 (int32_t add, int32x4_t m1, int32x4_t m2, mve_pred16_t p)
{
- return vmladavaxq_p (a, b, c, p);
+ return vmladavaxq_p (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vmladavaxt.s32" } } */
-/* { dg-final { scan-assembler "vmladavaxt.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_p_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_p_s8.c
index e4705ce..57af7bc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_p_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_p_s8.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavaxt.s8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo (int32_t a, int8x16_t b, int8x16_t c, mve_pred16_t p)
+foo (int32_t add, int8x16_t m1, int8x16_t m2, mve_pred16_t p)
{
- return vmladavaxq_p_s8 (a, b, c, p);
+ return vmladavaxq_p_s8 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vmladavaxt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavaxt.s8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo1 (int32_t a, int8x16_t b, int8x16_t c, mve_pred16_t p)
+foo1 (int32_t add, int8x16_t m1, int8x16_t m2, mve_pred16_t p)
{
- return vmladavaxq_p (a, b, c, p);
+ return vmladavaxq_p (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vmladavaxt.s8" } } */
-/* { dg-final { scan-assembler "vmladavaxt.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_s16.c
index ffd542a..684580d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_s16.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmladavax.s16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo (int32_t a, int16x8_t b, int16x8_t c)
+foo (int32_t add, int16x8_t m1, int16x8_t m2)
{
- return vmladavaxq_s16 (a, b, c);
+ return vmladavaxq_s16 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vmladavax.s16" } } */
+/*
+**foo1:
+** ...
+** vmladavax.s16 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo1 (int32_t a, int16x8_t b, int16x8_t c)
+foo1 (int32_t add, int16x8_t m1, int16x8_t m2)
{
- return vmladavaxq (a, b, c);
+ return vmladavaxq (add, m1, m2);
}
-/* { dg-final { scan-assembler "vmladavax.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_s32.c
index b91e54d..5d15264 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_s32.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmladavax.s32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo (int32_t a, int32x4_t b, int32x4_t c)
+foo (int32_t add, int32x4_t m1, int32x4_t m2)
{
- return vmladavaxq_s32 (a, b, c);
+ return vmladavaxq_s32 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vmladavax.s32" } } */
+/*
+**foo1:
+** ...
+** vmladavax.s32 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo1 (int32_t a, int32x4_t b, int32x4_t c)
+foo1 (int32_t add, int32x4_t m1, int32x4_t m2)
{
- return vmladavaxq (a, b, c);
+ return vmladavaxq (add, m1, m2);
}
-/* { dg-final { scan-assembler "vmladavax.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_s8.c
index 61949c4..71bcdc9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaxq_s8.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmladavax.s8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo (int32_t a, int8x16_t b, int8x16_t c)
+foo (int32_t add, int8x16_t m1, int8x16_t m2)
{
- return vmladavaxq_s8 (a, b, c);
+ return vmladavaxq_s8 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vmladavax.s8" } } */
+/*
+**foo1:
+** ...
+** vmladavax.s8 (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32_t
-foo1 (int32_t a, int8x16_t b, int8x16_t c)
+foo1 (int32_t add, int8x16_t m1, int8x16_t m2)
{
- return vmladavaxq (a, b, c);
+ return vmladavaxq (add, m1, m2);
}
-/* { dg-final { scan-assembler "vmladavax.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s16.c
index f33d388..11e32c7 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s16.c
@@ -1,21 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlaldavaxt.s16 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
-foo (int64_t a, int16x8_t b, int16x8_t c, mve_pred16_t p)
+foo (int64_t add, int16x8_t m1, int16x8_t m2, mve_pred16_t p)
{
- return vmlaldavaxq_p_s16 (a, b, c, p);
+ return vmlaldavaxq_p_s16 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vmlaldavaxt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlaldavaxt.s16 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
-foo1 (int64_t a, int16x8_t b, int16x8_t c, mve_pred16_t p)
+foo1 (int64_t add, int16x8_t m1, int16x8_t m2, mve_pred16_t p)
{
- return vmlaldavaxq_p (a, b, c, p);
+ return vmlaldavaxq_p (add, m1, m2, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmlaldavaxt.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s32.c
index ab072a9..937fab4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s32.c
@@ -1,21 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlaldavaxt.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
-foo (int64_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
+foo (int64_t add, int32x4_t m1, int32x4_t m2, mve_pred16_t p)
{
- return vmlaldavaxq_p_s32 (a, b, c, p);
+ return vmlaldavaxq_p_s32 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vmlaldavaxt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlaldavaxt.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
-foo1 (int64_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
+foo1 (int64_t add, int32x4_t m1, int32x4_t m2, mve_pred16_t p)
{
- return vmlaldavaxq_p (a, b, c, p);
+ return vmlaldavaxq_p (add, m1, m2, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmlaldavaxt.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_s16.c
index e68fbd2..4f10ec7 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmlaldavax.s16 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
-foo (int64_t a, int16x8_t b, int16x8_t c)
+foo (int64_t add, int16x8_t m1, int16x8_t m2)
{
- return vmlaldavaxq_s16 (a, b, c);
+ return vmlaldavaxq_s16 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vmlaldavax.s16" } } */
+/*
+**foo1:
+** ...
+** vmlaldavax.s16 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
-foo1 (int64_t a, int16x8_t b, int16x8_t c)
+foo1 (int64_t add, int16x8_t m1, int16x8_t m2)
{
- return vmlaldavaxq (a, b, c);
+ return vmlaldavaxq (add, m1, m2);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmlaldavax.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_s32.c
index 7b6fea2..1d78a7c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmlaldavax.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
-foo (int64_t a, int32x4_t b, int32x4_t c)
+foo (int64_t add, int32x4_t m1, int32x4_t m2)
{
- return vmlaldavaxq_s32 (a, b, c);
+ return vmlaldavaxq_s32 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vmlaldavax.s32" } } */
+/*
+**foo1:
+** ...
+** vmlaldavax.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
-foo1 (int64_t a, int32x4_t b, int32x4_t c)
+foo1 (int64_t add, int32x4_t m1, int32x4_t m2)
{
- return vmlaldavaxq (a, b, c);
+ return vmlaldavaxq (add, m1, m2);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmlaldavax.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s16.c
index bf66e61..83af9bb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo (int16x8_t m1, int16x8_t m2, int16_t add, mve_pred16_t p)
{
- return vmlasq_m_n_s16 (a, b, c, p);
+ return vmlasq_m_n_s16 (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo1 (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo1 (int16x8_t m1, int16x8_t m2, int16_t add, mve_pred16_t p)
{
- return vmlasq_m (a, b, c, p);
+ return vmlasq_m (m1, m2, add, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s32.c
index 53c21e2..f6bf644 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo (int32x4_t m1, int32x4_t m2, int32_t add, mve_pred16_t p)
{
- return vmlasq_m_n_s32 (a, b, c, p);
+ return vmlasq_m_n_s32 (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo1 (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo1 (int32x4_t m1, int32x4_t m2, int32_t add, mve_pred16_t p)
{
- return vmlasq_m (a, b, c, p);
+ return vmlasq_m (m1, m2, add, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s8.c
index ac08b15..021fc03 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo (int8x16_t a, int8x16_t b, int8_t c, mve_pred16_t p)
+foo (int8x16_t m1, int8x16_t m2, int8_t add, mve_pred16_t p)
{
- return vmlasq_m_n_s8 (a, b, c, p);
+ return vmlasq_m_n_s8 (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo1 (int8x16_t a, int8x16_t b, int8_t c, mve_pred16_t p)
+foo1 (int8x16_t m1, int8x16_t m2, int8_t add, mve_pred16_t p)
{
- return vmlasq_m (a, b, c, p);
+ return vmlasq_m (m1, m2, add, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_u16.c
index 99f1e28..1b478da 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
-foo (uint16x8_t a, uint16x8_t b, uint16_t c, mve_pred16_t p)
+foo (uint16x8_t m1, uint16x8_t m2, uint16_t add, mve_pred16_t p)
{
- return vmlasq_m_n_u16 (a, b, c, p);
+ return vmlasq_m_n_u16 (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
-foo1 (uint16x8_t a, uint16x8_t b, uint16_t c, mve_pred16_t p)
+foo1 (uint16x8_t m1, uint16x8_t m2, uint16_t add, mve_pred16_t p)
{
- return vmlasq_m (a, b, c, p);
+ return vmlasq_m (m1, m2, add, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t m1, uint16x8_t m2, mve_pred16_t p)
+{
+ return vmlasq_m (m1, m2, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_u32.c
index 8d8edca..99fc605 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
-foo (uint32x4_t a, uint32x4_t b, uint32_t c, mve_pred16_t p)
+foo (uint32x4_t m1, uint32x4_t m2, uint32_t add, mve_pred16_t p)
{
- return vmlasq_m_n_u32 (a, b, c, p);
+ return vmlasq_m_n_u32 (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
-foo1 (uint32x4_t a, uint32x4_t b, uint32_t c, mve_pred16_t p)
+foo1 (uint32x4_t m1, uint32x4_t m2, uint32_t add, mve_pred16_t p)
{
- return vmlasq_m (a, b, c, p);
+ return vmlasq_m (m1, m2, add, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t m1, uint32x4_t m2, mve_pred16_t p)
+{
+ return vmlasq_m (m1, m2, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_u8.c
index e7f685b..43128266 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
-foo (uint8x16_t a, uint8x16_t b, uint8_t c, mve_pred16_t p)
+foo (uint8x16_t m1, uint8x16_t m2, uint8_t add, mve_pred16_t p)
{
- return vmlasq_m_n_u8 (a, b, c, p);
+ return vmlasq_m_n_u8 (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
-foo1 (uint8x16_t a, uint8x16_t b, uint8_t c, mve_pred16_t p)
+foo1 (uint8x16_t m1, uint8x16_t m2, uint8_t add, mve_pred16_t p)
{
- return vmlasq_m (a, b, c, p);
+ return vmlasq_m (m1, m2, add, p);
+}
+
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t m1, uint8x16_t m2, mve_pred16_t p)
+{
+ return vmlasq_m (m1, m2, 1, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_s16.c
index 8bfe3c3..0ab8e9f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmlas.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo (int16x8_t a, int16x8_t b, int16_t c)
+foo (int16x8_t m1, int16x8_t m2, int16_t add)
{
- return vmlasq_n_s16 (a, b, c);
+ return vmlasq_n_s16 (m1, m2, add);
}
-/* { dg-final { scan-assembler "vmlas.s16" } } */
+/*
+**foo1:
+** ...
+** vmlas.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo1 (int16x8_t a, int16x8_t b, int16_t c)
+foo1 (int16x8_t m1, int16x8_t m2, int16_t add)
{
- return vmlasq (a, b, c);
+ return vmlasq (m1, m2, add);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmlas.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_s32.c
index db06182..88f1dc5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmlas.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo (int32x4_t a, int32x4_t b, int32_t c)
+foo (int32x4_t m1, int32x4_t m2, int32_t add)
{
- return vmlasq_n_s32 (a, b, c);
+ return vmlasq_n_s32 (m1, m2, add);
}
-/* { dg-final { scan-assembler "vmlas.s32" } } */
+/*
+**foo1:
+** ...
+** vmlas.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo1 (int32x4_t a, int32x4_t b, int32_t c)
+foo1 (int32x4_t m1, int32x4_t m2, int32_t add)
{
- return vmlasq (a, b, c);
+ return vmlasq (m1, m2, add);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmlas.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_s8.c
index 3a15165..a5cb99e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmlas.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo (int8x16_t a, int8x16_t b, int8_t c)
+foo (int8x16_t m1, int8x16_t m2, int8_t add)
{
- return vmlasq_n_s8 (a, b, c);
+ return vmlasq_n_s8 (m1, m2, add);
}
-/* { dg-final { scan-assembler "vmlas.s8" } } */
+/*
+**foo1:
+** ...
+** vmlas.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo1 (int8x16_t a, int8x16_t b, int8_t c)
+foo1 (int8x16_t m1, int8x16_t m2, int8_t add)
{
- return vmlasq (a, b, c);
+ return vmlasq (m1, m2, add);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmlas.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_u16.c
index b9444f2..f455fc1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_u16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmlas.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
-foo (uint16x8_t a, uint16x8_t b, uint16_t c)
+foo (uint16x8_t m1, uint16x8_t m2, uint16_t add)
{
- return vmlasq_n_u16 (a, b, c);
+ return vmlasq_n_u16 (m1, m2, add);
}
-/* { dg-final { scan-assembler "vmlas.u16" } } */
+/*
+**foo1:
+** ...
+** vmlas.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
-foo1 (uint16x8_t a, uint16x8_t b, uint16_t c)
+foo1 (uint16x8_t m1, uint16x8_t m2, uint16_t add)
{
- return vmlasq (a, b, c);
+ return vmlasq (m1, m2, add);
+}
+
+/*
+**foo2:
+** ...
+** vmlas.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t m1, uint16x8_t m2)
+{
+ return vmlasq (m1, m2, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmlas.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_u32.c
index 5708a06..561b4f7 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmlas.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
-foo (uint32x4_t a, uint32x4_t b, uint32_t c)
+foo (uint32x4_t m1, uint32x4_t m2, uint32_t add)
{
- return vmlasq_n_u32 (a, b, c);
+ return vmlasq_n_u32 (m1, m2, add);
}
-/* { dg-final { scan-assembler "vmlas.u32" } } */
+/*
+**foo1:
+** ...
+** vmlas.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
-foo1 (uint32x4_t a, uint32x4_t b, uint32_t c)
+foo1 (uint32x4_t m1, uint32x4_t m2, uint32_t add)
{
- return vmlasq (a, b, c);
+ return vmlasq (m1, m2, add);
+}
+
+/*
+**foo2:
+** ...
+** vmlas.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t m1, uint32x4_t m2)
+{
+ return vmlasq (m1, m2, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmlas.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_u8.c
index d83940c..414cba1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_n_u8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmlas.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
-foo (uint8x16_t a, uint8x16_t b, uint8_t c)
+foo (uint8x16_t m1, uint8x16_t m2, uint8_t add)
{
- return vmlasq_n_u8 (a, b, c);
+ return vmlasq_n_u8 (m1, m2, add);
}
-/* { dg-final { scan-assembler "vmlas.u8" } } */
+/*
+**foo1:
+** ...
+** vmlas.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
-foo1 (uint8x16_t a, uint8x16_t b, uint8_t c)
+foo1 (uint8x16_t m1, uint8x16_t m2, uint8_t add)
{
- return vmlasq (a, b, c);
+ return vmlasq (m1, m2, add);
+}
+
+/*
+**foo2:
+** ...
+** vmlas.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t m1, uint8x16_t m2)
+{
+ return vmlasq (m1, m2, 1);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vmlas.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_f16.c
index 68fb012..3c9b82d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_f16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b)
{
return vmulq_f16 (a, b);
}
-/* { dg-final { scan-assembler "vmul.f16" } } */
+/*
+**foo1:
+** ...
+** vmul.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16x8_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_f32.c
index 512661a..adebaee 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_f32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b)
{
return vmulq_f32 (a, b);
}
-/* { dg-final { scan-assembler "vmul.f32" } } */
+/*
+**foo1:
+** ...
+** vmul.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32x4_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_f16.c
index d05d48f..4737ac3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_f16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t inactive, float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vmulq_m_f16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t inactive, float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_f32.c
index 8c2ec81..2c09a9e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_f32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t inactive, float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vmulq_m_f32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t inactive, float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_f16.c
index 1f1d408..8de0d38 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_f16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t inactive, float16x8_t a, float16_t b, mve_pred16_t p)
{
return vmulq_m_n_f16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t inactive, float16x8_t a, float16_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo2 (float16x8_t inactive, float16x8_t a, mve_pred16_t p)
+{
+ return vmulq_m (inactive, a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_f32.c
index 4aae084..36e9aa9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_f32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t inactive, float32x4_t a, float32_t b, mve_pred16_t p)
{
return vmulq_m_n_f32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t inactive, float32x4_t a, float32_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo2 (float32x4_t inactive, float32x4_t a, mve_pred16_t p)
+{
+ return vmulq_m (inactive, a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_s16.c
index 9a87f7d..163d425 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vmulq_m_n_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_s32.c
index da7d38b..89e4c21 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vmulq_m_n_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_s8.c
index 227b3a5..4055959 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vmulq_m_n_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_u16.c
index e09334d..2ea47a6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vmulq_m_n_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, uint16x8_t a, mve_pred16_t p)
+{
+ return vmulq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_u32.c
index 62d6c26..c818c45 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vmulq_m_n_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, uint32x4_t a, mve_pred16_t p)
+{
+ return vmulq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_u8.c
index e7993ab..d038086 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vmulq_m_n_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, uint8x16_t a, mve_pred16_t p)
+{
+ return vmulq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_s16.c
index 61cdf65..72f5d3c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vmulq_m_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_s32.c
index 622407b..2ee86e9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vmulq_m_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_s8.c
index bb2943c..6356f4a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vmulq_m_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_u16.c
index a068017..903bccb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_u16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vmulq_m_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_u32.c
index 586a325..8d386c07 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_u32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vmulq_m_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_u8.c
index 0a8e49a..de3f609 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_m_u8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vmulq_m_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vmulq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_f16.c
index a3f693f..e4efd6b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_f16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16_t b)
{
return vmulq_n_f16 (a, b);
}
-/* { dg-final { scan-assembler "vmul.f16" } } */
+/*
+**foo1:
+** ...
+** vmul.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.f16" } } */
+/*
+**foo2:
+** ...
+** vmul.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo2 (float16x8_t a)
+{
+ return vmulq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_f32.c
index 5d1cfa3..97c71ab 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_f32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32_t b)
{
return vmulq_n_f32 (a, b);
}
-/* { dg-final { scan-assembler "vmul.f32" } } */
+/*
+**foo1:
+** ...
+** vmul.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.f32" } } */
+/*
+**foo2:
+** ...
+** vmul.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo2 (float32x4_t a)
+{
+ return vmulq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_s16.c
index 98e84cb..c2f3c1d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16_t b)
{
return vmulq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vmul.i16" } } */
+/*
+**foo1:
+** ...
+** vmul.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_s32.c
index adbfd6f..50b5f0c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32_t b)
{
return vmulq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vmul.i32" } } */
+/*
+**foo1:
+** ...
+** vmul.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_s8.c
index c845f10..425b576 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8_t b)
{
return vmulq_n_s8 (a, b);
}
-/* { dg-final { scan-assembler "vmul.i8" } } */
+/*
+**foo1:
+** ...
+** vmul.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_u16.c
index e52acdc..1e02ad0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_u16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16_t b)
{
return vmulq_n_u16 (a, b);
}
-/* { dg-final { scan-assembler "vmul.i16" } } */
+/*
+**foo1:
+** ...
+** vmul.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.i16" } } */
+/*
+**foo2:
+** ...
+** vmul.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t a)
+{
+ return vmulq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_u32.c
index 9da4bc1..6a05f54 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32_t b)
{
return vmulq_n_u32 (a, b);
}
-/* { dg-final { scan-assembler "vmul.i32" } } */
+/*
+**foo1:
+** ...
+** vmul.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.i32" } } */
+/*
+**foo2:
+** ...
+** vmul.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t a)
+{
+ return vmulq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_u8.c
index e0f152d..7ba29e6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_n_u8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8_t b)
{
return vmulq_n_u8 (a, b);
}
-/* { dg-final { scan-assembler "vmul.i8" } } */
+/*
+**foo1:
+** ...
+** vmul.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.i8" } } */
+/*
+**foo2:
+** ...
+** vmul.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t a)
+{
+ return vmulq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_s16.c
index 89cc604..026bbae 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b)
{
return vmulq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vmul.i16" } } */
+/*
+**foo1:
+** ...
+** vmul.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_s32.c
index f87fbf1..75a17e0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b)
{
return vmulq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vmul.i32" } } */
+/*
+**foo1:
+** ...
+** vmul.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_s8.c
index 4e40065..a776289 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b)
{
return vmulq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vmul.i8" } } */
+/*
+**foo1:
+** ...
+** vmul.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_u16.c
index ae95bf6..4150c39 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_u16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b)
{
return vmulq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vmul.i16" } } */
+/*
+**foo1:
+** ...
+** vmul.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_u32.c
index 4f8e976..3bdc5df 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_u32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b)
{
return vmulq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vmul.i32" } } */
+/*
+**foo1:
+** ...
+** vmul.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_u8.c
index a3776ff..dc988fd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_u8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmul.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b)
{
return vmulq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vmul.i8" } } */
+/*
+**foo1:
+** ...
+** vmul.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b)
{
return vmulq (a, b);
}
-/* { dg-final { scan-assembler "vmul.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_f16.c
index 1f864cf..bde0536 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_f16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vmulq_x_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_f32.c
index 07cc3d0..162569c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_f32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vmulq_x_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_f16.c
index 8fa6c75..b37a9ae 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_f16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vmulq_x_n_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo2 (float16x8_t a, mve_pred16_t p)
+{
+ return vmulq_x (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_f32.c
index 654713c..a2be895 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_f32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vmulq_x_n_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.f32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo2 (float32x4_t a, mve_pred16_t p)
+{
+ return vmulq_x (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_s16.c
index 4ec5ab3..70e1699 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vmulq_x_n_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_s32.c
index c521800..4e3e232 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vmulq_x_n_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_s8.c
index a2a7c73..a7a2cca 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vmulq_x_n_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_u16.c
index 419a3cb..76b8a7e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vmulq_x_n_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t a, mve_pred16_t p)
+{
+ return vmulq_x (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_u32.c
index 5acfcf6..cba9856 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vmulq_x_n_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t a, mve_pred16_t p)
+{
+ return vmulq_x (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_u8.c
index 27e95ce..3383666 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vmulq_x_n_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t a, mve_pred16_t p)
+{
+ return vmulq_x (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_s16.c
index 5c232bf..a1a6003 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vmulq_x_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_s32.c
index 685fe45..f3a2917 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vmulq_x_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_s8.c
index 19ecc6b..cdd311d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vmulq_x_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_u16.c
index 0700ca8..c8d4eed 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_u16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vmulq_x_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_u32.c
index a1cb2aa..497e542 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_u32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vmulq_x_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_u8.c
index 3b29852..e54b95f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmulq_x_u8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vmulq_x_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmult.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vmulq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmult.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s16.c
index 65d3f77..8884a7c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vqaddq_m_n_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vqaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s32.c
index 4499a0e..77d4b36 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vqaddq_m_n_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vqaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s8.c
index d3e1d55..943fae8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vqaddq_m_n_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vqaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_u16.c
index baadfe7..b880806 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vqaddq_m_n_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vqaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.u16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, uint16x8_t a, mve_pred16_t p)
+{
+ return vqaddq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_u32.c
index 8080877..b9815bd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vqaddq_m_n_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vqaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, uint32x4_t a, mve_pred16_t p)
+{
+ return vqaddq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_u8.c
index 32f2894..674d0c5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vqaddq_m_n_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vqaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.u8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, uint8x16_t a, mve_pred16_t p)
+{
+ return vqaddq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_s16.c
index d5b7fa6..ce1cedd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vqaddq_m_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vqaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_s32.c
index 015bc3e..9b6717e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vqaddq_m_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vqaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_s8.c
index b241fdd..46ce20b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vqaddq_m_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vqaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_u16.c
index fa75235..ed1ffbf 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_u16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vqaddq_m_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vqaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_u32.c
index 0729b6b..50450ff 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_u32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vqaddq_m_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vqaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_u8.c
index f1541658..a260e96 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_u8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vqaddq_m_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vqaddq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_s16.c
index 5eeda2b..0fac7ab 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_s16.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqadd.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16_t b)
{
return vqaddq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vqadd.s16" } } */
+/*
+**foo1:
+** ...
+** vqadd.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16_t b)
{
return vqaddq (a, b);
}
-/* { dg-final { scan-assembler "vqadd.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_s32.c
index 5b914d1..d750b1f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_s32.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqadd.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32_t b)
{
return vqaddq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vqadd.s32" } } */
+/*
+**foo1:
+** ...
+** vqadd.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32_t b)
{
return vqaddq (a, b);
}
-/* { dg-final { scan-assembler "vqadd.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_s8.c
index 06f22c2..5fc796e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_s8.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqadd.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8_t b)
{
return vqaddq_n_s8 (a, b);
}
-/* { dg-final { scan-assembler "vqadd.s8" } } */
+/*
+**foo1:
+** ...
+** vqadd.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8_t b)
{
return vqaddq (a, b);
}
-/* { dg-final { scan-assembler "vqadd.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_u16.c
index 5403f0b..decad65 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_u16.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqadd.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16_t b)
{
return vqaddq_n_u16 (a, b);
}
-/* { dg-final { scan-assembler "vqadd.u16" } } */
+/*
+**foo1:
+** ...
+** vqadd.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16_t b)
{
return vqaddq (a, b);
}
-/* { dg-final { scan-assembler "vqadd.u16" } } */
+/*
+**foo2:
+** ...
+** vqadd.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t a)
+{
+ return vqaddq (a, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_u32.c
index 7718580..b0a6d79 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_u32.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqadd.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32_t b)
{
return vqaddq_n_u32 (a, b);
}
-/* { dg-final { scan-assembler "vqadd.u32" } } */
+/*
+**foo1:
+** ...
+** vqadd.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32_t b)
{
return vqaddq (a, b);
}
-/* { dg-final { scan-assembler "vqadd.u32" } } */
+/*
+**foo2:
+** ...
+** vqadd.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t a)
+{
+ return vqaddq (a, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_u8.c
index f0fa9bf..f9ca9a1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_n_u8.c
@@ -1,21 +1,45 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqadd.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8_t b)
{
return vqaddq_n_u8 (a, b);
}
-/* { dg-final { scan-assembler "vqadd.u8" } } */
+/*
+**foo1:
+** ...
+** vqadd.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8_t b)
{
return vqaddq (a, b);
}
-/* { dg-final { scan-assembler "vqadd.u8" } } */
+/*
+**foo2:
+** ...
+** vqadd.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t a)
+{
+ return vqaddq (a, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_s16.c
index 83cd347..ffa3146 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_s16.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqadd.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b)
{
return vqaddq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vqadd.s16" } } */
+/*
+**foo1:
+** ...
+** vqadd.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b)
{
return vqaddq (a, b);
}
-/* { dg-final { scan-assembler "vqadd.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_s32.c
index d26dd20..c5937a9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_s32.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqadd.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b)
{
return vqaddq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vqadd.s32" } } */
+/*
+**foo1:
+** ...
+** vqadd.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b)
{
return vqaddq (a, b);
}
-/* { dg-final { scan-assembler "vqadd.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_s8.c
index de03264..9f93751 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_s8.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqadd.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b)
{
return vqaddq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vqadd.s8" } } */
+/*
+**foo1:
+** ...
+** vqadd.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vqaddq (a, b);
}
-/* { dg-final { scan-assembler "vqadd.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_u16.c
index cd4efc1..aa4be43 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_u16.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqadd.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b)
{
return vqaddq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vqadd.u16" } } */
+/*
+**foo1:
+** ...
+** vqadd.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b)
{
return vqaddq (a, b);
}
-/* { dg-final { scan-assembler "vqadd.u16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_u32.c
index 8b3afb4..daef60e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_u32.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqadd.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b)
{
return vqaddq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vqadd.u32" } } */
+/*
+**foo1:
+** ...
+** vqadd.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b)
{
return vqaddq (a, b);
}
-/* { dg-final { scan-assembler "vqadd.u32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_u8.c
index da2ff1bb..e28807e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_u8.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqadd.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b)
{
return vqaddq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vqadd.u8" } } */
+/*
+**foo1:
+** ...
+** vqadd.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b)
{
return vqaddq (a, b);
}
-/* { dg-final { scan-assembler "vqadd.u8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s16.c
index d8c4f4b..42b3e25 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlaht.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo (int16x8_t add, int16x8_t m1, int16_t m2, mve_pred16_t p)
{
- return vqdmlahq_m_n_s16 (a, b, c, p);
+ return vqdmlahq_m_n_s16 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmlaht.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlaht.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo1 (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo1 (int16x8_t add, int16x8_t m1, int16_t m2, mve_pred16_t p)
{
- return vqdmlahq_m (a, b, c, p);
+ return vqdmlahq_m (add, m1, m2, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmlaht.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s32.c
index 361f5d0..03e50f1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlaht.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo (int32x4_t add, int32x4_t m1, int32_t m2, mve_pred16_t p)
{
- return vqdmlahq_m_n_s32 (a, b, c, p);
+ return vqdmlahq_m_n_s32 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmlaht.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlaht.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo1 (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo1 (int32x4_t add, int32x4_t m1, int32_t m2, mve_pred16_t p)
{
- return vqdmlahq_m (a, b, c, p);
+ return vqdmlahq_m (add, m1, m2, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmlaht.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s8.c
index a9eaea8..d7f8a15 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlaht.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo (int8x16_t a, int8x16_t b, int8_t c, mve_pred16_t p)
+foo (int8x16_t add, int8x16_t m1, int8_t m2, mve_pred16_t p)
{
- return vqdmlahq_m_n_s8 (a, b, c, p);
+ return vqdmlahq_m_n_s8 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmlaht.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlaht.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo1 (int8x16_t a, int8x16_t b, int8_t c, mve_pred16_t p)
+foo1 (int8x16_t add, int8x16_t m1, int8_t m2, mve_pred16_t p)
{
- return vqdmlahq_m (a, b, c, p);
+ return vqdmlahq_m (add, m1, m2, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmlaht.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_n_s16.c
index c109dd4..210bace 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_n_s16.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqdmlah.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo (int16x8_t a, int16x8_t b, int16_t c)
+foo (int16x8_t add, int16x8_t m1, int16_t m2)
{
- return vqdmlahq_n_s16 (a, b, c);
+ return vqdmlahq_n_s16 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vqdmlah.s16" } } */
+/*
+**foo1:
+** ...
+** vqdmlah.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo1 (int16x8_t a, int16x8_t b, int16_t c)
+foo1 (int16x8_t add, int16x8_t m1, int16_t m2)
{
- return vqdmlahq (a, b, c);
+ return vqdmlahq (add, m1, m2);
}
-/* { dg-final { scan-assembler "vqdmlah.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_n_s32.c
index 752d9d9..dbb2494 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_n_s32.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqdmlah.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo (int32x4_t a, int32x4_t b, int32_t c)
+foo (int32x4_t add, int32x4_t m1, int32_t m2)
{
- return vqdmlahq_n_s32 (a, b, c);
+ return vqdmlahq_n_s32 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vqdmlah.s32" } } */
+/*
+**foo1:
+** ...
+** vqdmlah.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo1 (int32x4_t a, int32x4_t b, int32_t c)
+foo1 (int32x4_t add, int32x4_t m1, int32_t m2)
{
- return vqdmlahq (a, b, c);
+ return vqdmlahq (add, m1, m2);
}
-/* { dg-final { scan-assembler "vqdmlah.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_n_s8.c
index 8dffa0e..a7962f8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_n_s8.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqdmlah.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo (int8x16_t a, int8x16_t b, int8_t c)
+foo (int8x16_t add, int8x16_t m1, int8_t m2)
{
- return vqdmlahq_n_s8 (a, b, c);
+ return vqdmlahq_n_s8 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vqdmlah.s8" } } */
+/*
+**foo1:
+** ...
+** vqdmlah.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo1 (int8x16_t a, int8x16_t b, int8_t c)
+foo1 (int8x16_t add, int8x16_t m1, int8_t m2)
{
- return vqdmlahq (a, b, c);
+ return vqdmlahq (add, m1, m2);
}
-/* { dg-final { scan-assembler "vqdmlah.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s16.c
index 7c2e5cf..34d407f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s16.c
@@ -1,23 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlasht.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo (int16x8_t m1, int16x8_t m2, int16_t add, mve_pred16_t p)
{
- return vqdmlashq_m_n_s16 (a, b, c, p);
+ return vqdmlashq_m_n_s16 (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmlasht.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlasht.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo1 (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo1 (int16x8_t m1, int16x8_t m2, int16_t add, mve_pred16_t p)
{
- return vqdmlashq_m (a, b, c, p);
+ return vqdmlashq_m (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmlasht.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s32.c
index cea9d9b..50a665e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s32.c
@@ -1,23 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlasht.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo (int32x4_t m1, int32x4_t m2, int32_t add, mve_pred16_t p)
{
- return vqdmlashq_m_n_s32 (a, b, c, p);
+ return vqdmlashq_m_n_s32 (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmlasht.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlasht.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo1 (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo1 (int32x4_t m1, int32x4_t m2, int32_t add, mve_pred16_t p)
{
- return vqdmlashq_m (a, b, c, p);
+ return vqdmlashq_m (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmlasht.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s8.c
index 83ee258..45f34b6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s8.c
@@ -1,23 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlasht.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo (int8x16_t a, int8x16_t b, int8_t c, mve_pred16_t p)
+foo (int8x16_t m1, int8x16_t m2, int8_t add, mve_pred16_t p)
{
- return vqdmlashq_m_n_s8 (a, b, c, p);
+ return vqdmlashq_m_n_s8 (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmlasht.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlasht.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo1 (int8x16_t a, int8x16_t b, int8_t c, mve_pred16_t p)
+foo1 (int8x16_t m1, int8x16_t m2, int8_t add, mve_pred16_t p)
{
- return vqdmlashq_m (a, b, c, p);
+ return vqdmlashq_m (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmlasht.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_n_s16.c
index c71a61c..a3f1ae8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_n_s16.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqdmlash.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo (int16x8_t a, int16x8_t b, int16_t c)
+foo (int16x8_t m1, int16x8_t m2, int16_t add)
{
- return vqdmlashq_n_s16 (a, b, c);
+ return vqdmlashq_n_s16 (m1, m2, add);
}
-/* { dg-final { scan-assembler "vqdmlash.s16" } } */
+/*
+**foo1:
+** ...
+** vqdmlash.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo1 (int16x8_t a, int16x8_t b, int16_t c)
+foo1 (int16x8_t m1, int16x8_t m2, int16_t add)
{
- return vqdmlashq (a, b, c);
+ return vqdmlashq (m1, m2, add);
}
-/* { dg-final { scan-assembler "vqdmlash.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_n_s32.c
index 61f6c66..cf867e5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_n_s32.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqdmlash.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo (int32x4_t a, int32x4_t b, int32_t c)
+foo (int32x4_t m1, int32x4_t m2, int32_t add)
{
- return vqdmlashq_n_s32 (a, b, c);
+ return vqdmlashq_n_s32 (m1, m2, add);
}
-/* { dg-final { scan-assembler "vqdmlash.s32" } } */
+/*
+**foo1:
+** ...
+** vqdmlash.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo1 (int32x4_t a, int32x4_t b, int32_t c)
+foo1 (int32x4_t m1, int32x4_t m2, int32_t add)
{
- return vqdmlashq (a, b, c);
+ return vqdmlashq (m1, m2, add);
}
-/* { dg-final { scan-assembler "vqdmlash.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_n_s8.c
index a078928..7e9362c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlashq_n_s8.c
@@ -1,21 +1,33 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vqdmlash.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo (int8x16_t a, int8x16_t b, int8_t c)
+foo (int8x16_t m1, int8x16_t m2, int8_t add)
{
- return vqdmlashq_n_s8 (a, b, c);
+ return vqdmlashq_n_s8 (m1, m2, add);
}
-/* { dg-final { scan-assembler "vqdmlash.s8" } } */
+/*
+**foo1:
+** ...
+** vqdmlash.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo1 (int8x16_t a, int8x16_t b, int8_t c)
+foo1 (int8x16_t m1, int8x16_t m2, int8_t add)
{
- return vqdmlashq (a, b, c);
+ return vqdmlashq (m1, m2, add);
}
-/* { dg-final { scan-assembler "vqdmlash.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s16.c
index 57ab85e..17c43c4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulht.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vqdmulhq_m_n_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulht.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulht.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vqdmulhq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulht.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s32.c
index 256353a..62e7988 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulht.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vqdmulhq_m_n_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulht.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulht.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vqdmulhq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulht.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s8.c
index c24be9e..3bd8b4f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulht.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vqdmulhq_m_n_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulht.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulht.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vqdmulhq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulht.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_s16.c
index 49efeef..b1efee5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulht.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vqdmulhq_m_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulht.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulht.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vqdmulhq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulht.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_s32.c
index a561483..3492c17 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulht.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vqdmulhq_m_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulht.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulht.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vqdmulhq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulht.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_s8.c
index 2e016f5..41118e0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulht.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vqdmulhq_m_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulht.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulht.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vqdmulhq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulht.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_n_s16.c
index 19534b6..dfff38b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_n_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqdmulh.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16_t b)
{
return vqdmulhq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vqdmulh.s16" } } */
+/*
+**foo1:
+** ...
+** vqdmulh.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16_t b)
{
return vqdmulhq (a, b);
}
-/* { dg-final { scan-assembler "vqdmulh.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_n_s32.c
index eff9f6e..ac0812b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_n_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqdmulh.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32_t b)
{
return vqdmulhq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vqdmulh.s32" } } */
+/*
+**foo1:
+** ...
+** vqdmulh.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32_t b)
{
return vqdmulhq (a, b);
}
-/* { dg-final { scan-assembler "vqdmulh.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_n_s8.c
index 188cf7c..db8db5c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_n_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqdmulh.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8_t b)
{
return vqdmulhq_n_s8 (a, b);
}
-/* { dg-final { scan-assembler "vqdmulh.s8" } } */
+/*
+**foo1:
+** ...
+** vqdmulh.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8_t b)
{
return vqdmulhq (a, b);
}
-/* { dg-final { scan-assembler "vqdmulh.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_s16.c
index 513a30f..e892784 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqdmulh.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b)
{
return vqdmulhq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vqdmulh.s16" } } */
+/*
+**foo1:
+** ...
+** vqdmulh.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b)
{
return vqdmulhq (a, b);
}
-/* { dg-final { scan-assembler "vqdmulh.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_s32.c
index 9cf147d..c15c8e2 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqdmulh.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b)
{
return vqdmulhq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vqdmulh.s32" } } */
+/*
+**foo1:
+** ...
+** vqdmulh.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b)
{
return vqdmulhq (a, b);
}
-/* { dg-final { scan-assembler "vqdmulh.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_s8.c
index 87211ad..1f7a556 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqdmulh.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b)
{
return vqdmulhq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vqdmulh.s8" } } */
+/*
+**foo1:
+** ...
+** vqdmulh.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vqdmulhq (a, b);
}
-/* { dg-final { scan-assembler "vqdmulh.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s16.c
index f0a4ad5..57ad651 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmullbt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vqdmullbq_m_n_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmullbt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmullbt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vqdmullbq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmullbt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s32.c
index 1c7b2e4..c7153b3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmullbt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int64x2_t
foo (int64x2_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vqdmullbq_m_n_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmullbt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmullbt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int64x2_t
foo1 (int64x2_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vqdmullbq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmullbt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_s16.c
index 6a056cf..d7abff0b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmullbt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vqdmullbq_m_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmullbt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmullbt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vqdmullbq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmullbt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_s32.c
index 019c536..503cd27 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_m_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmullbt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64x2_t
foo (int64x2_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vqdmullbq_m_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmullbt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmullbt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64x2_t
foo1 (int64x2_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vqdmullbq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmullbt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_n_s16.c
index ec501c3..31a3a24 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_n_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqdmullb.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int16x8_t a, int16_t b)
{
return vqdmullbq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vqdmullb.s16" } } */
+/*
+**foo1:
+** ...
+** vqdmullb.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int16x8_t a, int16_t b)
{
return vqdmullbq (a, b);
}
-/* { dg-final { scan-assembler "vqdmullb.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_n_s32.c
index 78fe3d6..dbc0718 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_n_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqdmullb.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int64x2_t
foo (int32x4_t a, int32_t b)
{
return vqdmullbq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vqdmullb.s32" } } */
+/*
+**foo1:
+** ...
+** vqdmullb.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int64x2_t
foo1 (int32x4_t a, int32_t b)
{
return vqdmullbq (a, b);
}
-/* { dg-final { scan-assembler "vqdmullb.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_s16.c
index 9a423d3..7d5fd25 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqdmullb.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int16x8_t a, int16x8_t b)
{
return vqdmullbq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vqdmullb.s16" } } */
+/*
+**foo1:
+** ...
+** vqdmullb.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int16x8_t a, int16x8_t b)
{
return vqdmullbq (a, b);
}
-/* { dg-final { scan-assembler "vqdmullb.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_s32.c
index f0278cd..503b175 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmullbq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqdmullb.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64x2_t
foo (int32x4_t a, int32x4_t b)
{
return vqdmullbq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vqdmullb.s32" } } */
+/*
+**foo1:
+** ...
+** vqdmullb.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64x2_t
foo1 (int32x4_t a, int32x4_t b)
{
return vqdmullbq (a, b);
}
-/* { dg-final { scan-assembler "vqdmullb.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s16.c
index 85f0314..a36afd8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulltt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vqdmulltq_m_n_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulltt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulltt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vqdmulltq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulltt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s32.c
index 6bb5004..fdbbfee 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulltt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int64x2_t
foo (int64x2_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vqdmulltq_m_n_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulltt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulltt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int64x2_t
foo1 (int64x2_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vqdmulltq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulltt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_s16.c
index a85393b..f5d5c6c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulltt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vqdmulltq_m_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulltt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulltt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vqdmulltq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulltt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_s32.c
index 82f25b2..91dad0e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_m_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulltt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64x2_t
foo (int64x2_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vqdmulltq_m_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulltt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulltt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64x2_t
foo1 (int64x2_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vqdmulltq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulltt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_n_s16.c
index f9ad32a..e4f09d0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_n_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqdmullt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int16x8_t a, int16_t b)
{
return vqdmulltq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vqdmullt.s16" } } */
+/*
+**foo1:
+** ...
+** vqdmullt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int16x8_t a, int16_t b)
{
return vqdmulltq (a, b);
}
-/* { dg-final { scan-assembler "vqdmullt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_n_s32.c
index 311b023..80694b6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_n_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqdmullt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int64x2_t
foo (int32x4_t a, int32_t b)
{
return vqdmulltq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vqdmullt.s32" } } */
+/*
+**foo1:
+** ...
+** vqdmullt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int64x2_t
foo1 (int32x4_t a, int32_t b)
{
return vqdmulltq (a, b);
}
-/* { dg-final { scan-assembler "vqdmullt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_s16.c
index 851f27a..4f8b1ee 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqdmullt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int16x8_t a, int16x8_t b)
{
return vqdmulltq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vqdmullt.s16" } } */
+/*
+**foo1:
+** ...
+** vqdmullt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int16x8_t a, int16x8_t b)
{
return vqdmulltq (a, b);
}
-/* { dg-final { scan-assembler "vqdmullt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_s32.c
index 1e81cc3..e3ebacc4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulltq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqdmullt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64x2_t
foo (int32x4_t a, int32x4_t b)
{
return vqdmulltq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vqdmullt.s32" } } */
+/*
+**foo1:
+** ...
+** vqdmullt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64x2_t
foo1 (int32x4_t a, int32x4_t b)
{
return vqdmulltq (a, b);
}
-/* { dg-final { scan-assembler "vqdmullt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s16.c
index 70c3fa0..304f86c6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlaht.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo (int16x8_t add, int16x8_t m1, int16_t m2, mve_pred16_t p)
{
- return vqrdmlahq_m_n_s16 (a, b, c, p);
+ return vqrdmlahq_m_n_s16 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlaht.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlaht.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo1 (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo1 (int16x8_t add, int16x8_t m1, int16_t m2, mve_pred16_t p)
{
- return vqrdmlahq_m (a, b, c, p);
+ return vqrdmlahq_m (add, m1, m2, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlaht.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s32.c
index 75ed991..265feca 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlaht.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo (int32x4_t add, int32x4_t m1, int32_t m2, mve_pred16_t p)
{
- return vqrdmlahq_m_n_s32 (a, b, c, p);
+ return vqrdmlahq_m_n_s32 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlaht.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlaht.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo1 (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo1 (int32x4_t add, int32x4_t m1, int32_t m2, mve_pred16_t p)
{
- return vqrdmlahq_m (a, b, c, p);
+ return vqrdmlahq_m (add, m1, m2, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlaht.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s8.c
index ddaea54..d1687f7 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlaht.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo (int8x16_t a, int8x16_t b, int8_t c, mve_pred16_t p)
+foo (int8x16_t add, int8x16_t m1, int8_t m2, mve_pred16_t p)
{
- return vqrdmlahq_m_n_s8 (a, b, c, p);
+ return vqrdmlahq_m_n_s8 (add, m1, m2, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlaht.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlaht.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo1 (int8x16_t a, int8x16_t b, int8_t c, mve_pred16_t p)
+foo1 (int8x16_t add, int8x16_t m1, int8_t m2, mve_pred16_t p)
{
- return vqrdmlahq_m (a, b, c, p);
+ return vqrdmlahq_m (add, m1, m2, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlaht.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s16.c
index 45e7497..4595d55 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqrdmlah.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo (int16x8_t a, int16x8_t b, int16_t c)
+foo (int16x8_t add, int16x8_t m1, int16_t m2)
{
- return vqrdmlahq_n_s16 (a, b, c);
+ return vqrdmlahq_n_s16 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vqrdmlah.s16" } } */
+/*
+**foo1:
+** ...
+** vqrdmlah.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo1 (int16x8_t a, int16x8_t b, int16_t c)
+foo1 (int16x8_t add, int16x8_t m1, int16_t m2)
{
- return vqrdmlahq (a, b, c);
+ return vqrdmlahq (add, m1, m2);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vqrdmlah.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s32.c
index 79bb9c9..22d9ce56 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqrdmlah.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo (int32x4_t a, int32x4_t b, int32_t c)
+foo (int32x4_t add, int32x4_t m1, int32_t m2)
{
- return vqrdmlahq_n_s32 (a, b, c);
+ return vqrdmlahq_n_s32 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vqrdmlah.s32" } } */
+/*
+**foo1:
+** ...
+** vqrdmlah.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo1 (int32x4_t a, int32x4_t b, int32_t c)
+foo1 (int32x4_t add, int32x4_t m1, int32_t m2)
{
- return vqrdmlahq (a, b, c);
+ return vqrdmlahq (add, m1, m2);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vqrdmlah.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s8.c
index 220518a..36a23ad 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqrdmlah.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo (int8x16_t a, int8x16_t b, int8_t c)
+foo (int8x16_t add, int8x16_t m1, int8_t m2)
{
- return vqrdmlahq_n_s8 (a, b, c);
+ return vqrdmlahq_n_s8 (add, m1, m2);
}
-/* { dg-final { scan-assembler "vqrdmlah.s8" } } */
+/*
+**foo1:
+** ...
+** vqrdmlah.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo1 (int8x16_t a, int8x16_t b, int8_t c)
+foo1 (int8x16_t add, int8x16_t m1, int8_t m2)
{
- return vqrdmlahq (a, b, c);
+ return vqrdmlahq (add, m1, m2);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vqrdmlah.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s16.c
index 35b9618..2995682 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlasht.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo (int16x8_t m1, int16x8_t m2, int16_t add, mve_pred16_t p)
{
- return vqrdmlashq_m_n_s16 (a, b, c, p);
+ return vqrdmlashq_m_n_s16 (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlasht.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlasht.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
-foo1 (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo1 (int16x8_t m1, int16x8_t m2, int16_t add, mve_pred16_t p)
{
- return vqrdmlashq_m (a, b, c, p);
+ return vqrdmlashq_m (m1, m2, add, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlasht.s16" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s32.c
index 8517835..7e637e6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlasht.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo (int32x4_t m1, int32x4_t m2, int32_t add, mve_pred16_t p)
{
- return vqrdmlashq_m_n_s32 (a, b, c, p);
+ return vqrdmlashq_m_n_s32 (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlasht.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlasht.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
-foo1 (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo1 (int32x4_t m1, int32x4_t m2, int32_t add, mve_pred16_t p)
{
- return vqrdmlashq_m (a, b, c, p);
+ return vqrdmlashq_m (m1, m2, add, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlasht.s32" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s8.c
index e42cc63..d81472d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlasht.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo (int8x16_t a, int8x16_t b, int8_t c, mve_pred16_t p)
+foo (int8x16_t m1, int8x16_t m2, int8_t add, mve_pred16_t p)
{
- return vqrdmlashq_m_n_s8 (a, b, c, p);
+ return vqrdmlashq_m_n_s8 (m1, m2, add, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlasht.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlasht.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
-foo1 (int8x16_t a, int8x16_t b, int8_t c, mve_pred16_t p)
+foo1 (int8x16_t m1, int8x16_t m2, int8_t add, mve_pred16_t p)
{
- return vqrdmlashq_m (a, b, c, p);
+ return vqrdmlashq_m (m1, m2, add, p);
+}
+
+#ifdef __cplusplus
}
+#endif
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlasht.s8" } } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s16.c
index abcff4f..a64b664 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vqsubq_m_n_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vqsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s32.c
index 23e59ff..350629c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vqsubq_m_n_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vqsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s8.c
index d783ab5..e5fa4c4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vqsubq_m_n_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vqsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_u16.c
index 5244efb..734ac2d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vqsubq_m_n_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vqsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.u16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, uint16x8_t a, mve_pred16_t p)
+{
+ return vqsubq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_u32.c
index 4427f87..f54aec8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vqsubq_m_n_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vqsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, uint32x4_t a, mve_pred16_t p)
+{
+ return vqsubq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_u8.c
index 0abfa5d..c96a839 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vqsubq_m_n_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vqsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.u8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, uint8x16_t a, mve_pred16_t p)
+{
+ return vqsubq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_s16.c
index faa189f..bd6a05e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vqsubq_m_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vqsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_s32.c
index 62a4dd0..baa9e9f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vqsubq_m_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vqsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_s8.c
index 71fb6f5..746001d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vqsubq_m_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vqsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_u16.c
index 68d642d..ed504fe3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_u16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vqsubq_m_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vqsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_u32.c
index 8f76c5f..508b54f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_u32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vqsubq_m_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vqsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_u8.c
index af335ae..5cfb2c5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_u8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vqsubq_m_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vqsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_s16.c
index 33a7918..a4407cc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqsub.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16_t b)
{
return vqsubq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vqsub.s16" } } */
+/*
+**foo1:
+** ...
+** vqsub.s16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16_t b)
{
return vqsubq (a, b);
}
-/* { dg-final { scan-assembler "vqsub.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_s32.c
index a2b3388..80634f0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqsub.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32_t b)
{
return vqsubq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vqsub.s32" } } */
+/*
+**foo1:
+** ...
+** vqsub.s32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32_t b)
{
return vqsubq (a, b);
}
-/* { dg-final { scan-assembler "vqsub.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_s8.c
index e8d7e99..172609a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqsub.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8_t b)
{
return vqsubq_n_s8 (a, b);
}
-/* { dg-final { scan-assembler "vqsub.s8" } } */
+/*
+**foo1:
+** ...
+** vqsub.s8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8_t b)
{
return vqsubq (a, b);
}
-/* { dg-final { scan-assembler "vqsub.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_u16.c
index f7b48c5..0a95d0a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_u16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqsub.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16_t b)
{
return vqsubq_n_u16 (a, b);
}
-/* { dg-final { scan-assembler "vqsub.u16" } } */
+/*
+**foo1:
+** ...
+** vqsub.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16_t b)
{
return vqsubq (a, b);
}
-/* { dg-final { scan-assembler "vqsub.u16" } } */
+/*
+**foo2:
+** ...
+** vqsub.u16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t a)
+{
+ return vqsubq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_u32.c
index f74a968..9964ea6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqsub.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32_t b)
{
return vqsubq_n_u32 (a, b);
}
-/* { dg-final { scan-assembler "vqsub.u32" } } */
+/*
+**foo1:
+** ...
+** vqsub.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32_t b)
{
return vqsubq (a, b);
}
-/* { dg-final { scan-assembler "vqsub.u32" } } */
+/*
+**foo2:
+** ...
+** vqsub.u32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t a)
+{
+ return vqsubq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_u8.c
index ce7b4ce..b28a93f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_n_u8.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqsub.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8_t b)
{
return vqsubq_n_u8 (a, b);
}
-/* { dg-final { scan-assembler "vqsub.u8" } } */
+/*
+**foo1:
+** ...
+** vqsub.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8_t b)
{
return vqsubq (a, b);
}
-/* { dg-final { scan-assembler "vqsub.u8" } } */
+/*
+**foo2:
+** ...
+** vqsub.u8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t a)
+{
+ return vqsubq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_s16.c
index 85bf265..1c5edd7 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqsub.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b)
{
return vqsubq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vqsub.s16" } } */
+/*
+**foo1:
+** ...
+** vqsub.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b)
{
return vqsubq (a, b);
}
-/* { dg-final { scan-assembler "vqsub.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_s32.c
index 35d17e8..a7b6c07 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqsub.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b)
{
return vqsubq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vqsub.s32" } } */
+/*
+**foo1:
+** ...
+** vqsub.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b)
{
return vqsubq (a, b);
}
-/* { dg-final { scan-assembler "vqsub.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_s8.c
index 50cfccf..92676fd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqsub.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b)
{
return vqsubq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vqsub.s8" } } */
+/*
+**foo1:
+** ...
+** vqsub.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vqsubq (a, b);
}
-/* { dg-final { scan-assembler "vqsub.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_u16.c
index 15f0b72..0b816c6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_u16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqsub.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b)
{
return vqsubq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vqsub.u16" } } */
+/*
+**foo1:
+** ...
+** vqsub.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b)
{
return vqsubq (a, b);
}
-/* { dg-final { scan-assembler "vqsub.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_u32.c
index 7d695e2..565508d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_u32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqsub.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b)
{
return vqsubq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vqsub.u32" } } */
+/*
+**foo1:
+** ...
+** vqsub.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b)
{
return vqsubq (a, b);
}
-/* { dg-final { scan-assembler "vqsub.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_u8.c
index c0552d1..cca60ff 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_u8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vqsub.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b)
{
return vqsubq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vqsub.u8" } } */
+/*
+**foo1:
+** ...
+** vqsub.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b)
{
return vqsubq (a, b);
}
-/* { dg-final { scan-assembler "vqsub.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_s32.c
index 263d350..2134e3f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_s32.c
@@ -1,21 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrmlaldavhat.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
foo (int64_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
{
return vrmlaldavhaq_p_s32 (a, b, c, p);
}
-/* { dg-final { scan-assembler "vrmlaldavhat.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrmlaldavhat.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
foo1 (int64_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
{
return vrmlaldavhaq_p (a, b, c, p);
}
-/* { dg-final { scan-assembler "vrmlaldavhat.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_u32.c
index 83ab68c..4ebd337 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_u32.c
@@ -1,21 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrmlaldavhat.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint64_t
foo (uint64_t a, uint32x4_t b, uint32x4_t c, mve_pred16_t p)
{
return vrmlaldavhaq_p_u32 (a, b, c, p);
}
-/* { dg-final { scan-assembler "vrmlaldavhat.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrmlaldavhat.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint64_t
foo1 (uint64_t a, uint32x4_t b, uint32x4_t c, mve_pred16_t p)
{
return vrmlaldavhaq_p (a, b, c, p);
}
-/* { dg-final { scan-assembler "vrmlaldavhat.u32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrmlaldavhat.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint64_t
+foo2 (uint32x4_t b, uint32x4_t c, mve_pred16_t p)
+{
+ return vrmlaldavhaq_p (1, b, c, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_s32.c
index 09cd9ee..2efde82 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vrmlaldavha.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
foo (int64_t a, int32x4_t b, int32x4_t c)
{
return vrmlaldavhaq_s32 (a, b, c);
}
-/* { dg-final { scan-assembler "vrmlaldavha.s32" } } */
+/*
+**foo1:
+** ...
+** vrmlaldavha.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int64_t
foo1 (int64_t a, int32x4_t b, int32x4_t c)
{
return vrmlaldavhaq (a, b, c);
}
-/* { dg-final { scan-assembler "vrmlaldavha.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_u32.c
index 1d6f64e..745655f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_u32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vrmlaldavha.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint64_t
foo (uint64_t a, uint32x4_t b, uint32x4_t c)
{
return vrmlaldavhaq_u32 (a, b, c);
}
-/* { dg-final { scan-assembler "vrmlaldavha.u32" } } */
+/*
+**foo1:
+** ...
+** vrmlaldavha.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint64_t
foo1 (uint64_t a, uint32x4_t b, uint32x4_t c)
{
return vrmlaldavhaq (a, b, c);
}
-/* { dg-final { scan-assembler "vrmlaldavha.u32" } } */
+/*
+**foo2:
+** ...
+** vrmlaldavha.u32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint64_t
+foo2 (uint32x4_t b, uint32x4_t c)
+{
+ return vrmlaldavhaq (1, b, c);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s16.c
index cf51de6..4c06451 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int32_t b, mve_pred16_t p)
{
return vrshlq_m_n_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int32_t b, mve_pred16_t p)
{
return vrshlq_m_n (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s32.c
index dcfd997..2c9c15b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vrshlq_m_n_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32_t b, mve_pred16_t p)
{
return vrshlq_m_n (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s8.c
index cc1b746..48c394e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int32_t b, mve_pred16_t p)
{
return vrshlq_m_n_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int32_t b, mve_pred16_t p)
{
return vrshlq_m_n (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_u16.c
index 93a95ba..2fe162b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_u16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, int32_t b, mve_pred16_t p)
{
return vrshlq_m_n_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, int32_t b, mve_pred16_t p)
{
return vrshlq_m_n (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_u32.c
index 4b8c82a..49ccaf8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_u32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, int32_t b, mve_pred16_t p)
{
return vrshlq_m_n_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, int32_t b, mve_pred16_t p)
{
return vrshlq_m_n (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_u8.c
index f1ff9dd..df2f38f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_u8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, int32_t b, mve_pred16_t p)
{
return vrshlq_m_n_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, int32_t b, mve_pred16_t p)
{
return vrshlq_m_n (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_s16.c
index 57f343c..0cb1511 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vrshlq_m_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vrshlq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_s32.c
index 2598b17..52872e3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vrshlq_m_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vrshlq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_s8.c
index 6e4f1bd..887f3fd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vrshlq_m_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vrshlq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_u16.c
index d4d9891..9f55d18 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_u16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vrshlq_m_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vrshlq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_u32.c
index 5d60f1f..f52e9d4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_u32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vrshlq_m_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vrshlq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_u8.c
index 913ba36..7241e31 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_u8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vrshlq_m_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vrshlq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_s16.c
index 713c6a2..feceb6d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vrshl.s16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int32_t b)
{
return vrshlq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vrshl.s16" } } */
+/*
+**foo1:
+** ...
+** vrshl.s16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int32_t b)
{
return vrshlq (a, b);
}
-/* { dg-final { scan-assembler "vrshl.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_s32.c
index 18906fe..4fe4e4f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vrshl.s32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32_t b)
{
return vrshlq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vrshl.s32" } } */
+/*
+**foo1:
+** ...
+** vrshl.s32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32_t b)
{
return vrshlq (a, b);
}
-/* { dg-final { scan-assembler "vrshl.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_s8.c
index d5b1286..fc8fd2d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vrshl.s8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int32_t b)
{
return vrshlq_n_s8 (a, b);
}
-/* { dg-final { scan-assembler "vrshl.s8" } } */
+/*
+**foo1:
+** ...
+** vrshl.s8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int32_t b)
{
return vrshlq (a, b);
}
-/* { dg-final { scan-assembler "vrshl.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_u16.c
index 49bb216..7d3a77a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_u16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vrshl.u16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, int32_t b)
{
return vrshlq_n_u16 (a, b);
}
-/* { dg-final { scan-assembler "vrshl.u16" } } */
+/*
+**foo1:
+** ...
+** vrshl.u16 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, int32_t b)
{
return vrshlq (a, b);
}
-/* { dg-final { scan-assembler "vrshl.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_u32.c
index 8ed6739..e5d688a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_u32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vrshl.u32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, int32_t b)
{
return vrshlq_n_u32 (a, b);
}
-/* { dg-final { scan-assembler "vrshl.u32" } } */
+/*
+**foo1:
+** ...
+** vrshl.u32 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, int32_t b)
{
return vrshlq (a, b);
}
-/* { dg-final { scan-assembler "vrshl.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_u8.c
index ccc6a00..9f594e9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_n_u8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vrshl.u8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, int32_t b)
{
return vrshlq_n_u8 (a, b);
}
-/* { dg-final { scan-assembler "vrshl.u8" } } */
+/*
+**foo1:
+** ...
+** vrshl.u8 q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, int32_t b)
{
return vrshlq (a, b);
}
-/* { dg-final { scan-assembler "vrshl.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_s16.c
index c28ad31..facb0c9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vrshl.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b)
{
return vrshlq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vrshl.s16" } } */
+/*
+**foo1:
+** ...
+** vrshl.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b)
{
return vrshlq (a, b);
}
-/* { dg-final { scan-assembler "vrshl.s16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_s32.c
index 2e279b6..d30d987 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vrshl.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b)
{
return vrshlq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vrshl.s32" } } */
+/*
+**foo1:
+** ...
+** vrshl.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b)
{
return vrshlq (a, b);
}
-/* { dg-final { scan-assembler "vrshl.s32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_s8.c
index 4d18419..52d1f41 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vrshl.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b)
{
return vrshlq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vrshl.s8" } } */
+/*
+**foo1:
+** ...
+** vrshl.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vrshlq (a, b);
}
-/* { dg-final { scan-assembler "vrshl.s8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_u16.c
index e0a9ea9..b729151 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_u16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vrshl.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, int16x8_t b)
{
return vrshlq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vrshl.u16" } } */
+/*
+**foo1:
+** ...
+** vrshl.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, int16x8_t b)
{
return vrshlq (a, b);
}
-/* { dg-final { scan-assembler "vrshl.u16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_u32.c
index 788a4b1..12b4642 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_u32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vrshl.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, int32x4_t b)
{
return vrshlq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vrshl.u32" } } */
+/*
+**foo1:
+** ...
+** vrshl.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, int32x4_t b)
{
return vrshlq (a, b);
}
-/* { dg-final { scan-assembler "vrshl.u32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_u8.c
index d860e9c..37b9194 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_u8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vrshl.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, int8x16_t b)
{
return vrshlq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vrshl.u8" } } */
+/*
+**foo1:
+** ...
+** vrshl.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, int8x16_t b)
{
return vrshlq (a, b);
}
-/* { dg-final { scan-assembler "vrshl.u8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_s16.c
index 800a1e8..b813647 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_s16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vrshlq_x_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.s16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vrshlq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_s32.c
index 921072a..d06d0f9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_s32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vrshlq_x_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.s32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vrshlq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_s8.c
index 217b257..0d1d885 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_s8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vrshlq_x_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.s8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vrshlq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_u16.c
index 5c0cad9..ae050e4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_u16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vrshlq_x_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.u16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vrshlq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_u32.c
index 2754d20..00a2edc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_u32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vrshlq_x_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.u32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vrshlq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_u8.c
index 46dada4..1172a62 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_x_u8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vrshlq_x_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vrshlt.u8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.u8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vrshlq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f16.c
index e03e962..6b148a4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f16.c
@@ -1,15 +1,45 @@
-/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=soft" } {""} } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmov.16 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16_t a, float16x8_t b)
{
- return vsetq_lane_f16 (a, b, 0);
+ return vsetq_lane_f16 (a, b, 1);
}
-/* { dg-final { scan-assembler "vmov.16" } } */
+/*
+**foo1:
+** ...
+** vmov.16 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo1 (float16_t a, float16x8_t b)
+{
+ return vsetq_lane (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** vmov.16 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo2 (float16x8_t b)
+{
+ return vsetq_lane (1.1, b, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f32.c
index 2b9f1a7..e4e7f89 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f32.c
@@ -1,15 +1,45 @@
-/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=soft" } {""} } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmov.32 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32_t a, float32x4_t b)
{
- return vsetq_lane_f32 (a, b, 0);
+ return vsetq_lane_f32 (a, b, 1);
}
-/* { dg-final { scan-assembler "vmov.32" } } */
+/*
+**foo1:
+** ...
+** vmov.32 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo1 (float32_t a, float32x4_t b)
+{
+ return vsetq_lane (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** vmov.32 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo2 (float32x4_t b)
+{
+ return vsetq_lane (1.1, b, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s16.c
index 92ad0dd1..950cd01 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s16.c
@@ -1,15 +1,33 @@
-/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=soft" } {""} } */
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmov.16 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16_t a, int16x8_t b)
{
- return vsetq_lane_s16 (a, b, 0);
+ return vsetq_lane_s16 (a, b, 1);
}
-/* { dg-final { scan-assembler "vmov.16" } } */
+/*
+**foo1:
+** ...
+** vmov.16 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+int16x8_t
+foo1 (int16_t a, int16x8_t b)
+{
+ return vsetq_lane (a, b, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s32.c
index e60c8f2..6b49ccd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s32.c
@@ -1,15 +1,33 @@
-/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=soft" } {""} } */
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmov.32 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32_t a, int32x4_t b)
{
- return vsetq_lane_s32 (a, b, 0);
+ return vsetq_lane_s32 (a, b, 1);
}
-/* { dg-final { scan-assembler "vmov.32" } } */
+/*
+**foo1:
+** ...
+** vmov.32 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+int32x4_t
+foo1 (int32_t a, int32x4_t b)
+{
+ return vsetq_lane (a, b, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s64.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s64.c
index 430df66..95ba4da 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s64.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s64.c
@@ -1,16 +1,33 @@
-/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=soft" } {""} } */
-/* { dg-require-effective-target arm_hard_ok } */
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
-/* { dg-additional-options "-mfloat-abi=hard -O2" } */
+/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmov d[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int64x2_t
foo (int64_t a, int64x2_t b)
{
- return vsetq_lane_s64 (a, b, 0);
+ return vsetq_lane_s64 (a, b, 1);
}
-/* { dg-final { scan-assembler {vmov\td0, r[1-9]*[0-9], r[1-9]*[0-9]} } } */
+/*
+**foo1:
+** ...
+** vmov d[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+int64x2_t
+foo1 (int64_t a, int64x2_t b)
+{
+ return vsetq_lane (a, b, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s8.c
index d8ccbb5..91a5bae 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s8.c
@@ -1,15 +1,33 @@
-/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=soft" } {""} } */
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmov.8 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8_t a, int8x16_t b)
{
- return vsetq_lane_s8 (a, b, 0);
+ return vsetq_lane_s8 (a, b, 1);
}
-/* { dg-final { scan-assembler "vmov.8" } } */
+/*
+**foo1:
+** ...
+** vmov.8 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+int8x16_t
+foo1 (int8_t a, int8x16_t b)
+{
+ return vsetq_lane (a, b, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u16.c
index 156a5d1..53986a5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u16.c
@@ -1,15 +1,45 @@
-/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=soft" } {""} } */
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmov.16 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16_t a, uint16x8_t b)
{
- return vsetq_lane_u16 (a, b, 0);
+ return vsetq_lane_u16 (a, b, 1);
}
-/* { dg-final { scan-assembler "vmov.16" } } */
+/*
+**foo1:
+** ...
+** vmov.16 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo1 (uint16_t a, uint16x8_t b)
+{
+ return vsetq_lane (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** vmov.16 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t b)
+{
+ return vsetq_lane (1, b, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u32.c
index e957548..3f17db9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u32.c
@@ -1,15 +1,45 @@
-/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=soft" } {""} } */
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmov.32 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32_t a, uint32x4_t b)
{
- return vsetq_lane_u32 (a, b, 0);
+ return vsetq_lane_u32 (a, b, 1);
}
-/* { dg-final { scan-assembler "vmov.32" } } */
+/*
+**foo1:
+** ...
+** vmov.32 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo1 (uint32_t a, uint32x4_t b)
+{
+ return vsetq_lane (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** vmov.32 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t b)
+{
+ return vsetq_lane (1, b, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u64.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u64.c
index 0e04012..5ce4c54 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u64.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u64.c
@@ -1,16 +1,45 @@
-/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=soft" } {""} } */
-/* { dg-require-effective-target arm_hard_ok } */
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
-/* { dg-additional-options "-mfloat-abi=hard -O2" } */
+/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmov d[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint64x2_t
foo (uint64_t a, uint64x2_t b)
{
- return vsetq_lane_u64 (a, b, 0);
+ return vsetq_lane_u64 (a, b, 1);
}
-/* { dg-final { scan-assembler {vmov\td0, r[1-9]*[0-9], r[1-9]*[0-9]} } } */
+/*
+**foo1:
+** ...
+** vmov d[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint64x2_t
+foo1 (uint64_t a, uint64x2_t b)
+{
+ return vsetq_lane (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** vmov d[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint64x2_t
+foo2 (uint64x2_t b)
+{
+ return vsetq_lane (1, b, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u8.c
index 668b3fe..58e932b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_u8.c
@@ -1,15 +1,45 @@
-/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=soft" } {""} } */
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+/*
+**foo:
+** ...
+** vmov.8 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8_t a, uint8x16_t b)
{
- return vsetq_lane_u8 (a, b, 0);
+ return vsetq_lane_u8 (a, b, 1);
}
-/* { dg-final { scan-assembler "vmov.8" } } */
+/*
+**foo1:
+** ...
+** vmov.8 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo1 (uint8_t a, uint8x16_t b)
+{
+ return vsetq_lane (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** vmov.8 q[0-9]+\[1\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t b)
+{
+ return vsetq_lane (1, b, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_f16.c
index 8e3ce24..5114f9f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_f16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b)
{
return vsubq_f16 (a, b);
}
-/* { dg-final { scan-assembler "vsub.f16" } } */
+/*
+**foo1:
+** ...
+** vsub.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16x8_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_f32.c
index 5cb239d..d0524ba 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_f32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b)
{
return vsubq_f32 (a, b);
}
-/* { dg-final { scan-assembler "vsub.f32" } } */
+/*
+**foo1:
+** ...
+** vsub.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32x4_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_f16.c
index f4b3f80..e8536dc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_f16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t inactive, float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vsubq_m_f16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t inactive, float16x8_t a, float16x8_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.f16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_f32.c
index 75dbf93..eca850b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_f32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t inactive, float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vsubq_m_f32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t inactive, float32x4_t a, float32x4_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.f32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_f16.c
index 556a084..1753d6c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_f16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t inactive, float16x8_t a, float16_t b, mve_pred16_t p)
{
return vsubq_m_n_f16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t inactive, float16x8_t a, float16_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.f16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo2 (float16x8_t inactive, float16x8_t a, mve_pred16_t p)
+{
+ return vsubq_m (inactive, a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_f32.c
index e53f5f1..056810f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_f32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t inactive, float32x4_t a, float32_t b, mve_pred16_t p)
{
return vsubq_m_n_f32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t inactive, float32x4_t a, float32_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.f32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo2 (float32x4_t inactive, float32x4_t a, mve_pred16_t p)
+{
+ return vsubq_m (inactive, a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_s16.c
index 73443d5..a55ed63 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_s16.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vsubq_m_n_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_s32.c
index b403111..480fed3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_s32.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vsubq_m_n_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_s8.c
index 5c4e101..9aaa540 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_s8.c
@@ -1,23 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vsubq_m_n_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_u16.c
index 04a3036..5d03312 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_u16.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vsubq_m_n_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, uint16x8_t a, mve_pred16_t p)
+{
+ return vsubq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_u32.c
index a21f936..3f94940 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_u32.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vsubq_m_n_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t inactive, uint32x4_t a, mve_pred16_t p)
+{
+ return vsubq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_u8.c
index 18f635f..c6ee888 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_n_u8.c
@@ -1,23 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vsubq_m_n_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t inactive, uint8x16_t a, mve_pred16_t p)
+{
+ return vsubq_m (inactive, a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_s16.c
index 598d648..cfd43b07 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_s16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vsubq_m_s16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t inactive, int16x8_t a, int16x8_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_s32.c
index af67502..6c382ba 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_s32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vsubq_m_s32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_s8.c
index 5effbe2..0408dd0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_s8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vsubq_m_s8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_u16.c
index 12218ae..9d860e9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_u16.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vsubq_m_u16 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_u32.c
index 3a63eeb..c409b0a 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_u32.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vsubq_m_u32 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_u8.c
index a17a274..7d568c1 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_m_u8.c
@@ -1,22 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vsubq_m_u8 (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t inactive, uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
return vsubq_m (inactive, a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_f16.c
index 10e27da..3c31189 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_f16.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16_t b)
{
return vsubq_n_f16 (a, b);
}
-/* { dg-final { scan-assembler "vsub.f16" } } */
+/*
+**foo1:
+** ...
+** vsub.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo1 (float16x8_t a, float16_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.f16" } } */
+/*
+**foo2:
+** ...
+** vsub.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo2 (float16x8_t a)
+{
+ return vsubq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_f32.c
index 9e16d6c..041266b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_f32.c
@@ -1,21 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32_t b)
{
return vsubq_n_f32 (a, b);
}
-/* { dg-final { scan-assembler "vsub.f32" } } */
+/*
+**foo1:
+** ...
+** vsub.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo1 (float32x4_t a, float32_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.f32" } } */
+/*
+**foo2:
+** ...
+** vsub.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo2 (float32x4_t a)
+{
+ return vsubq (a, 1.1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_s16.c
index 7f2af86..78a2b91 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_s16.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
-/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16_t b)
{
return vsubq_n_s16 (a, b);
}
-/* { dg-final { scan-assembler "vsub.i16" } } */
+/*
+**foo1:
+** ...
+** vsub.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_s32.c
index a5e6bf4..98ab34e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_s32.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
-/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32_t b)
{
return vsubq_n_s32 (a, b);
}
-/* { dg-final { scan-assembler "vsub.i32" } } */
+/*
+**foo1:
+** ...
+** vsub.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_s8.c
index 5754379..07173ea 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_s8.c
@@ -1,22 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
-/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8_t b)
{
return vsubq_n_s8 (a, b);
}
-/* { dg-final { scan-assembler "vsub.i8" } } */
+/*
+**foo1:
+** ...
+** vsub.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_u16.c
index ea0a3f9..f0744f5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_u16.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
-/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16_t b)
{
return vsubq_n_u16 (a, b);
}
-/* { dg-final { scan-assembler "vsub.i16" } } */
+/*
+**foo1:
+** ...
+** vsub.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.i16" } } */
+/*
+**foo2:
+** ...
+** vsub.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t a)
+{
+ return vsubq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_u32.c
index cc409b5..600d629 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_u32.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
-/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32_t b)
{
return vsubq_n_u32 (a, b);
}
-/* { dg-final { scan-assembler "vsub.i32" } } */
+/*
+**foo1:
+** ...
+** vsub.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.i32" } } */
+/*
+**foo2:
+** ...
+** vsub.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t a)
+{
+ return vsubq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_u8.c
index 8a18a89..34d4725 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_n_u8.c
@@ -1,22 +1,53 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
-/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8_t b)
{
return vsubq_n_u8 (a, b);
}
-/* { dg-final { scan-assembler "vsub.i8" } } */
+/*
+**foo1:
+** ...
+** vsub.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.i8" } } */
+/*
+**foo2:
+** ...
+** vsub.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t a)
+{
+ return vsubq (a, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_s16.c
index 15e732f..80213e8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_s16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b)
{
return vsubq_s16 (a, b);
}
-/* { dg-final { scan-assembler "vsub.i16" } } */
+/*
+**foo1:
+** ...
+** vsub.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo1 (int16x8_t a, int16x8_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_s32.c
index 5b4ee85..262ec5c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_s32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b)
{
return vsubq_s32 (a, b);
}
-/* { dg-final { scan-assembler "vsub.i32" } } */
+/*
+**foo1:
+** ...
+** vsub.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo1 (int32x4_t a, int32x4_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_s8.c
index b23893a..9a2d55f 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_s8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b)
{
return vsubq_s8 (a, b);
}
-/* { dg-final { scan-assembler "vsub.i8" } } */
+/*
+**foo1:
+** ...
+** vsub.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo1 (int8x16_t a, int8x16_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_u16.c
index edb5e35..62a5942 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_u16.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b)
{
return vsubq_u16 (a, b);
}
-/* { dg-final { scan-assembler "vsub.i16" } } */
+/*
+**foo1:
+** ...
+** vsub.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo1 (uint16x8_t a, uint16x8_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.i16" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_u32.c
index 68040af..3c824b0 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_u32.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b)
{
return vsubq_u32 (a, b);
}
-/* { dg-final { scan-assembler "vsub.i32" } } */
+/*
+**foo1:
+** ...
+** vsub.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo1 (uint32x4_t a, uint32x4_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.i32" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_u8.c
index 92c4f05..c9c7f6c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_u8.c
@@ -1,21 +1,41 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vsub.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b)
{
return vsubq_u8 (a, b);
}
-/* { dg-final { scan-assembler "vsub.i8" } } */
+/*
+**foo1:
+** ...
+** vsub.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo1 (uint8x16_t a, uint8x16_t b)
{
return vsubq (a, b);
}
-/* { dg-final { scan-assembler "vsub.i8" } } */
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_f16.c
index 4cb8be0..cb233e9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_f16.c
@@ -1,15 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16x8_t b, mve_pred16_t p)
{
- return vsubq_x_f16 (a, b, p);
+ return vsubq_x_f16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.f16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+float16x8_t
+foo1 (float16x8_t a, float16x8_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_f32.c
index f6711d7..227e934 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_f32.c
@@ -1,15 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32x4_t b, mve_pred16_t p)
{
- return vsubq_x_f32 (a, b, p);
+ return vsubq_x_f32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.f32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+float32x4_t
+foo1 (float32x4_t a, float32x4_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_f16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_f16.c
index c4adacb..14574d5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_f16.c
@@ -1,15 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float16x8_t
foo (float16x8_t a, float16_t b, mve_pred16_t p)
{
- return vsubq_x_n_f16 (a, b, p);
+ return vsubq_x_n_f16 (a, b, p);
+}
+
+
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo1 (float16x8_t a, float16_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.f16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo2 (float16x8_t a, mve_pred16_t p)
+{
+ return vsubq_x (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_f32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_f32.c
index a4affa0..864f6fe 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_f32.c
@@ -1,15 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
float32x4_t
foo (float32x4_t a, float32_t b, mve_pred16_t p)
{
- return vsubq_x_n_f32 (a, b, p);
+ return vsubq_x_n_f32 (a, b, p);
+}
+
+
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo1 (float32x4_t a, float32_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.f32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.f32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo2 (float32x4_t a, mve_pred16_t p)
+{
+ return vsubq_x (a, 1.1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_s16.c
index 99c59b1..ee9e7bc 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_s16.c
@@ -1,15 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16_t b, mve_pred16_t p)
{
- return vsubq_x_n_s16 (a, b, p);
+ return vsubq_x_n_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+int16x8_t
+foo1 (int16x8_t a, int16_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_s32.c
index 6c29ebe..551f46c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_s32.c
@@ -1,15 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32_t b, mve_pred16_t p)
{
- return vsubq_x_n_s32 (a, b, p);
+ return vsubq_x_n_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+int32x4_t
+foo1 (int32x4_t a, int32_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_s8.c
index 0f83c30..04a9d72 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_s8.c
@@ -1,15 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8_t b, mve_pred16_t p)
{
- return vsubq_x_n_s8 (a, b, p);
+ return vsubq_x_n_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+int8x16_t
+foo1 (int8x16_t a, int8_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_u16.c
index 9a372d7..a07d495 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_u16.c
@@ -1,15 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16_t b, mve_pred16_t p)
{
- return vsubq_x_n_u16 (a, b, p);
+ return vsubq_x_n_u16 (a, b, p);
+}
+
+
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo1 (uint16x8_t a, uint16_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i16" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t a, mve_pred16_t p)
+{
+ return vsubq_x (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_u32.c
index 5219f15..1055769 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_u32.c
@@ -1,15 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32_t b, mve_pred16_t p)
{
- return vsubq_x_n_u32 (a, b, p);
+ return vsubq_x_n_u32 (a, b, p);
+}
+
+
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo1 (uint32x4_t a, uint32_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i32" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo2 (uint32x4_t a, mve_pred16_t p)
+{
+ return vsubq_x (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_u8.c
index 0a0bcf8..a67d303 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_n_u8.c
@@ -1,15 +1,65 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8_t b, mve_pred16_t p)
{
- return vsubq_x_n_u8 (a, b, p);
+ return vsubq_x_n_u8 (a, b, p);
+}
+
+
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo1 (uint8x16_t a, uint8_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i8" } } */
+/*
+**foo2:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo2 (uint8x16_t a, mve_pred16_t p)
+{
+ return vsubq_x (a, 1, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_s16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_s16.c
index 37936a6..9bf3632 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_s16.c
@@ -1,15 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int16x8_t
foo (int16x8_t a, int16x8_t b, mve_pred16_t p)
{
- return vsubq_x_s16 (a, b, p);
+ return vsubq_x_s16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+int16x8_t
+foo1 (int16x8_t a, int16x8_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_s32.c
index c085f59..19707f6 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_s32.c
@@ -1,15 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int32x4_t
foo (int32x4_t a, int32x4_t b, mve_pred16_t p)
{
- return vsubq_x_s32 (a, b, p);
+ return vsubq_x_s32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+int32x4_t
+foo1 (int32x4_t a, int32x4_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_s8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_s8.c
index 3615078..ef4d831 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_s8.c
@@ -1,15 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
int8x16_t
foo (int8x16_t a, int8x16_t b, mve_pred16_t p)
{
- return vsubq_x_s8 (a, b, p);
+ return vsubq_x_s8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+int8x16_t
+foo1 (int8x16_t a, int8x16_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_u16.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_u16.c
index 21423dc..6c3d669 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_u16.c
@@ -1,15 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint16x8_t
foo (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
{
- return vsubq_x_u16 (a, b, p);
+ return vsubq_x_u16 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i16" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i16 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint16x8_t
+foo1 (uint16x8_t a, uint16x8_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_u32.c
index 38dd09a..97f9f74 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_u32.c
@@ -1,15 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint32x4_t
foo (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
{
- return vsubq_x_u32 (a, b, p);
+ return vsubq_x_u32 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i32" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint32x4_t
+foo1 (uint32x4_t a, uint32x4_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_u8.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_u8.c
index 406cbf7..75e75e5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_u8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsubq_x_u8.c
@@ -1,15 +1,49 @@
/* { dg-require-effective-target arm_v8_1m_mve_ok } */
/* { dg-add-options arm_v8_1m_mve } */
/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
#include "arm_mve.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**foo:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
uint8x16_t
foo (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
{
- return vsubq_x_u8 (a, b, p);
+ return vsubq_x_u8 (a, b, p);
}
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vsubt.i8" } } */
+/*
+**foo1:
+** ...
+** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vsubt.i8 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+uint8x16_t
+foo1 (uint8x16_t a, uint8x16_t b, mve_pred16_t p)
+{
+ return vsubq_x (a, b, p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/pr107987.c b/gcc/testsuite/gcc.target/arm/mve/pr107987.c
new file mode 100644
index 0000000..e19a3f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/pr107987.c
@@ -0,0 +1,11 @@
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+
+#include <arm_mve.h>
+
+uint32x4_t foo (uint32x4_t a, uint32x4_t b)
+{
+ mve_pred16_t p = vcmpneq_n_u32 (vandq_u32 (a, b), 0);
+ return vaddq_x_u32 (a, b, p);
+}
diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-compare-1.c b/gcc/testsuite/gcc.target/arm/simd/mve-compare-1.c
index 029c931..887f8db 100644
--- a/gcc/testsuite/gcc.target/arm/simd/mve-compare-1.c
+++ b/gcc/testsuite/gcc.target/arm/simd/mve-compare-1.c
@@ -50,31 +50,31 @@ TEST_TYPE (vs32, __INT32_TYPE__, COMPARE_REG_AND_ZERO, 16)
TEST_TYPE (vu32, __UINT32_TYPE__, COMPARE_REG, 16)
/* { 8 bits } x { eq, ne, lt, le, gt, ge, hi, cs }.
-/* { dg-final { scan-assembler-times {\tvcmp.i8 eq, q[0-9]+, q[0-9]+\n} 4 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.i8 ne, q[0-9]+, q[0-9]+\n} 4 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s8 lt, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s8 le, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s8 gt, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s8 ge, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.u8 hi, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.u8 cs, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.i8\teq, q[0-9]+, q[0-9]+\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.i8\tne, q[0-9]+, q[0-9]+\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s8\tlt, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s8\tle, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s8\tgt, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s8\tge, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u8\thi, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u8\tcs, q[0-9]+, q[0-9]+\n} 2 } } */
/* { 16 bits } x { eq, ne, lt, le, gt, ge, hi, cs }.
-/* { dg-final { scan-assembler-times {\tvcmp.i16 eq, q[0-9]+, q[0-9]+\n} 4 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.i16 ne, q[0-9]+, q[0-9]+\n} 4 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s16 lt, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s16 le, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s16 gt, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s16 ge, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.u16 hi, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.u16 cs, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.i16\teq, q[0-9]+, q[0-9]+\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.i16\tne, q[0-9]+, q[0-9]+\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s16\tlt, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s16\tle, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s16\tgt, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s16\tge, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u16\thi, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u16\tcs, q[0-9]+, q[0-9]+\n} 2 } } */
/* { 32 bits } x { eq, ne, lt, le, gt, ge, hi, cs }.
-/* { dg-final { scan-assembler-times {\tvcmp.i32 eq, q[0-9]+, q[0-9]+\n} 4 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.i32 ne, q[0-9]+, q[0-9]+\n} 4 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s32 lt, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s32 le, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s32 gt, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s32 ge, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.u32 hi, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.u32 cs, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.i32\teq, q[0-9]+, q[0-9]+\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.i32\tne, q[0-9]+, q[0-9]+\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s32\tlt, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s32\tle, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s32\tgt, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s32\tge, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u32\thi, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u32\tcs, q[0-9]+, q[0-9]+\n} 2 } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-compare-scalar-1.c b/gcc/testsuite/gcc.target/arm/simd/mve-compare-scalar-1.c
index 7774972..20ab0a2 100644
--- a/gcc/testsuite/gcc.target/arm/simd/mve-compare-scalar-1.c
+++ b/gcc/testsuite/gcc.target/arm/simd/mve-compare-scalar-1.c
@@ -39,31 +39,31 @@ TEST_TYPE (vs32, __INT32_TYPE__, 16)
TEST_TYPE (vu32, __UINT32_TYPE__, 16)
/* { 8 bits } x { eq, ne, lt, le, gt, ge, hi, cs }.
-/* { dg-final { scan-assembler-times {\tvcmp.i8 eq, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.i8 ne, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s8 lt, q[0-9]+, q[0-9]+\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s8 le, q[0-9]+, q[0-9]+\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s8 gt, q[0-9]+, q[0-9]+\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s8 ge, q[0-9]+, q[0-9]+\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.u8 hi, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.u8 cs, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.i8\teq, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.i8\tne, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s8\tlt, q[0-9]+, q[0-9]+\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s8\tle, q[0-9]+, q[0-9]+\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s8\tgt, q[0-9]+, q[0-9]+\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s8\tge, q[0-9]+, q[0-9]+\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u8\thi, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u8\tcs, q[0-9]+, q[0-9]+\n} 2 } } */
/* { 16 bits } x { eq, ne, lt, le, gt, ge, hi, cs }.
-/* { dg-final { scan-assembler-times {\tvcmp.i16 eq, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.i16 ne, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s16 lt, q[0-9]+, q[0-9]+\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s16 le, q[0-9]+, q[0-9]+\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s16 gt, q[0-9]+, q[0-9]+\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s16 ge, q[0-9]+, q[0-9]+\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.u16 hi, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.u16 cs, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.i16\teq, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.i16\tne, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s16\tlt, q[0-9]+, q[0-9]+\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s16\tle, q[0-9]+, q[0-9]+\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s16\tgt, q[0-9]+, q[0-9]+\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s16\tge, q[0-9]+, q[0-9]+\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u16\thi, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u16\tcs, q[0-9]+, q[0-9]+\n} 2 } } */
/* { 32 bits } x { eq, ne, lt, le, gt, ge, hi, cs }.
-/* { dg-final { scan-assembler-times {\tvcmp.i32 eq, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.i32 ne, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s32 lt, q[0-9]+, q[0-9]+\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s32 le, q[0-9]+, q[0-9]+\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s32 gt, q[0-9]+, q[0-9]+\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s32 ge, q[0-9]+, q[0-9]+\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.u32 hi, q[0-9]+, q[0-9]+\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.u32 cs, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.i32\teq, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.i32\tne, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s32\tlt, q[0-9]+, q[0-9]+\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s32\tle, q[0-9]+, q[0-9]+\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s32\tgt, q[0-9]+, q[0-9]+\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s32\tge, q[0-9]+, q[0-9]+\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u32\thi, q[0-9]+, q[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u32\tcs, q[0-9]+, q[0-9]+\n} 2 } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vabs.c b/gcc/testsuite/gcc.target/arm/simd/mve-vabs.c
index 64cd1c2..f2f9ee3 100644
--- a/gcc/testsuite/gcc.target/arm/simd/mve-vabs.c
+++ b/gcc/testsuite/gcc.target/arm/simd/mve-vabs.c
@@ -38,7 +38,7 @@ FUNC(f, float, 16, 8, vabs)
integer optimizations actually generate a call to memmove, the other ones a
'vabs'. */
/* { dg-final { scan-assembler-times {vabs.s[0-9]+\tq[0-9]+, q[0-9]+} 3 } } */
-/* { dg-final { scan-assembler-times {vabs.f[0-9]+ q[0-9]+, q[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vabs.f[0-9]+\tq[0-9]+, q[0-9]+} 2 } } */
/* { dg-final { scan-assembler-times {vldr[bhw].[0-9]+\tq[0-9]+} 5 } } */
/* { dg-final { scan-assembler-times {vstr[bhw].[0-9]+\tq[0-9]+} 5 } } */
/* { dg-final { scan-assembler-times {memmove} 3 } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vadd-1.c b/gcc/testsuite/gcc.target/arm/simd/mve-vadd-1.c
index 15a9daa..f31d1cc 100644
--- a/gcc/testsuite/gcc.target/arm/simd/mve-vadd-1.c
+++ b/gcc/testsuite/gcc.target/arm/simd/mve-vadd-1.c
@@ -22,9 +22,9 @@ FUNC(u, uint, 16, 8, +, vadd)
FUNC(s, int, 8, 16, +, vadd)
FUNC(u, uint, 8, 16, +, vadd)
-/* { dg-final { scan-assembler-times {vadd\.i32 q[0-9]+, q[0-9]+, q[0-9]+} 2 } } */
-/* { dg-final { scan-assembler-times {vadd\.i16 q[0-9]+, q[0-9]+, q[0-9]+} 2 } } */
-/* { dg-final { scan-assembler-times {vadd\.i8 q[0-9]+, q[0-9]+, q[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vadd\.i32\tq[0-9]+, q[0-9]+, q[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vadd\.i16\tq[0-9]+, q[0-9]+, q[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vadd\.i8\tq[0-9]+, q[0-9]+, q[0-9]+} 2 } } */
void test_vadd_f32 (float * dest, float * a, float * b) {
int i;
@@ -32,7 +32,7 @@ void test_vadd_f32 (float * dest, float * a, float * b) {
dest[i] = a[i] + b[i];
}
}
-/* { dg-final { scan-assembler-times {vadd\.f32 q[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {vadd\.f32\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
void test_vadd_f16 (__fp16 * dest, __fp16 * a, __fp16 * b) {
int i;
@@ -40,4 +40,4 @@ void test_vadd_f16 (__fp16 * dest, __fp16 * a, __fp16 * b) {
dest[i] = a[i] + b[i];
}
}
-/* { dg-final { scan-assembler-times {vadd\.f16 q[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {vadd\.f16\tq[0-9]+, q[0-9]+, q[0-9]+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vadd-scalar-1.c b/gcc/testsuite/gcc.target/arm/simd/mve-vadd-scalar-1.c
index bbf70e1..7eec234 100644
--- a/gcc/testsuite/gcc.target/arm/simd/mve-vadd-scalar-1.c
+++ b/gcc/testsuite/gcc.target/arm/simd/mve-vadd-scalar-1.c
@@ -24,9 +24,9 @@ FUNC_IMM(u, uint, 8, 16, +, vaddimm)
/* For the moment we do not select the T2 vadd variant operating on a scalar
final argument. */
-/* { dg-final { scan-assembler-times {vadd\.i32 q[0-9]+, q[0-9]+, r[0-9]+} 2 { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times {vadd\.i16 q[0-9]+, q[0-9]+, r[0-9]+} 2 { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times {vadd\.i8 q[0-9]+, q[0-9]+, r[0-9]+} 2 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times {vadd\.i32\tq[0-9]+, q[0-9]+, r[0-9]+} 2 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times {vadd\.i16\tq[0-9]+, q[0-9]+, r[0-9]+} 2 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times {vadd\.i8\tq[0-9]+, q[0-9]+, r[0-9]+} 2 { xfail *-*-* } } } */
void test_vaddimm_f32 (float * dest, float * a) {
int i;
@@ -34,7 +34,7 @@ void test_vaddimm_f32 (float * dest, float * a) {
dest[i] = a[i] + 5.0;
}
}
-/* { dg-final { scan-assembler-times {vadd\.f32 q[0-9]+, q[0-9]+, r[0-9]+} 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times {vadd\.f32\tq[0-9]+, q[0-9]+, r[0-9]+} 1 { xfail *-*-* } } } */
/* Note that dest[i] = a[i] + 5.0f16 is not vectorized. */
void test_vaddimm_f16 (__fp16 * dest, __fp16 * a) {
@@ -44,4 +44,4 @@ void test_vaddimm_f16 (__fp16 * dest, __fp16 * a) {
dest[i] = a[i] + b;
}
}
-/* { dg-final { scan-assembler-times {vadd\.f16 q[0-9]+, q[0-9]+, r[0-9]+} 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times {vadd\.f16\tq[0-9]+, q[0-9]+, r[0-9]+} 1 { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vcmp.c b/gcc/testsuite/gcc.target/arm/simd/mve-vcmp.c
index 8da15e7..806b145 100644
--- a/gcc/testsuite/gcc.target/arm/simd/mve-vcmp.c
+++ b/gcc/testsuite/gcc.target/arm/simd/mve-vcmp.c
@@ -36,15 +36,15 @@ ALL_FUNCS(>=, vcmpge)
/* MVE has only 128-bit vectors, so we can vectorize only half of the
functions above. */
-/* { dg-final { scan-assembler-times {\tvcmp.i[0-9]+ eq, q[0-9]+, q[0-9]+\n} 6 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.i[0-9]+ ne, q[0-9]+, q[0-9]+\n} 6 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.i[0-9]+\teq, q[0-9]+, q[0-9]+\n} 6 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.i[0-9]+\tne, q[0-9]+, q[0-9]+\n} 6 } } */
/* lt, le, gt, ge apply to signed types, cs and hi to unsigned types. */
/* lt and le with unsigned types are replaced with the opposite condition, hence
the double number of matches for cs and hi. */
-/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+ lt, q[0-9]+, q[0-9]+\n} 3 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+ le, q[0-9]+, q[0-9]+\n} 3 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+ gt, q[0-9]+, q[0-9]+\n} 3 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+ ge, q[0-9]+, q[0-9]+\n} 3 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.u[0-9]+ cs, q[0-9]+, q[0-9]+\n} 6 } } */
-/* { dg-final { scan-assembler-times {\tvcmp.u[0-9]+ hi, q[0-9]+, q[0-9]+\n} 6 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+\tlt, q[0-9]+, q[0-9]+\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+\tle, q[0-9]+, q[0-9]+\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+\tgt, q[0-9]+, q[0-9]+\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.s[0-9]+\tge, q[0-9]+, q[0-9]+\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u[0-9]+\tcs, q[0-9]+, q[0-9]+\n} 6 } } */
+/* { dg-final { scan-assembler-times {\tvcmp.u[0-9]+\thi, q[0-9]+, q[0-9]+\n} 6 } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/pr101325.c b/gcc/testsuite/gcc.target/arm/simd/pr101325.c
index 4cb2513..ce9ce3a 100644
--- a/gcc/testsuite/gcc.target/arm/simd/pr101325.c
+++ b/gcc/testsuite/gcc.target/arm/simd/pr101325.c
@@ -9,6 +9,6 @@ unsigned foo(int8x16_t v, int8x16_t w)
{
return vcmpeqq (v, w);
}
-/* { dg-final { scan-assembler {\tvcmp.i8 eq} } } */
-/* { dg-final { scan-assembler {\tvmrs\tr[0-9]+, P0} } } */
+/* { dg-final { scan-assembler {\tvcmp.i8\teq} } } */
+/* { dg-final { scan-assembler {\tvmrs\tr[0-9]+, p0} } } */
/* { dg-final { scan-assembler {\tuxth} } } */
diff --git a/gcc/testsuite/gcc.target/bpf/bswap-1.c b/gcc/testsuite/gcc.target/bpf/bswap-1.c
new file mode 100644
index 0000000..4748143
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/bswap-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-mlittle-endian" } */
+
+unsigned short in16 = 0x1234U;
+unsigned int in32 = 0x12345678U;
+unsigned long in64 = 0x123456789abcdef0ULL;
+
+unsigned short out16 = 0;
+unsigned int out32 = 0;
+unsigned long out64 = 0;
+
+int foo (void)
+{
+ out16 = __builtin_bswap16 (in16);
+ out32 = __builtin_bswap32 (in32);
+ out64 = __builtin_bswap64 (in64);
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler "endbe\t%r., 16" } } */
+/* { dg-final { scan-assembler "endbe\t%r., 32" } } */
+/* { dg-final { scan-assembler "endbe\t%r., 64" } } */
diff --git a/gcc/testsuite/gcc.target/gcn/math-builtins-1.c b/gcc/testsuite/gcc.target/gcn/math-builtins-1.c
new file mode 100644
index 0000000..e1aadfb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/math-builtins-1.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+typedef float v64sf __attribute__ ((vector_size (256)));
+typedef double v64df __attribute__ ((vector_size (512)));
+typedef int v64si __attribute__ ((vector_size (256)));
+typedef long v64di __attribute__ ((vector_size (512)));
+
+v64sf f (v64sf _x, v64si _y)
+{
+ v64sf x = _x;
+ v64si y = _y;
+ x = __builtin_gcn_fabsvf (x); /* { dg-final { scan-assembler "v_add_f32\\s+v\[0-9\]+, 0, |v\[0-9\]+|" } } */
+ x = __builtin_gcn_floorvf (x); /* { dg-final { scan-assembler "v_floor_f32\\s+v\[0-9\]+, v\[0-9\]+" } }*/
+ x = __builtin_gcn_frexpvf_mant (x); /* { dg-final { scan-assembler "v_frexp_mant_f32\\s+v\[0-9\]+, v\[0-9\]+" } }*/
+ y = __builtin_gcn_frexpvf_exp (x); /* { dg-final { scan-assembler "v_frexp_exp_i32_f32\\s+v\[0-9\]+, v\[0-9\]+" } }*/
+ x = __builtin_gcn_ldexpvf (x, y); /* { dg-final { scan-assembler "v_ldexp_f32\\s+v\[0-9\]+, v\[0-9\]+, v\[0-9\]+" } }*/
+
+ return x;
+}
+
+v64df g (v64df _x, v64si _y)
+{
+ v64df x = _x;
+ v64si y = _y;
+ x = __builtin_gcn_fabsv (x); /* { dg-final { scan-assembler "v_add_f64\\s+v\\\[\[0-9\]+:\[0-9]+\\\], 0, |v\\\[\[0-9\]+:\[0-9\]+\\\]|" } } */
+ x = __builtin_gcn_floorv (x); /* { dg-final { scan-assembler "v_floor_f64\\s+v\\\[\[0-9\]+:\[0-9]+\\\], v\\\[\[0-9\]+:\[0-9]+\\\]" } }*/
+ x = __builtin_gcn_frexpv_mant (x); /* { dg-final { scan-assembler "v_frexp_mant_f64\\s+v\\\[\[0-9\]+:\[0-9]+\\\], v\\\[\[0-9\]+:\[0-9]+\\\]" } }*/
+ y = __builtin_gcn_frexpv_exp (x); /* { dg-final { scan-assembler "v_frexp_exp_i32_f64\\s+v\[0-9\]+, v\\\[\[0-9\]+:\[0-9]+\\\]" } }*/
+ x = __builtin_gcn_ldexpv (x, y); /* { dg-final { scan-assembler "v_ldexp_f64\\s+v\\\[\[0-9\]+:\[0-9]+\\\], v\\\[\[0-9\]+:\[0-9]+\\\], v\[0-9\]+" } }*/
+
+ return x;
+}
diff --git a/gcc/testsuite/gcc.target/gcn/unsafe-math-1.c b/gcc/testsuite/gcc.target/gcn/unsafe-math-1.c
new file mode 100644
index 0000000..2b54fa2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/unsafe-math-1.c
@@ -0,0 +1,10 @@
+/* { dg-do link } */
+/* { dg-options "-O0 -ffast-math" } */
+
+int main (void)
+{
+ float x = 0.123456f;
+
+ float r1 = __builtin_exp2f (x);
+ float r2 = __builtin_log2f (x);
+}
diff --git a/gcc/testsuite/gcc.target/i386/amx-check.h b/gcc/testsuite/gcc.target/i386/amx-check.h
index 6fff5ff4..27dd37b 100644
--- a/gcc/testsuite/gcc.target/i386/amx-check.h
+++ b/gcc/testsuite/gcc.target/i386/amx-check.h
@@ -213,6 +213,9 @@ main ()
#ifdef AMX_BF16
&& __builtin_cpu_supports ("amx-bf16")
#endif
+#ifdef AMX_FP16
+ && __builtin_cpu_supports ("amx-fp16")
+#endif
#ifdef __linux__
&& request_perm_xtile_data ()
#endif
diff --git a/gcc/testsuite/gcc.target/i386/amx-helper.h b/gcc/testsuite/gcc.target/i386/amx-helper.h
new file mode 100644
index 0000000..fe24d70
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/amx-helper.h
@@ -0,0 +1,61 @@
+#ifndef AMX_HELPER_H_INCLUDED
+#define AMX_HELPER_H_INCLUDED
+#if defined(AMX_FP16)
+#include <immintrin.h>
+#include <xmmintrin.h>
+#endif
+#include "amx-check.h"
+
+typedef union
+{
+ _Float16 f16;
+ uint16_t u;
+} union16f_uw;
+
+#if defined(AMX_FP16)
+/* Transformation functions between fp16/float */
+static uint16_t make_f32_fp16 (float f)
+{
+ union16f_uw tmp;
+ __m128 b = _mm_set_ss (f);
+ __m128h a;
+ tmp.f16 = _mm_cvtsh_h (_mm_cvtss_sh (a, b));
+ return tmp.u;
+}
+
+static float make_fp16_f32 (uint16_t fp)
+{
+ union16f_uw tmp;
+ tmp.u = fp;
+ __m128h b = _mm_set_sh (tmp.f16);
+ __m128 a;
+ return _mm_cvtss_f32 (_mm_cvtsh_ss (a, b));
+}
+
+/* Init tile buffer with fp16 pairs */
+void init_fp16_max_tile_buffer (uint8_t* buf)
+{
+ int i, j;
+ uint16_t* ptr = (uint16_t *) buf;
+
+ for (i = 0; i < 16; i++)
+ for (j = 0; j < 32; j++)
+ {
+ float f = 2.5f * i + 1.25f * j;
+ ptr[i * 32 + j] = make_f32_fp16 (f);
+ }
+}
+
+/* Init tile fp16 pair buffer with zero */
+void init_fp16_max_tile_zero_buffer (uint8_t* buf)
+{
+ int i, j;
+ uint16_t* ptr = (uint16_t *) buf;
+
+ for (i = 0; i < 16; i++)
+ for (j = 0; j < 32; j++)
+ ptr[i * 32 + j] = make_f32_fp16 (0.0f);
+}
+#endif
+
+#endif
diff --git a/gcc/testsuite/gcc.target/i386/amxbf16-dpbf16ps-2.c b/gcc/testsuite/gcc.target/i386/amxbf16-dpbf16ps-2.c
index b00bc13..35881e7 100644
--- a/gcc/testsuite/gcc.target/i386/amxbf16-dpbf16ps-2.c
+++ b/gcc/testsuite/gcc.target/i386/amxbf16-dpbf16ps-2.c
@@ -1,7 +1,6 @@
/* { dg-do run { target { ! ia32 } } } */
-/* { dg-require-effective-target amx_tile } */
/* { dg-require-effective-target amx_bf16 } */
-/* { dg-options "-O2 -mamx-tile -mamx-bf16" } */
+/* { dg-options "-O2 -mamx-bf16" } */
#include <immintrin.h>
#define AMX_BF16
diff --git a/gcc/testsuite/gcc.target/i386/amxfp16-asmatt-1.c b/gcc/testsuite/gcc.target/i386/amxfp16-asmatt-1.c
new file mode 100644
index 0000000..09ae6d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/amxfp16-asmatt-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mamx-fp16" } */
+/* { dg-final { scan-assembler "tdpfp16ps\[ \\t]+\[^\n\]*%tmm3+\[^\n\]*%tmm2+\[^\n\]*%tmm1" } } */
+#include <immintrin.h>
+
+#define TMM1 1
+#define TMM2 2
+#define TMM3 3
+
+void TEST ()
+{
+ _tile_dpfp16ps (TMM1, TMM2, TMM3);
+}
diff --git a/gcc/testsuite/gcc.target/i386/amxfp16-asmintel-1.c b/gcc/testsuite/gcc.target/i386/amxfp16-asmintel-1.c
new file mode 100644
index 0000000..a8dff94
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/amxfp16-asmintel-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-require-effective-target masm_intel } */
+/* { dg-options "-O2 -mamx-fp16 -masm=intel" } */
+/* { dg-final { scan-assembler "tdpfp16ps\[ \\t]+\[^\n\]*%tmm1+\[^\n\]*%tmm2+\[^\n\]*%tmm3" } } */
+#include <immintrin.h>
+
+void TEST ()
+{
+ _tile_dpfp16ps (1, 2, 3);
+}
diff --git a/gcc/testsuite/gcc.target/i386/amxfp16-dpfp16ps-2.c b/gcc/testsuite/gcc.target/i386/amxfp16-dpfp16ps-2.c
new file mode 100644
index 0000000..a1fafbc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/amxfp16-dpfp16ps-2.c
@@ -0,0 +1,56 @@
+/* { dg-do run { target { ! ia32 } } } */
+/* { dg-require-effective-target amx_fp16 } */
+/* { dg-require-effective-target avx512fp16 } */
+/* { dg-options "-O2 -mamx-fp16 -mavx512fp16" } */
+#define AMX_FP16
+#define DO_TEST test_amx_fp16_dpfp16ps
+void test_amx_fp16_dpfp16ps ();
+#include "amx-helper.h"
+
+void calc_matrix_dpfp16ps (__tile *dst, __tile *src1, __tile *src2)
+{
+ uint16_t *src1_buf = (uint16_t *)src1->buf;
+ uint16_t *src2_buf = (uint16_t *)src2->buf;
+ float *dst_buf = (float *)dst->buf;
+
+ int M = src1->rows;
+ int N = src1->colsb / 4;
+ int K = src2->colsb / 4;
+ int i, j, k, t;
+
+ for (i = 0; i < M; i++)
+ for (j = 0; j < N; j++)
+ for (k = 0; k < K; k++)
+ for (t = 0; t < 2; t+=2)
+ {
+ dst_buf[i * K + k] +=
+ (make_fp16_f32 (src1_buf[i * 2 * N + 2 * j + t]) *
+ make_fp16_f32 (src2_buf[j * 2 * K + 2 * k + t])) +
+ (make_fp16_f32 (src1_buf[i * 2 * N + 2 * j + t + 1]) *
+ make_fp16_f32 (src2_buf[j * 2 * K + 2 * k + t + 1]));
+ }
+
+}
+
+void test_amx_fp16_dpfp16ps ()
+{
+ __tilecfg_u cfg;
+ __tile dst, dst_ref, src1, src2;
+ uint8_t tmp_dst_buf[1024], tmp_dst_zero_buf[1024];
+
+ init_fp16_max_tile_buffer (tmp_dst_buf);
+ init_fp16_max_tile_zero_buffer (tmp_dst_zero_buf);
+
+ init_tile_config (&cfg);
+ init_tile_reg_and_src_with_buffer (1, dst, tmp_dst_zero_buf);
+ init_tile_reg_and_src_with_buffer (2, src1, tmp_dst_buf);
+ init_tile_reg_and_src_with_buffer (3, src2, tmp_dst_buf);
+
+ calc_matrix_dpfp16ps (&dst, &src1, &src2);
+
+ _tile_dpfp16ps (1, 2, 3);
+ _tile_stored (1, dst_ref.buf, _STRIDE);
+
+ if (!check_float_tile_register (&dst_ref, &dst))
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/amxint8-dpbssd-2.c b/gcc/testsuite/gcc.target/i386/amxint8-dpbssd-2.c
index 74ad71b..d7efb3d 100644
--- a/gcc/testsuite/gcc.target/i386/amxint8-dpbssd-2.c
+++ b/gcc/testsuite/gcc.target/i386/amxint8-dpbssd-2.c
@@ -1,7 +1,6 @@
/* { dg-do run { target { ! ia32 } } } */
-/* { dg-require-effective-target amx_tile } */
/* { dg-require-effective-target amx_int8 } */
-/* { dg-options "-O2 -mamx-tile -mamx-int8" } */
+/* { dg-options "-O2 -mamx-int8" } */
#include <immintrin.h>
#define AMX_INT8
diff --git a/gcc/testsuite/gcc.target/i386/amxint8-dpbsud-2.c b/gcc/testsuite/gcc.target/i386/amxint8-dpbsud-2.c
index e7241bd..c8bf89d 100644
--- a/gcc/testsuite/gcc.target/i386/amxint8-dpbsud-2.c
+++ b/gcc/testsuite/gcc.target/i386/amxint8-dpbsud-2.c
@@ -1,7 +1,6 @@
/* { dg-do run { target { ! ia32 } } } */
-/* { dg-require-effective-target amx_tile } */
/* { dg-require-effective-target amx_int8 } */
-/* { dg-options "-O2 -mamx-tile -mamx-int8" } */
+/* { dg-options "-O2 -mamx-int8" } */
#include <immintrin.h>
#define AMX_INT8
diff --git a/gcc/testsuite/gcc.target/i386/amxint8-dpbusd-2.c b/gcc/testsuite/gcc.target/i386/amxint8-dpbusd-2.c
index f0b9f97..bb8777d 100644
--- a/gcc/testsuite/gcc.target/i386/amxint8-dpbusd-2.c
+++ b/gcc/testsuite/gcc.target/i386/amxint8-dpbusd-2.c
@@ -1,7 +1,6 @@
/* { dg-do run { target { ! ia32 } } } */
-/* { dg-require-effective-target amx_tile } */
/* { dg-require-effective-target amx_int8 } */
-/* { dg-options "-O2 -mamx-tile -mamx-int8" } */
+/* { dg-options "-O2 -mamx-int8" } */
#include <immintrin.h>
#define AMX_INT8
diff --git a/gcc/testsuite/gcc.target/i386/amxint8-dpbuud-2.c b/gcc/testsuite/gcc.target/i386/amxint8-dpbuud-2.c
index eb70b2f..d30f46d 100644
--- a/gcc/testsuite/gcc.target/i386/amxint8-dpbuud-2.c
+++ b/gcc/testsuite/gcc.target/i386/amxint8-dpbuud-2.c
@@ -1,7 +1,6 @@
/* { dg-do run { target { ! ia32 } } } */
-/* { dg-require-effective-target amx_tile } */
/* { dg-require-effective-target amx_int8 } */
-/* { dg-options "-O2 -mamx-tile -mamx-int8" } */
+/* { dg-options "-O2 -mamx-int8" } */
#include <immintrin.h>
#define AMX_INT8
diff --git a/gcc/testsuite/gcc.target/i386/avx-1.c b/gcc/testsuite/gcc.target/i386/avx-1.c
index 154e7b3..0b2b68b 100644
--- a/gcc/testsuite/gcc.target/i386/avx-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -m3dnow -mavx -mavx2 -maes -mpclmul -mgfni -mavx512bw -mavx512fp16 -mavx512vl" } */
+/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -m3dnow -mavx -mavx2 -maes -mpclmul -mgfni -mavx512bw -mavx512fp16 -mavx512vl -mprefetchi" } */
/* { dg-add-options bind_pic_locally } */
#include <mm_malloc.h>
@@ -153,7 +153,7 @@
#define __builtin_ia32_shufpd(A, B, N) __builtin_ia32_shufpd(A, B, 0)
/* xmmintrin.h */
-#define __builtin_prefetch(P, A, I) __builtin_prefetch(P, 0, _MM_HINT_NTA)
+#define __builtin_ia32_prefetch(A, B, C, D) __builtin_ia32_prefetch(A, 0, 3, 0)
#define __builtin_ia32_pshufw(A, N) __builtin_ia32_pshufw(A, 0)
#define __builtin_ia32_vec_set_v4hi(A, D, N) \
__builtin_ia32_vec_set_v4hi(A, D, 0)
@@ -835,6 +835,10 @@
#define __builtin_ia32_bextri_u32(X, Y) __builtin_ia32_bextri_u32 (X, 1)
#define __builtin_ia32_bextri_u64(X, Y) __builtin_ia32_bextri_u64 (X, 1)
+/* cmpccxadd.h */
+#define __builtin_ia32_cmpccxadd(A, B, C, D) __builtin_ia32_cmpccxadd(A, B, C, 1)
+#define __builtin_ia32_cmpccxadd64(A, B, C, D) __builtin_ia32_cmpccxadd64(A, B, C, 1)
+
#include <wmmintrin.h>
#include <immintrin.h>
#include <mm3dnow.h>
diff --git a/gcc/testsuite/gcc.target/i386/avx512bf16-cvtsbh2ss-1.c b/gcc/testsuite/gcc.target/i386/avx512bf16-cvtsbh2ss-1.c
index 8e929e6..edf30b5 100644
--- a/gcc/testsuite/gcc.target/i386/avx512bf16-cvtsbh2ss-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512bf16-cvtsbh2ss-1.c
@@ -1,8 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-mavx512bf16 -O2" } */
/* { dg-additional-options "-fno-PIE -mfpmath=sse" { target ia32 } } */
-/* { dg-final { scan-assembler-times "sall\[ \\t\]+\[^\{\n\]*16" 1 } } */
-/* { dg-final { scan-assembler-times "movl" 1 } } */
+/* { dg-final { scan-assembler-times "pslld" 1 } } */
#include <immintrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/avxneconvert-1.c b/gcc/testsuite/gcc.target/i386/avxneconvert-1.c
new file mode 100644
index 0000000..2bb129c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avxneconvert-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-mavxneconvert -O2" } */
+
+typedef float v8sf __attribute__((vector_size(32)));
+typedef __bf16 v8bf __attribute__((vector_size(16)));
+
+v8bf
+foo (v8sf a)
+{
+ return __builtin_ia32_cvtneps2bf16_v8sf (a);
+}
diff --git a/gcc/testsuite/gcc.target/i386/builtin_target.c b/gcc/testsuite/gcc.target/i386/builtin_target.c
index 3e7505a..fff643c 100644
--- a/gcc/testsuite/gcc.target/i386/builtin_target.c
+++ b/gcc/testsuite/gcc.target/i386/builtin_target.c
@@ -95,6 +95,11 @@ quick_check ()
assert (__builtin_cpu_supports ("avx512vpopcntdq") >= 0);
+ assert (__builtin_cpu_supports ("x86-64") >= 0);
+ assert (__builtin_cpu_supports ("x86-64-v2") >= 0);
+ assert (__builtin_cpu_supports ("x86-64-v3") >= 0);
+ assert (__builtin_cpu_supports ("x86-64-v4") >= 0);
+
/* Check CPU type. */
assert (__builtin_cpu_is ("amd") >= 0);
diff --git a/gcc/testsuite/gcc.target/i386/cbranchbf4.c b/gcc/testsuite/gcc.target/i386/cbranchbf4.c
new file mode 100644
index 0000000..8241a0c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cbranchbf4.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-fexcess-precision=16 -O -msse2 -mfpmath=sse" } */
+/* { dg-final { scan-assembler-times "pslld" 4 } } */
+
+char
+foo (__bf16 a, __bf16 b)
+{
+ return a > b;
+}
+
+float
+foo1 (__bf16 a, __bf16 b, float c, float d)
+{
+ return a > b ? c : d;
+}
diff --git a/gcc/testsuite/gcc.target/i386/cmpccxadd-1.c b/gcc/testsuite/gcc.target/i386/cmpccxadd-1.c
new file mode 100644
index 0000000..c825717
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cmpccxadd-1.c
@@ -0,0 +1,61 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mcmpccxadd" } */
+/* { dg-final { scan-assembler-times "cmpoxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnoxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpbxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnbxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpzxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnzxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpbexadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnbexadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpsxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnsxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmppxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnpxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmplxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnlxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmplexadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnlexadd\[ \\t\]" 2 } } */
+#include <x86gprintrin.h>
+
+int *a;
+int b, c;
+long long *d;
+long long e, f;
+
+void extern
+cmpccxadd_test(void)
+{
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_O);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_O);
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NO);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NO);
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_B);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_B);
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NB);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NB);
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_Z);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_Z);
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NZ);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NZ);
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_BE);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_BE);
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NBE);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NBE);
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_S);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_S);
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NS);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NS);
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_P);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_P);
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NP);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NP);
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_L);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_L);
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NL);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NL);
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_LE);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_LE);
+ b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NLE);
+ e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NLE);
+}
diff --git a/gcc/testsuite/gcc.target/i386/cmpccxadd-2.c b/gcc/testsuite/gcc.target/i386/cmpccxadd-2.c
new file mode 100644
index 0000000..e713344
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cmpccxadd-2.c
@@ -0,0 +1,138 @@
+/* { dg-do run { target { ! ia32 } } } */
+/* { dg-options "-O2 -mcmpccxadd" } */
+/* { dg-require-effective-target cmpccxadd } */
+
+#include <stdlib.h>
+#include <x86gprintrin.h>
+
+int
+main()
+{
+ if (!__builtin_cpu_supports("cmpccxadd"))
+ return 0;
+
+ int srcdest1[16] = { -2147483648,1,1,1,1,2,1,2,1,2,4,2,1,1,1,2 };
+ int srcdest2[16] = { 1,1,2,1,1,1,1,1,2,1,1,1,2,1,1,1 };
+ int src3[16] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };
+ int _srcdest1[16], _srcdest2[16], res[16], cond[16];
+ long long srcdest1_64[16] = { -9223372036854775807LL-1,1,1,1,1,2,1,2,1,2,4,2,1,1,1,2 };
+ long long srcdest2_64[16] = { 1,1,2,1,1,1,1,1,2,1,1,1,2,1,1,1 };
+ long long src3_64[16] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };
+ long long _srcdest1_64[16], _srcdest2_64[16], res_64[16], cond_64[16];
+
+ int tmp2[16];
+ long long tmp2_64[16];
+
+ int cf[16] = { 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+ int of[16] = { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+ int sf[16] = { 0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0 };
+ int zf[16] = { 0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0 };
+ int af[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+ int pf[16] = { 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0 };
+
+ for (int i = 0; i < 16; i++)
+ {
+ tmp2[i] = srcdest1[i] + src3[i];
+ tmp2_64[i] = srcdest1_64[i] + src3_64[i];
+ }
+
+ cond[0] = of[0] == 1 ? 1 : 0;
+ cond[1] = of[1] == 0 ? 1 : 0;
+ cond[2] = cf[2] == 1 ? 1 : 0;
+ cond[3] = cf[3] == 0 ? 1 : 0;
+ cond[4] = zf[4] == 1 ? 1 : 0;
+ cond[5] = zf[5] == 0 ? 1 : 0;
+ cond[6] = (cf[6] || zf[6]) == 1 ? 1 : 0;
+ cond[7] = (cf[7] || zf[7]) == 0 ? 1 : 0;
+ cond[8] = sf[8] == 1 ? 1 : 0;
+ cond[9] = sf[9] == 0 ? 1 : 0;
+ cond[10] = pf[10] == 1 ? 1 : 0;
+ cond[11] = pf[11] == 0 ? 1 : 0;
+ cond[12] = ((sf[12] && !of[12]) || (!sf[12] && of[12])) == 1 ? 1 : 0;
+ cond[13] = ((sf[13] && !of[13]) || (!sf[13] && of[13])) == 0 ? 1 : 0;
+ cond[14] = (((sf[14] && !of[14]) || (!sf[14] && of[14])) || zf[14]) == 1 ? 1 : 0;
+ cond[15] = (((sf[15] && !of[15]) || (!sf[15] && of[15])) || zf[15]) == 0 ? 1 : 0;
+
+ cond_64[0] = of[0] == 1 ? 1 : 0;
+ cond_64[1] = of[1] == 0 ? 1 : 0;
+ cond_64[2] = cf[2] == 1 ? 1 : 0;
+ cond_64[3] = cf[3] == 0 ? 1 : 0;
+ cond_64[4] = zf[4] == 1 ? 1 : 0;
+ cond_64[5] = zf[5] == 0 ? 1 : 0;
+ cond_64[6] = (cf[6] || zf[6]) == 1 ? 1 : 0;
+ cond_64[7] = (cf[7] || zf[7]) == 0 ? 1 : 0;
+ cond_64[8] = sf[8] == 1 ? 1 : 0;
+ cond_64[9] = sf[9] == 0 ? 1 : 0;
+ cond_64[10] = pf[10] == 1 ? 1 : 0;
+ cond_64[11] = pf[11] == 0 ? 1 : 0;
+ cond_64[12] = ((sf[12] && !of[12]) || (!sf[12] && of[12])) == 1 ? 1 : 0;
+ cond_64[13] = ((sf[13] && !of[13]) || (!sf[13] && of[13])) == 0 ? 1 : 0;
+ cond_64[14] = (((sf[14] && !of[14]) || (!sf[14] && of[14])) || zf[14]) == 1 ? 1 : 0;
+ cond_64[15] = (((sf[15] && !of[15]) || (!sf[15] && of[15])) || zf[15]) == 0 ? 1 : 0;
+
+ for (int i = 0; i < 16; i++)
+ {
+ if (cond[i] == 1)
+ {
+ _srcdest1[i] = tmp2[i];
+ }
+ else
+ {
+ _srcdest1[i] = srcdest1[i];
+ }
+ if (cond_64[i] == 1)
+ {
+ _srcdest1_64[i] = tmp2_64[i];
+ }
+ else
+ {
+ _srcdest1_64[i] = srcdest1_64[i];
+ }
+ _srcdest2[i] = srcdest1[i];
+ _srcdest2_64[i] = srcdest1_64[i];
+ }
+
+ res[0] = __cmpccxadd_epi32 (&srcdest1[0], srcdest2[0], src3[0], _CMPCCX_O);
+ res[1] = __cmpccxadd_epi32 (&srcdest1[1], srcdest2[1], src3[1], _CMPCCX_NO);
+ res[2] = __cmpccxadd_epi32 (&srcdest1[2], srcdest2[2], src3[2], _CMPCCX_B);
+ res[3] = __cmpccxadd_epi32 (&srcdest1[3], srcdest2[3], src3[3], _CMPCCX_NB);
+ res[4] = __cmpccxadd_epi32 (&srcdest1[4], srcdest2[4], src3[4], _CMPCCX_Z);
+ res[5] = __cmpccxadd_epi32 (&srcdest1[5], srcdest2[5], src3[5], _CMPCCX_NZ);
+ res[6] = __cmpccxadd_epi32 (&srcdest1[6], srcdest2[6], src3[6], _CMPCCX_BE);
+ res[7] = __cmpccxadd_epi32 (&srcdest1[7], srcdest2[7], src3[7], _CMPCCX_NBE);
+ res[8] = __cmpccxadd_epi32 (&srcdest1[8], srcdest2[8], src3[8], _CMPCCX_S);
+ res[9] = __cmpccxadd_epi32 (&srcdest1[9], srcdest2[9], src3[9], _CMPCCX_NS);
+ res[10] = __cmpccxadd_epi32 (&srcdest1[10], srcdest2[10], src3[10], _CMPCCX_P);
+ res[11] = __cmpccxadd_epi32 (&srcdest1[11], srcdest2[11], src3[11], _CMPCCX_NP);
+ res[12] = __cmpccxadd_epi32 (&srcdest1[12], srcdest2[12], src3[12], _CMPCCX_L);
+ res[13] = __cmpccxadd_epi32 (&srcdest1[13], srcdest2[13], src3[13], _CMPCCX_NL);
+ res[14] = __cmpccxadd_epi32 (&srcdest1[14], srcdest2[14], src3[14], _CMPCCX_LE);
+ res[15] = __cmpccxadd_epi32 (&srcdest1[15], srcdest2[15], src3[15], _CMPCCX_NLE);
+
+ res_64[0] = __cmpccxadd_epi64 (&srcdest1_64[0], srcdest2_64[0], src3_64[0], _CMPCCX_O);
+ res_64[1] = __cmpccxadd_epi64 (&srcdest1_64[1], srcdest2_64[1], src3_64[1], _CMPCCX_NO);
+ res_64[2] = __cmpccxadd_epi64 (&srcdest1_64[2], srcdest2_64[2], src3_64[2], _CMPCCX_B);
+ res_64[3] = __cmpccxadd_epi64 (&srcdest1_64[3], srcdest2_64[3], src3_64[3], _CMPCCX_NB);
+ res_64[4] = __cmpccxadd_epi64 (&srcdest1_64[4], srcdest2_64[4], src3_64[4], _CMPCCX_Z);
+ res_64[5] = __cmpccxadd_epi64 (&srcdest1_64[5], srcdest2_64[5], src3_64[5], _CMPCCX_NZ);
+ res_64[6] = __cmpccxadd_epi64 (&srcdest1_64[6], srcdest2_64[6], src3_64[6], _CMPCCX_BE);
+ res_64[7] = __cmpccxadd_epi64 (&srcdest1_64[7], srcdest2_64[7], src3_64[7], _CMPCCX_NBE);
+ res_64[8] = __cmpccxadd_epi64 (&srcdest1_64[8], srcdest2_64[8], src3_64[8], _CMPCCX_S);
+ res_64[9] = __cmpccxadd_epi64 (&srcdest1_64[9], srcdest2_64[9], src3_64[9], _CMPCCX_NS);
+ res_64[10] = __cmpccxadd_epi64 (&srcdest1_64[10], srcdest2_64[10], src3_64[10], _CMPCCX_P);
+ res_64[11] = __cmpccxadd_epi64 (&srcdest1_64[11], srcdest2_64[11], src3_64[11], _CMPCCX_NP);
+ res_64[12] = __cmpccxadd_epi64 (&srcdest1_64[12], srcdest2_64[12], src3_64[12], _CMPCCX_L);
+ res_64[13] = __cmpccxadd_epi64 (&srcdest1_64[13], srcdest2_64[13], src3_64[13], _CMPCCX_NL);
+ res_64[14] = __cmpccxadd_epi64 (&srcdest1_64[14], srcdest2_64[14], src3_64[14], _CMPCCX_LE);
+ res_64[15] = __cmpccxadd_epi64 (&srcdest1_64[15], srcdest2_64[15], src3_64[15], _CMPCCX_NLE);
+
+ for (int i = 0; i < 16; i++)
+ {
+ if ((srcdest1[i] != _srcdest1[i]) || (res[i] != _srcdest2[i]))
+ abort();
+ if ((srcdest1_64[i] != _srcdest1_64[i]) || (res_64[i] != _srcdest2_64[i]))
+ abort();
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/excess-precision-11.c b/gcc/testsuite/gcc.target/i386/excess-precision-11.c
new file mode 100644
index 0000000..b83ecae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/excess-precision-11.c
@@ -0,0 +1,8 @@
+/* Test C2x constexpr. Valid code, compilation tests, excess precision. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors -mfpmath=387 -fexcess-precision=standard" } */
+
+constexpr long double ld = 1.0 / 3.0;
+constexpr long double ld2 = 1.1;
+constexpr double d = (double) (1.0 / 3.0);
+constexpr double d2 = (double) 1.1;
diff --git a/gcc/testsuite/gcc.target/i386/excess-precision-12.c b/gcc/testsuite/gcc.target/i386/excess-precision-12.c
new file mode 100644
index 0000000..b44f0b5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/excess-precision-12.c
@@ -0,0 +1,6 @@
+/* Test C2x constexpr. Invalid code, compilation tests, excess precision. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors -mfpmath=387 -fexcess-precision=standard" } */
+
+constexpr double d = 1.0 / 3.0; /* { dg-error "'constexpr' initializer not representable in type of object" } */
+constexpr double d2 = 1.1; /* { dg-error "'constexpr' initializer not representable in type of object" } */
diff --git a/gcc/testsuite/gcc.target/i386/extendbfsf.c b/gcc/testsuite/gcc.target/i386/extendbfsf.c
new file mode 100644
index 0000000..a38fa68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/extendbfsf.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512bf16 -mavx512vl -O2 -ffast-math" } */
+/* { dg-final { scan-assembler-times "pslld" 1 } } */
+/* { dg-final { scan-assembler-times "vcvtneps2bf16" 1 } } */
+
+float
+extendsfbf (__bf16 a)
+{
+ return a;
+}
+
+__bf16
+truncsfbf (float a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc
index 5655c5b..3780230 100644
--- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc
+++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc
@@ -83,6 +83,10 @@ extern void test_avx512fp16 (void) __attribute__((__target__("avx512fp16")));
extern void test_avxifma (void) __attribute__((__target__("avxifma")));
extern void test_avxvnniint8 (void) __attribute__((__target__("avxvnniint8")));
extern void test_avxneconvert (void) __attribute__((__target__("avxneconvert")));
+extern void test_cmpccxadd (void) __attribute__((__target__("cmpccxadd")));
+extern void test_amx_fp16 (void) __attribute__((__target__("amx-fp16")));
+extern void test_prefetchi (void) __attribute__((__target__("prefetchi")));
+extern void test_raoint (void) __attribute__((__target__("raoint")));
extern void test_no_sgx (void) __attribute__((__target__("no-sgx")));
extern void test_no_avx5124fmaps(void) __attribute__((__target__("no-avx5124fmaps")));
@@ -167,6 +171,10 @@ extern void test_no_avx512fp16 (void) __attribute__((__target__("no-avx512fp16"
extern void test_no_avxifma (void) __attribute__((__target__("no-avxifma")));
extern void test_no_avxvnniint8 (void) __attribute__((__target__("no-avxvnniint8")));
extern void test_no_avxneconvert (void) __attribute__((__target__("no-avxneconvert")));
+extern void test_no_cmpccxadd (void) __attribute__((__target__("no-cmpccxadd")));
+extern void test_no_amx_fp16 (void) __attribute__((__target__("no-amx-fp16")));
+extern void test_no_prefetchi (void) __attribute__((__target__("no-prefetchi")));
+extern void test_no_raoint (void) __attribute__((__target__("no-raoint")));
extern void test_arch_nocona (void) __attribute__((__target__("arch=nocona")));
extern void test_arch_core2 (void) __attribute__((__target__("arch=core2")));
@@ -177,6 +185,8 @@ extern void test_arch_silvermont (void) __attribute__((__target__("arch=silverm
extern void test_arch_goldmont (void) __attribute__((__target__("arch=goldmont")));
extern void test_arch_goldmont_plus (void) __attribute__((__target__("arch=goldmont-plus")));
extern void test_arch_tremont (void) __attribute__((__target__("arch=tremont")));
+extern void test_arch_sierraforest (void) __attribute__((__target__("arch=sierraforest")));
+extern void test_arch_grandridge (void) __attribute__((__target__("arch=grandridge")));
extern void test_arch_knl (void) __attribute__((__target__("arch=knl")));
extern void test_arch_knm (void) __attribute__((__target__("arch=knm")));
extern void test_arch_skylake (void) __attribute__((__target__("arch=skylake")));
@@ -190,6 +200,7 @@ extern void test_arch_cooperlake (void) __attribute__((__target__("arch=
extern void test_arch_sapphirerapids (void) __attribute__((__target__("arch=sapphirerapids")));
extern void test_arch_alderlake (void) __attribute__((__target__("arch=alderlake")));
extern void test_arch_rocketlake (void) __attribute__((__target__("arch=rocketlake")));
+extern void test_arch_graniterapids (void) __attribute__((__target__("arch=graniterapids")));
extern void test_arch_lujiazui (void) __attribute__((__target__("arch=lujiazui")));
extern void test_arch_k8 (void) __attribute__((__target__("arch=k8")));
extern void test_arch_k8_sse3 (void) __attribute__((__target__("arch=k8-sse3")));
diff --git a/gcc/testsuite/gcc.target/i386/pieces-memset-3.c b/gcc/testsuite/gcc.target/i386/pieces-memset-3.c
index 765441a..431732a 100644
--- a/gcc/testsuite/gcc.target/i386/pieces-memset-3.c
+++ b/gcc/testsuite/gcc.target/i386/pieces-memset-3.c
@@ -13,6 +13,6 @@ foo (int x)
/* { dg-final { scan-assembler-times "vinserti64x4\[ \\t\]+\[^\n\]*%zmm" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqu64\[ \\t\]+\[^\n\]*%zmm" 1 } } */
/* No need to dynamically realign the stack here. */
-/* { dg-final { scan-assembler-not "and\[^\n\r]*%\[re\]sp" { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-not "and\[^\n\r]*%\[re\]sp" } } */
/* Nor use a frame pointer. */
-/* { dg-final { scan-assembler-not "%\[re\]bp" { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-not "%\[re\]bp" { xfail ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pieces-memset-37.c b/gcc/testsuite/gcc.target/i386/pieces-memset-37.c
index 0c5056b..5cc4d77 100644
--- a/gcc/testsuite/gcc.target/i386/pieces-memset-37.c
+++ b/gcc/testsuite/gcc.target/i386/pieces-memset-37.c
@@ -10,6 +10,6 @@ foo (int a1, int a2, int a3, int a4, int a5, int a6, int x, char *dst)
/* { dg-final { scan-assembler-times "vpbroadcastb\[ \\t\]+\[^\n\]*%ymm" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]+\[^\n\]*%ymm" 2 } } */
/* No need to dynamically realign the stack here. */
-/* { dg-final { scan-assembler-not "and\[^\n\r]*%\[re\]sp" { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-not "and\[^\n\r]*%\[re\]sp" } } */
/* Nor use a frame pointer. */
/* { dg-final { scan-assembler-not "%\[re\]bp" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pieces-memset-39.c b/gcc/testsuite/gcc.target/i386/pieces-memset-39.c
index e33644c..8627127 100644
--- a/gcc/testsuite/gcc.target/i386/pieces-memset-39.c
+++ b/gcc/testsuite/gcc.target/i386/pieces-memset-39.c
@@ -11,6 +11,6 @@ foo (int a1, int a2, int a3, int a4, int a5, int a6, int x, char *dst)
/* { dg-final { scan-assembler-not "vinserti64x4" } } */
/* { dg-final { scan-assembler-times "vmovdqu8\[ \\t\]+\[^\n\]*%zmm" 1 } } */
/* No need to dynamically realign the stack here. */
-/* { dg-final { scan-assembler-not "and\[^\n\r]*%\[re\]sp" { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-not "and\[^\n\r]*%\[re\]sp" } } */
/* Nor use a frame pointer. */
/* { dg-final { scan-assembler-not "%\[re\]bp" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pieces-memset-50.c b/gcc/testsuite/gcc.target/i386/pieces-memset-50.c
new file mode 100644
index 0000000..c09e7c3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pieces-memset-50.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=alderlake" } */
+
+extern char *dst;
+
+void
+foo (int x)
+{
+ __builtin_memset (dst, x, 64);
+}
+
+/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]+\[^\n\]*%ymm" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr106577.c b/gcc/testsuite/gcc.target/i386/pr106577.c
new file mode 100644
index 0000000..1182d4f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr106577.c
@@ -0,0 +1,10 @@
+/* PR target/106577 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -mavx" } */
+
+int i;
+void
+foo (void)
+{
+ i ^= !(((unsigned __int128)0xf0f0f0f0f0f0f0f0 << 64 | 0xf0f0f0f0f0f0f0f0) & i);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr107304.c b/gcc/testsuite/gcc.target/i386/pr107304.c
index 24d6879..0043b7b 100644
--- a/gcc/testsuite/gcc.target/i386/pr107304.c
+++ b/gcc/testsuite/gcc.target/i386/pr107304.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O0 -march=tigerlake" } */
+/* { dg-require-ifunc "" } */
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/i386/pr107540.c b/gcc/testsuite/gcc.target/i386/pr107540.c
new file mode 100644
index 0000000..a0351ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr107540.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-flive-range-shrinkage -mavx" } */
+
+typedef double __attribute__((__vector_size__ (32))) V;
+
+V v;
+
+void
+foo (void)
+{
+ v = __builtin_ia32_movddup256 (v);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr107546.c b/gcc/testsuite/gcc.target/i386/pr107546.c
new file mode 100644
index 0000000..e5cf56d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr107546.c
@@ -0,0 +1,19 @@
+/* PR target/107546 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -mno-xop -mno-avx512f" } */
+/* { dg-final { scan-assembler-not "pcmpeqb\t" } } */
+/* { dg-final { scan-assembler-times "pcmpgtb\t" 2 } } */
+
+typedef signed char V __attribute__((vector_size(16)));
+
+V
+foo (V x)
+{
+ return x < 48;
+}
+
+V
+bar (V x)
+{
+ return x >= (V) { 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57 };
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr107627-1.c b/gcc/testsuite/gcc.target/i386/pr107627-1.c
new file mode 100644
index 0000000..60ec87b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr107627-1.c
@@ -0,0 +1,22 @@
+/* PR target/107627 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-final { scan-assembler-not "\torq\t" } } */
+
+static inline unsigned __int128
+foo (unsigned long long x, unsigned long long y)
+{
+ return ((unsigned __int128) x << 64) | y;
+}
+
+static inline unsigned long long
+bar (unsigned long long x, unsigned long long y, unsigned z)
+{
+ return foo (x, y) >> (z % 64);
+}
+
+void
+baz (unsigned long long *x, const unsigned long long *y, unsigned z)
+{
+ x[0] = bar (y[0], y[1], z);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr107627-2.c b/gcc/testsuite/gcc.target/i386/pr107627-2.c
new file mode 100644
index 0000000..7f96613
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr107627-2.c
@@ -0,0 +1,22 @@
+/* PR target/107627 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-final { scan-assembler-not "\torl\t" } } */
+
+static inline unsigned long long
+qux (unsigned int x, unsigned int y)
+{
+ return ((unsigned long long) x << 32) | y;
+}
+
+static inline unsigned int
+corge (unsigned int x, unsigned int y, unsigned z)
+{
+ return qux (x, y) >> (z % 32);
+}
+
+void
+garply (unsigned int *x, const unsigned int *y, unsigned z)
+{
+ x[0] = corge (y[0], y[1], z);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr107627-3.c b/gcc/testsuite/gcc.target/i386/pr107627-3.c
new file mode 100644
index 0000000..99c7f7f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr107627-3.c
@@ -0,0 +1,28 @@
+/* PR target/107627 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-final { scan-assembler-not "\torq\t" } } */
+
+static inline unsigned __int128
+foo (unsigned long long x, unsigned long long y)
+{
+ return ((unsigned __int128) x << 64) | y;
+}
+
+static inline unsigned long long
+bar (unsigned long long x, unsigned long long y, unsigned z)
+{
+ return foo (x, y) >> (z % 64);
+}
+
+void
+baz (unsigned long long *x, const unsigned long long *y, unsigned z)
+{
+ x[0] = bar (0xdeadbeefcafebabeULL, y[1], z);
+}
+
+void
+qux (unsigned long long *x, const unsigned long long *y, unsigned z)
+{
+ x[0] = bar (y[0], 0xdeadbeefcafebabeULL, z);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr107627-4.c b/gcc/testsuite/gcc.target/i386/pr107627-4.c
new file mode 100644
index 0000000..f7d9bdb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr107627-4.c
@@ -0,0 +1,28 @@
+/* PR target/107627 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-final { scan-assembler-not "\torl\t" } } */
+
+static inline unsigned long long
+qux (unsigned int x, unsigned int y)
+{
+ return ((unsigned long long) x << 32) | y;
+}
+
+static inline unsigned int
+corge (unsigned int x, unsigned int y, unsigned z)
+{
+ return qux (x, y) >> (z % 32);
+}
+
+void
+garply (unsigned int *x, const unsigned int *y, unsigned z)
+{
+ x[0] = corge (0xdeadbeefU, y[1], z);
+}
+
+void
+fred (unsigned int *x, const unsigned int *y, unsigned z)
+{
+ x[0] = corge (y[0], 0xcafebabeU, z);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr107628.c b/gcc/testsuite/gcc.target/i386/pr107628.c
new file mode 100644
index 0000000..a0de117
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr107628.c
@@ -0,0 +1,11 @@
+/* PR target/107628 */
+/* { dg-do compile } */
+/* { dg-options "-fsignaling-nans -msse2" } */
+
+typedef __bf16 __attribute__((__vector_size__ (2))) V;
+
+void
+foo (V v)
+{
+ v < (V) (short) 65436;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr107647.c b/gcc/testsuite/gcc.target/i386/pr107647.c
new file mode 100644
index 0000000..45fcb55
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr107647.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffp-contract=off -mavx2 -mfma" } */
+
+void cscal(int n, float da_r, float *x)
+{
+ for (int i = 0; i < n; i += 4)
+ {
+ float temp0 = da_r * x[i] - x[i+1];
+ float temp1 = da_r * x[i+2] - x[i+3];
+ x[i+1] = da_r * x[i+1] + x[i];
+ x[i+3] = da_r * x[i+3] + x[i+2];
+ x[i] = temp0;
+ x[i+2] = temp1;
+ }
+}
+
+/* { dg-final { scan-assembler-not "fma" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr107863.c b/gcc/testsuite/gcc.target/i386/pr107863.c
new file mode 100644
index 0000000..99fd85d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr107863.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx2 -O" } */
+
+typedef char v16qi __attribute__((vector_size(16)));
+
+v16qi foo(v16qi a){
+ return __builtin_ia32_vec_set_v16qi (a, -1, 2);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr107934.c b/gcc/testsuite/gcc.target/i386/pr107934.c
new file mode 100644
index 0000000..59106b29
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr107934.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=knl -ffinite-math-only -msse2" } */
+
+int
+foo (__bf16 bf)
+{
+ return bf;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr107969.c b/gcc/testsuite/gcc.target/i386/pr107969.c
new file mode 100644
index 0000000..f73a862
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr107969.c
@@ -0,0 +1,12 @@
+/* PR target/107969 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fexcess-precision=16 -msoft-float -msse2" } */
+
+int i;
+__bf16 f;
+
+void
+bar (void)
+{
+ i *= 0 <= f;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr107970.c b/gcc/testsuite/gcc.target/i386/pr107970.c
new file mode 100644
index 0000000..1fbbb14
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr107970.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-Ofast -m3dnow -msse4.1" } */
+
+float *foo_p;
+
+void
+foo(float *__restrict q) {
+ foo_p[0] = __builtin_truncf(q[0]);
+ foo_p[1] = __builtin_truncf(q[1]);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr86270.c b/gcc/testsuite/gcc.target/i386/pr86270.c
index 81841ef..98b012c 100644
--- a/gcc/testsuite/gcc.target/i386/pr86270.c
+++ b/gcc/testsuite/gcc.target/i386/pr86270.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -fno-unroll-loops" } */
int *a;
long len;
diff --git a/gcc/testsuite/gcc.target/i386/pr93002.c b/gcc/testsuite/gcc.target/i386/pr93002.c
index 0248fcc..7e2d869 100644
--- a/gcc/testsuite/gcc.target/i386/pr93002.c
+++ b/gcc/testsuite/gcc.target/i386/pr93002.c
@@ -1,6 +1,6 @@
/* PR target/93002 */
/* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -fno-unroll-loops" } */
/* { dg-final { scan-assembler-not "cmp\[^\n\r]*-1" } } */
volatile int sink;
diff --git a/gcc/testsuite/gcc.target/i386/pr93492-2.c b/gcc/testsuite/gcc.target/i386/pr93492-2.c
index 3d67095..ede8c20 100644
--- a/gcc/testsuite/gcc.target/i386/pr93492-2.c
+++ b/gcc/testsuite/gcc.target/i386/pr93492-2.c
@@ -1,7 +1,7 @@
/* { dg-do "compile" { target *-*-linux* } } */
/* { dg-options "-O1 -fcf-protection -mmanual-endbr -fasynchronous-unwind-tables" } */
-/* Test the placement of the .LPFE1 label. */
+/* Test the placement of the .LPFE0 label. */
void
__attribute__ ((cf_check,patchable_function_entry (1, 0)))
@@ -9,4 +9,4 @@ f10_endbr (void)
{
}
-/* { dg-final { scan-assembler "\t\.cfi_startproc\n\tendbr(32|64)\n.*\.LPFE1:\n\tnop\n\tret\n" } } */
+/* { dg-final { scan-assembler "\t\.cfi_startproc\n\tendbr(32|64)\n.*\.LPFE0:\n\tnop\n\tret\n" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr93492-3.c b/gcc/testsuite/gcc.target/i386/pr93492-3.c
index a625c92..b68da30 100644
--- a/gcc/testsuite/gcc.target/i386/pr93492-3.c
+++ b/gcc/testsuite/gcc.target/i386/pr93492-3.c
@@ -2,7 +2,7 @@
/* { dg-require-effective-target mfentry } */
/* { dg-options "-O1 -fcf-protection -mmanual-endbr -mfentry -pg -fasynchronous-unwind-tables" } */
-/* Test the placement of the .LPFE1 label. */
+/* Test the placement of the .LPFE0 label. */
void
__attribute__ ((cf_check,patchable_function_entry (1, 0)))
@@ -10,4 +10,4 @@ f10_endbr (void)
{
}
-/* { dg-final { scan-assembler "\t\.cfi_startproc\n\tendbr(32|64)\n.*\.LPFE1:\n\tnop\n1:\tcall\t\[^\n\]*__fentry__\[^\n\]*\n\tret\n" } } */
+/* { dg-final { scan-assembler "\t\.cfi_startproc\n\tendbr(32|64)\n.*\.LPFE0:\n\tnop\n1:\tcall\t\[^\n\]*__fentry__\[^\n\]*\n\tret\n" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr93492-4.c b/gcc/testsuite/gcc.target/i386/pr93492-4.c
index 8f205c34..c73034a 100644
--- a/gcc/testsuite/gcc.target/i386/pr93492-4.c
+++ b/gcc/testsuite/gcc.target/i386/pr93492-4.c
@@ -1,11 +1,11 @@
/* { dg-do "compile" { target *-*-linux* } } */
/* { dg-options "-O1 -fpatchable-function-entry=1 -fasynchronous-unwind-tables" } */
-/* Test the placement of the .LPFE1 label. */
+/* Test the placement of the .LPFE0 label. */
void
foo (void)
{
}
-/* { dg-final { scan-assembler "\t\.cfi_startproc\n.*\.LPFE1:\n\tnop\n\tret\n" } } */
+/* { dg-final { scan-assembler "\t\.cfi_startproc\n.*\.LPFE0:\n\tnop\n\tret\n" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr93492-5.c b/gcc/testsuite/gcc.target/i386/pr93492-5.c
index 1ca5ba1..ee9849a 100644
--- a/gcc/testsuite/gcc.target/i386/pr93492-5.c
+++ b/gcc/testsuite/gcc.target/i386/pr93492-5.c
@@ -2,11 +2,11 @@
/* { dg-options "-O1 -fpatchable-function-entry=1 -mfentry -pg -fasynchronous-unwind-tables" } */
/* { dg-additional-options "-fno-PIE" { target ia32 } } */
-/* Test the placement of the .LPFE1 label. */
+/* Test the placement of the .LPFE0 label. */
void
foo (void)
{
}
-/* { dg-final { scan-assembler "\t\.cfi_startproc\n.*\.LPFE1:\n\tnop\n1:\tcall\t\[^\n\]*__fentry__\[^\n\]*\n\tret\n" } } */
+/* { dg-final { scan-assembler "\t\.cfi_startproc\n.*\.LPFE0:\n\tnop\n1:\tcall\t\[^\n\]*__fentry__\[^\n\]*\n\tret\n" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr98167.c b/gcc/testsuite/gcc.target/i386/pr98167.c
new file mode 100644
index 0000000..40e0ac1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr98167.c
@@ -0,0 +1,44 @@
+/* PR target/98167 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx2" } */
+
+/* { dg-final { scan-assembler-times "vpshufd\t" 8 } } */
+/* { dg-final { scan-assembler-times "vpermilps\t" 3 } } */
+
+#define VEC_PERM_4 \
+ 2, 3, 1, 0
+#define VEC_PERM_8 \
+ 4, 5, 6, 7, 3, 2, 1, 0
+#define VEC_PERM_16 \
+ 8, 9, 10, 11, 12, 13, 14, 15, 7, 6, 5, 4, 3, 2, 1, 0
+
+#define TYPE_PERM_OP(type, size, op, name) \
+ typedef type v##size##s##type __attribute__ ((vector_size(4*size))); \
+ v##size##s##type type##foo##size##i_##name (v##size##s##type a, \
+ v##size##s##type b) \
+ { \
+ v##size##s##type a1 = __builtin_shufflevector (a, a, \
+ VEC_PERM_##size); \
+ v##size##s##type b1 = __builtin_shufflevector (b, b, \
+ VEC_PERM_##size); \
+ return a1 op b1; \
+ }
+
+#define INT_PERMS(op, name) \
+ TYPE_PERM_OP (int, 4, op, name) \
+
+#define FP_PERMS(op, name) \
+ TYPE_PERM_OP (float, 4, op, name) \
+
+INT_PERMS (+, add)
+INT_PERMS (-, sub)
+INT_PERMS (*, mul)
+INT_PERMS (|, ior)
+INT_PERMS (^, xor)
+INT_PERMS (&, and)
+INT_PERMS (<<, shl)
+INT_PERMS (>>, shr)
+FP_PERMS (+, add)
+FP_PERMS (-, sub)
+FP_PERMS (*, mul)
+
diff --git a/gcc/testsuite/gcc.target/i386/prefetchi-1.c b/gcc/testsuite/gcc.target/i386/prefetchi-1.c
new file mode 100644
index 0000000..80f25e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/prefetchi-1.c
@@ -0,0 +1,40 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mprefetchi -O2" } */
+/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit0\[ \\t\]+" 2 } } */
+/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit1\[ \\t\]+" 2 } } */
+
+#include <x86intrin.h>
+
+int
+bar (int a)
+{
+ return a + 1;
+}
+
+int
+foo1 (int b)
+{
+ _mm_prefetch (bar, _MM_HINT_IT0);
+ return bar (b) + 1;
+}
+
+int
+foo2 (int b)
+{
+ _mm_prefetch (bar, _MM_HINT_IT1);
+ return bar (b) + 1;
+}
+
+int
+foo3 (int b)
+{
+ _m_prefetchit0 (bar);
+ return bar (b) + 1;
+}
+
+int
+foo4 (int b)
+{
+ _m_prefetchit1 (bar);
+ return bar (b) + 1;
+}
diff --git a/gcc/testsuite/gcc.target/i386/prefetchi-2.c b/gcc/testsuite/gcc.target/i386/prefetchi-2.c
new file mode 100644
index 0000000..e05ce9c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/prefetchi-2.c
@@ -0,0 +1,26 @@
+/* { dg-do compile { target { ia32 } } } */
+/* { dg-options "-mprefetchi -O2" } */
+/* { dg-final { scan-assembler-not "\[ \\t\]+prefetchit0" } } */
+/* { dg-final { scan-assembler-not "\[ \\t\]+prefetchit1" } } */
+
+#include <x86intrin.h>
+
+int
+bar (int a)
+{
+ return a + 1;
+}
+
+int
+foo1 (int b)
+{
+ __builtin_ia32_prefetch (bar, 0, 3, 1); /* { dg-warning "instruction prefetch applies when in 64-bit mode with RIP-relative addressing and option '-mprefetchi'; they stay NOPs otherwise" } */
+ return bar (b) + 1;
+}
+
+int
+foo2 (int b)
+{
+ __builtin_ia32_prefetchi (bar, 2); /* { dg-warning "instruction prefetch applies when in 64-bit mode with RIP-relative addressing and option '-mprefetchi'; they stay NOPs otherwise" } */
+ return bar (b) + 1;
+}
diff --git a/gcc/testsuite/gcc.target/i386/prefetchi-3.c b/gcc/testsuite/gcc.target/i386/prefetchi-3.c
new file mode 100644
index 0000000..f0a4173
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/prefetchi-3.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-mprefetchi -O2" } */
+/* { dg-final { scan-assembler-not "prefetchit0" } } */
+/* { dg-final { scan-assembler-not "prefetchit1" } } */
+
+#include <x86intrin.h>
+
+void* p;
+
+void extern
+prefetchi_test1 (void)
+{
+ __builtin_ia32_prefetchi (p, 2); /* { dg-warning "instruction prefetch applies when in 64-bit mode with RIP-relative addressing and option '-mprefetchi'; they stay NOPs otherwise" } */
+}
+
+void extern
+prefetchi_test2 (void)
+{
+ __builtin_ia32_prefetch (p, 0, 3, 1); /* { dg-warning "instruction prefetch applies when in 64-bit mode with RIP-relative addressing and option '-mprefetchi'; they stay NOPs otherwise" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/prefetchi-4.c b/gcc/testsuite/gcc.target/i386/prefetchi-4.c
new file mode 100644
index 0000000..73ae596
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/prefetchi-4.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+#include <x86intrin.h>
+
+void* p;
+
+void extern
+prefetch_test (void)
+{
+ __builtin_ia32_prefetch (p, 0, 3, 0);
+ __builtin_ia32_prefetch (p, 0, 2, 0);
+ __builtin_ia32_prefetch (p, 0, 1, 0);
+ __builtin_ia32_prefetch (p, 0, 0, 0);
+ __builtin_ia32_prefetch (p, 1, 3, 0);
+ __builtin_ia32_prefetch (p, 1, 2, 0);
+ __builtin_ia32_prefetch (p, 1, 1, 0);
+ __builtin_ia32_prefetch (p, 1, 0, 0);
+}
diff --git a/gcc/testsuite/gcc.target/i386/prefetchi-5.c b/gcc/testsuite/gcc.target/i386/prefetchi-5.c
new file mode 100644
index 0000000..8c26540
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/prefetchi-5.c
@@ -0,0 +1,4 @@
+/* { dg-do compile { target { ia32 } } } */
+/* { dg-options "-O0 -march=pentiumpro" } */
+
+#include "prefetchi-4.c"
diff --git a/gcc/testsuite/gcc.target/i386/rao-helper.h b/gcc/testsuite/gcc.target/i386/rao-helper.h
new file mode 100644
index 0000000..df38551
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/rao-helper.h
@@ -0,0 +1,79 @@
+#include <immintrin.h>
+#include <stdint.h>
+#include <pthread.h>
+#include <string.h>
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+#include "cpuid.h"
+
+typedef struct {
+ uint32_t id; /* filled in by launch_threads. */
+} state_t;
+
+static pthread_t* threads = 0;
+static state_t* thread_state = 0;
+static const unsigned int num_threads = 4;
+
+static void* threads_worker (state_t *tstate);
+
+void launch_threads (uint32_t nthreads,
+ void* (*worker)(state_t*),
+ state_t* tstate_proto)
+{
+ int i;
+ thread_state = malloc (sizeof (state_t) *nthreads);
+ threads = malloc (sizeof (pthread_t) *nthreads);
+ memset (threads, 0, sizeof (pthread_t) *nthreads);
+ for(i = 0; i < nthreads; i++)
+ {
+ memcpy (thread_state + i, tstate_proto, sizeof (state_t));
+ thread_state[i].id = i;
+ pthread_create (threads+i, NULL,
+ (void* (*)(void*))worker,
+ (void*) (thread_state+i));
+ }
+}
+
+void wait()
+{
+ int i;
+ for(i = 0; i < num_threads; i++)
+ pthread_join (threads[i], 0);
+ free (threads);
+ threads = 0;
+ free (thread_state);
+ thread_state = 0;
+}
+
+#ifndef DO_TEST
+#define DO_TEST do_test
+static void rao_test (void);
+__attribute__ ((noinline))
+static void
+do_test (void)
+{
+ state_t tstate_proto;
+ launch_threads(num_threads, threads_worker, &tstate_proto);
+ wait();
+ rao_test ();
+}
+#endif
+
+int
+main()
+{
+ if (__builtin_cpu_supports ("raoint"))
+ {
+ DO_TEST ();
+#ifdef DEBUG
+ printf ("PASSED\n");
+#endif
+ }
+#ifdef DEBUG
+ else
+ printf ("SKIPPED\n");
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/raoint-1.c b/gcc/testsuite/gcc.target/i386/raoint-1.c
new file mode 100644
index 0000000..d4f880e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/raoint-1.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-mraoint -O2" } */
+/* { dg-final { scan-assembler-times "aadd" 2 { target {! ia32 } } } } */
+/* { dg-final { scan-assembler-times "aand" 2 { target {! ia32 } } } } */
+/* { dg-final { scan-assembler-times "aor" 2 { target {! ia32 } } } } */
+/* { dg-final { scan-assembler-times "axor" 2 { target {! ia32 } } } } */
+/* { dg-final { scan-assembler-times "aadd" 1 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "aand" 1 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "aor" 1 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "axor" 1 { target ia32 } } } */
+#include <immintrin.h>
+
+volatile int x;
+volatile long long y;
+int *a;
+long long *b;
+
+void extern
+rao_int_test (void)
+{
+ _aadd_i32 (a, x);
+ _aand_i32 (a, x);
+ _aor_i32 (a, x);
+ _axor_i32 (a, x);
+#ifdef __x86_64__
+ _aadd_i64 (b, y);
+ _aand_i64 (b, y);
+ _aor_i64 (b, y);
+ _axor_i64 (b, y);
+#endif
+}
diff --git a/gcc/testsuite/gcc.target/i386/raoint-aadd-2.c b/gcc/testsuite/gcc.target/i386/raoint-aadd-2.c
new file mode 100644
index 0000000..8ae9bc2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/raoint-aadd-2.c
@@ -0,0 +1,24 @@
+/* { dg-do run { target { *-*-linux* && { ! ia32 } } } }*/
+/* { dg-require-effective-target raoint }*/
+/* { dg-options "-pthread -O2 -mraoint" }*/
+#include "rao-helper.h"
+
+const unsigned int inc_val = 3;
+const unsigned int num_iters= 1000000;
+static long long shared_val = 0;
+
+static
+void* threads_worker (state_t *tstate)
+{
+ int i;
+ for (i = 0; i < num_iters; i++)
+ _aadd_i64 (&shared_val, inc_val);
+ return 0;
+}
+
+static void
+rao_test (void)
+{
+ if (shared_val != num_iters * num_threads * inc_val)
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/raoint-aand-2.c b/gcc/testsuite/gcc.target/i386/raoint-aand-2.c
new file mode 100644
index 0000000..40bc1d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/raoint-aand-2.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { *-*-linux* && { ! ia32 } } } }*/
+/* { dg-require-effective-target raoint }*/
+/* { dg-options "-pthread -O2 -mraoint" }*/
+#include "rao-helper.h"
+
+const unsigned int num_iters= 1000000;
+unsigned int thread_val[4] = { 0xffffff5a, 0xffff96ff, 0xff73ffff, 0xceffffff };
+static long long shared_val = 0xffffffff;
+unsigned int expected_val = 0xce73965a;
+
+static void*
+threads_worker (state_t *tstate)
+{
+ int i;
+ unsigned int val = thread_val[tstate->id];
+ for (i = 0; i < num_iters; i++)
+ _aand_i64 (&shared_val, val);
+}
+
+static void
+rao_test(void)
+{
+ if (shared_val != expected_val)
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/raoint-aor-2.c b/gcc/testsuite/gcc.target/i386/raoint-aor-2.c
new file mode 100644
index 0000000..ec7f7cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/raoint-aor-2.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { *-*-linux* && { ! ia32 } } } }*/
+/* { dg-require-effective-target raoint }*/
+/* { dg-options "-pthread -O2 -mraoint" }*/
+#include "rao-helper.h"
+
+const unsigned int num_iters= 1000000;
+unsigned int thread_val[4] = { 0x5a, 0x9600, 0x730000, 0xce000000 };
+static long long shared_val = 0;
+unsigned int expected_val = 0xce73965a;
+
+static void*
+threads_worker (state_t *tstate)
+{
+ int i;
+ unsigned int val = thread_val[tstate->id];
+ for (i = 0; i < num_iters; i++)
+ _aor_i64 (&shared_val, val);
+}
+
+static void
+rao_test (void)
+{
+ if (shared_val != expected_val)
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/raoint-axor-2.c b/gcc/testsuite/gcc.target/i386/raoint-axor-2.c
new file mode 100644
index 0000000..a875592
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/raoint-axor-2.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { *-*-linux* && { ! ia32 } } } }*/
+/* { dg-require-effective-target raoint }*/
+/* { dg-options "-pthread -O2 -mraoint" }*/
+#include "rao-helper.h"
+
+const unsigned int num_iters= 1000001;
+unsigned int thread_val[4] = { 0x5a, 0x9600, 0x730000, 0xce000000 };
+static long long shared_val = 0;
+unsigned int expected_val = 0xce73965a;
+
+static void*
+threads_worker (state_t *tstate)
+{
+ int i;
+ unsigned int val = thread_val[tstate->id];
+ for (i = 0; i < num_iters; i++)
+ _axor_i64 (&shared_val, val);
+}
+
+static void
+rao_test (void)
+{
+ if (shared_val != expected_val)
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse-12.c b/gcc/testsuite/gcc.target/i386/sse-12.c
index 3eabc49..3210a5c 100644
--- a/gcc/testsuite/gcc.target/i386/sse-12.c
+++ b/gcc/testsuite/gcc.target/i386/sse-12.c
@@ -3,7 +3,7 @@
popcntintrin.h gfniintrin.h and mm_malloc.h are usable
with -O -std=c89 -pedantic-errors. */
/* { dg-do compile } */
-/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavxifma -mavxvnniint8 -mavxneconvert" } */
+/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint" } */
#include <x86intrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/sse-13.c b/gcc/testsuite/gcc.target/i386/sse-13.c
index b9cdfb6..66423ec 100644
--- a/gcc/testsuite/gcc.target/i386/sse-13.c
+++ b/gcc/testsuite/gcc.target/i386/sse-13.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert" } */
+/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint" } */
/* { dg-add-options bind_pic_locally } */
#include <mm_malloc.h>
@@ -125,7 +125,7 @@
#define __builtin_ia32_shufpd(A, B, N) __builtin_ia32_shufpd(A, B, 0)
/* xmmintrin.h */
-#define __builtin_prefetch(P, A, I) __builtin_prefetch(P, 0, _MM_HINT_NTA)
+#define __builtin_ia32_prefetch(A, B, C, D) __builtin_ia32_prefetch(A, 0, 3, 0)
#define __builtin_ia32_pshufw(A, N) __builtin_ia32_pshufw(A, 0)
#define __builtin_ia32_vec_set_v4hi(A, D, N) \
__builtin_ia32_vec_set_v4hi(A, D, 0)
@@ -842,4 +842,8 @@
#define __builtin_ia32_vpclmulqdq_v2di(A, B, C) __builtin_ia32_vpclmulqdq_v2di(A, B, 1)
#define __builtin_ia32_vpclmulqdq_v8di(A, B, C) __builtin_ia32_vpclmulqdq_v8di(A, B, 1)
+/* cmpccxadd.h */
+#define __builtin_ia32_cmpccxadd(A, B, C, D) __builtin_ia32_cmpccxadd(A, B, C, 1)
+#define __builtin_ia32_cmpccxadd64(A, B, C, D) __builtin_ia32_cmpccxadd64(A, B, C, 1)
+
#include <x86intrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/sse-14.c b/gcc/testsuite/gcc.target/i386/sse-14.c
index b6ee380..2953318 100644
--- a/gcc/testsuite/gcc.target/i386/sse-14.c
+++ b/gcc/testsuite/gcc.target/i386/sse-14.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert" } */
+/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mamx-fp16 -mraoint" } */
/* { dg-add-options bind_pic_locally } */
#include <mm_malloc.h>
diff --git a/gcc/testsuite/gcc.target/i386/sse-22.c b/gcc/testsuite/gcc.target/i386/sse-22.c
index 71ac0f3..f600bb5 100644
--- a/gcc/testsuite/gcc.target/i386/sse-22.c
+++ b/gcc/testsuite/gcc.target/i386/sse-22.c
@@ -103,7 +103,7 @@
#ifndef DIFFERENT_PRAGMAS
-#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert")
+#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint")
#endif
/* Following intrinsics require immediate arguments. They
@@ -220,7 +220,7 @@ test_4 (_mm_cmpestrz, int, __m128i, int, __m128i, int, 1)
/* immintrin.h (AVX/AVX2/RDRND/FSGSBASE/F16C/RTM/AVX512F/SHA) */
#ifdef DIFFERENT_PRAGMAS
-#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert")
+#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,amx-fp16,raoint")
#endif
#include <immintrin.h>
test_1 (_cvtss_sh, unsigned short, float, 1)
diff --git a/gcc/testsuite/gcc.target/i386/sse-23.c b/gcc/testsuite/gcc.target/i386/sse-23.c
index 898dde8..0f56e93 100644
--- a/gcc/testsuite/gcc.target/i386/sse-23.c
+++ b/gcc/testsuite/gcc.target/i386/sse-23.c
@@ -94,7 +94,7 @@
#define __builtin_ia32_shufpd(A, B, N) __builtin_ia32_shufpd(A, B, 0)
/* xmmintrin.h */
-#define __builtin_prefetch(P, A, I) __builtin_prefetch(P, 0, _MM_HINT_NTA)
+#define __builtin_ia32_prefetch(A, B, C, D) __builtin_ia32_prefetch(A, 0, 3, 0)
#define __builtin_ia32_pshufw(A, N) __builtin_ia32_pshufw(A, 0)
#define __builtin_ia32_vec_set_v4hi(A, D, N) \
__builtin_ia32_vec_set_v4hi(A, D, 0)
@@ -843,6 +843,10 @@
#define __builtin_ia32_vpclmulqdq_v2di(A, B, C) __builtin_ia32_vpclmulqdq_v2di(A, B, 1)
#define __builtin_ia32_vpclmulqdq_v8di(A, B, C) __builtin_ia32_vpclmulqdq_v8di(A, B, 1)
-#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert")
+/* cmpccxadd.h */
+#define __builtin_ia32_cmpccxadd(A, B, C, D) __builtin_ia32_cmpccxadd(A, B, C, 1)
+#define __builtin_ia32_cmpccxadd64(A, B, C, D) __builtin_ia32_cmpccxadd64(A, B, C, 1)
+
+#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,cmpccxadd,amx-fp16,prefetchi,raoint")
#include <x86intrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c
index 293be09..68da4db 100644
--- a/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c
+++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c
@@ -1,7 +1,7 @@
/* Test that <x86gprintrin.h> is usable with -O -std=c89 -pedantic-errors. */
/* { dg-do compile } */
-/* { dg-options "-O -std=c89 -pedantic-errors -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mhreset -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mno-sse -mno-mmx" } */
-/* { dg-additional-options "-muintr" { target { ! ia32 } } } */
+/* { dg-options "-O -std=c89 -pedantic-errors -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mhreset -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mraoint -mno-sse -mno-mmx" } */
+/* { dg-additional-options "-mcmpccxadd -mprefetchi -muintr" { target { ! ia32 } } } */
#include <x86gprintrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c
index c633027..737c2a2 100644
--- a/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c
+++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -Werror-implicit-function-declaration -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mhreset -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mno-sse -mno-mmx" } */
+/* { dg-options "-O2 -Werror-implicit-function-declaration -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mhreset -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mraoint -mno-sse -mno-mmx" } */
/* { dg-add-options bind_pic_locally } */
-/* { dg-additional-options "-muintr" { target { ! ia32 } } } */
+/* { dg-additional-options "-mcmpccxadd -mprefetchi -muintr" { target { ! ia32 } } } */
/* Test that the intrinsics in <x86gprintrin.h> compile with optimization.
All of them are defined as inline functions that reference the proper
@@ -28,4 +28,8 @@
/* rtmintrin.h */
#define __builtin_ia32_xabort(N) __builtin_ia32_xabort(1)
+/* cmpccxadd.h */
+#define __builtin_ia32_cmpccxadd(A, B, C, D) __builtin_ia32_cmpccxadd(A, B, C, 1)
+#define __builtin_ia32_cmpccxadd64(A, B, C, D) __builtin_ia32_cmpccxadd64(A, B, C, 1)
+
#include <x86gprintrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c
index 3a7e1f4..52690b1 100644
--- a/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c
+++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
-/* { dg-options "-O0 -Werror-implicit-function-declaration -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mhreset -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mno-sse -mno-mmx" } */
+/* { dg-options "-O0 -Werror-implicit-function-declaration -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mhreset -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mraoint -mno-sse -mno-mmx" } */
/* { dg-add-options bind_pic_locally } */
-/* { dg-additional-options "-muintr" { target { ! ia32 } } } */
+/* { dg-additional-options "-mcmpccxadd -mprefetchi -muintr" { target { ! ia32 } } } */
/* Test that the intrinsics in <x86gprintrin.h> compile without optimization.
All of them are defined as inline functions that reference the proper
diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c
index d8a6126..94cfc58 100644
--- a/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c
+++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c
@@ -15,9 +15,9 @@
#ifndef DIFFERENT_PRAGMAS
#ifdef __x86_64__
-#pragma GCC target ("adx,bmi,bmi2,fsgsbase,fxsr,hreset,lwp,lzcnt,popcnt,rdrnd,rdseed,tbm,rtm,serialize,tsxldtrk,uintr,xsaveopt")
+#pragma GCC target ("adx,bmi,bmi2,cmpccxadd,fsgsbase,fxsr,hreset,lwp,lzcnt,popcnt,prefetchi,raoint,rdrnd,rdseed,tbm,rtm,serialize,tsxldtrk,uintr,xsaveopt")
#else
-#pragma GCC target ("adx,bmi,bmi2,fsgsbase,fxsr,hreset,lwp,lzcnt,popcnt,rdrnd,rdseed,tbm,rtm,serialize,tsxldtrk,xsaveopt")
+#pragma GCC target ("adx,bmi,bmi2,fsgsbase,fxsr,hreset,lwp,lzcnt,popcnt,raoint,rdrnd,rdseed,tbm,rtm,serialize,tsxldtrk,xsaveopt")
#endif
#endif
diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c
index 9ef66fd..95f3e0a 100644
--- a/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c
+++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c
@@ -27,10 +27,14 @@
/* rtmintrin.h */
#define __builtin_ia32_xabort(M) __builtin_ia32_xabort(1)
+/* cmpccxadd.h */
+#define __builtin_ia32_cmpccxadd(A, B, C, D) __builtin_ia32_cmpccxadd(A, B, C, 1)
+#define __builtin_ia32_cmpccxadd64(A, B, C, D) __builtin_ia32_cmpccxadd64(A, B, C, 1)
+
#ifdef __x86_64__
-#pragma GCC target ("adx,bmi,bmi2,clflushopt,clwb,clzero,enqcmd,fsgsbase,fxsr,hreset,lwp,lzcnt,mwaitx,pconfig,pku,popcnt,rdpid,rdrnd,rdseed,tbm,rtm,serialize,sgx,tsxldtrk,uintr,xsavec,xsaveopt,xsaves,wbnoinvd")
+#pragma GCC target ("adx,bmi,bmi2,clflushopt,clwb,clzero,cmpccxadd,enqcmd,fsgsbase,fxsr,hreset,lwp,lzcnt,mwaitx,pconfig,pku,popcnt,prefetchi,raoint,rdpid,rdrnd,rdseed,tbm,rtm,serialize,sgx,tsxldtrk,uintr,xsavec,xsaveopt,xsaves,wbnoinvd")
#else
-#pragma GCC target ("adx,bmi,bmi2,clflushopt,clwb,clzero,enqcmd,fsgsbase,fxsr,hreset,lwp,lzcnt,mwaitx,pconfig,pku,popcnt,rdpid,rdrnd,rdseed,tbm,rtm,serialize,sgx,tsxldtrk,xsavec,xsaveopt,xsaves,wbnoinvd")
+#pragma GCC target ("adx,bmi,bmi2,clflushopt,clwb,clzero,enqcmd,fsgsbase,fxsr,hreset,lwp,lzcnt,mwaitx,pconfig,pku,popcnt,raoint,rdpid,rdrnd,rdseed,tbm,rtm,serialize,sgx,tsxldtrk,xsavec,xsaveopt,xsaves,wbnoinvd")
#endif
#include <x86gprintrin.h>
diff --git a/gcc/testsuite/gcc.target/loongarch/fcopysign.c b/gcc/testsuite/gcc.target/loongarch/fcopysign.c
new file mode 100644
index 0000000..058ba2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/fcopysign.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-mdouble-float" } */
+/* { dg-final { scan-assembler "fcopysign\\.s" } } */
+/* { dg-final { scan-assembler "fcopysign\\.d" } } */
+
+double
+my_copysign (double a, double b)
+{
+ return __builtin_copysign (a, b);
+}
+
+float
+my_copysignf (float a, float b)
+{
+ return __builtin_copysignf (a, b);
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/flogb.c b/gcc/testsuite/gcc.target/loongarch/flogb.c
new file mode 100644
index 0000000..1daefe5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/flogb.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-mdouble-float -fno-math-errno" } */
+/* { dg-final { scan-assembler "fabs\\.s" } } */
+/* { dg-final { scan-assembler "fabs\\.d" } } */
+/* { dg-final { scan-assembler "flogb\\.s" } } */
+/* { dg-final { scan-assembler "flogb\\.d" } } */
+
+double
+my_logb (double a)
+{
+ return __builtin_logb (a);
+}
+
+float
+my_logbf (float a)
+{
+ return __builtin_logbf (a);
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/frint.c b/gcc/testsuite/gcc.target/loongarch/frint.c
new file mode 100644
index 0000000..3ee6a8f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/frint.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-mdouble-float" } */
+/* { dg-final { scan-assembler "frint\\.s" } } */
+/* { dg-final { scan-assembler "frint\\.d" } } */
+
+double
+my_rint (double a)
+{
+ return __builtin_rint (a);
+}
+
+float
+my_rintf (float a)
+{
+ return __builtin_rintf (a);
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/fscaleb.c b/gcc/testsuite/gcc.target/loongarch/fscaleb.c
new file mode 100644
index 0000000..f18470f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/fscaleb.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mabi=lp64d -mdouble-float -fno-math-errno" } */
+/* { dg-final { scan-assembler-times "fscaleb\\.s" 3 } } */
+/* { dg-final { scan-assembler-times "fscaleb\\.d" 4 } } */
+/* { dg-final { scan-assembler-times "slli\\.w" 1 } } */
+
+double
+my_scalbln (double a, long b)
+{
+ return __builtin_scalbln (a, b);
+}
+
+double
+my_scalbn (double a, int b)
+{
+ return __builtin_scalbn (a, b);
+}
+
+double
+my_ldexp (double a, int b)
+{
+ return __builtin_ldexp (a, b);
+}
+
+float
+my_scalblnf (float a, long b)
+{
+ return __builtin_scalblnf (a, b);
+}
+
+float
+my_scalbnf (float a, int b)
+{
+ return __builtin_scalbnf (a, b);
+}
+
+float
+my_ldexpf (float a, int b)
+{
+ return __builtin_ldexpf (a, b);
+}
+
+/* b must be sign-extended */
+double
+my_ldexp_long (double a, long b)
+{
+ return __builtin_ldexp (a, b);
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/ftint-no-inexact.c b/gcc/testsuite/gcc.target/loongarch/ftint-no-inexact.c
new file mode 100644
index 0000000..88b83a9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/ftint-no-inexact.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64d -mdouble-float -fno-math-errno -fno-fp-int-builtin-inexact" } */
+/* { dg-final { scan-assembler "ftint\\.l\\.s" } } */
+/* { dg-final { scan-assembler "ftint\\.l\\.d" } } */
+/* { dg-final { scan-assembler-not "ftintrm\\.l\\.s" } } */
+/* { dg-final { scan-assembler-not "ftintrm\\.l\\.d" } } */
+/* { dg-final { scan-assembler-not "ftintrp\\.l\\.s" } } */
+/* { dg-final { scan-assembler-not "ftintrp\\.l\\.d" } } */
+
+long
+my_lrint (double a)
+{
+ return __builtin_lrint (a);
+}
+
+long
+my_lrintf (float a)
+{
+ return __builtin_lrintf (a);
+}
+
+long
+my_lfloor (double a)
+{
+ return __builtin_lfloor (a);
+}
+
+long
+my_lfloorf (float a)
+{
+ return __builtin_lfloorf (a);
+}
+
+long
+my_lceil (double a)
+{
+ return __builtin_lceil (a);
+}
+
+long
+my_lceilf (float a)
+{
+ return __builtin_lceilf (a);
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/ftint.c b/gcc/testsuite/gcc.target/loongarch/ftint.c
new file mode 100644
index 0000000..7a326a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/ftint.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64d -mdouble-float -fno-math-errno -ffp-int-builtin-inexact" } */
+/* { dg-final { scan-assembler "ftint\\.l\\.s" } } */
+/* { dg-final { scan-assembler "ftint\\.l\\.d" } } */
+/* { dg-final { scan-assembler "ftintrm\\.l\\.s" } } */
+/* { dg-final { scan-assembler "ftintrm\\.l\\.d" } } */
+/* { dg-final { scan-assembler "ftintrp\\.l\\.s" } } */
+/* { dg-final { scan-assembler "ftintrp\\.l\\.d" } } */
+
+long
+my_lrint (double a)
+{
+ return __builtin_lrint (a);
+}
+
+long
+my_lrintf (float a)
+{
+ return __builtin_lrintf (a);
+}
+
+long
+my_lfloor (double a)
+{
+ return __builtin_lfloor (a);
+}
+
+long
+my_lfloorf (float a)
+{
+ return __builtin_lfloorf (a);
+}
+
+long
+my_lceil (double a)
+{
+ return __builtin_lceil (a);
+}
+
+long
+my_lceilf (float a)
+{
+ return __builtin_lceilf (a);
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/imm-load.c b/gcc/testsuite/gcc.target/loongarch/imm-load.c
new file mode 100644
index 0000000..c04ca33
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/imm-load.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64d -O2 -fdump-rtl-split1" } */
+
+long int
+test (void)
+{
+ return 0x1234567890abcdef;
+}
+/* { dg-final { scan-rtl-dump-times "scanning new insn with uid" 6 "split1" } } */
+
diff --git a/gcc/testsuite/gcc.target/loongarch/imm-load1.c b/gcc/testsuite/gcc.target/loongarch/imm-load1.c
new file mode 100644
index 0000000..2ff0297
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/imm-load1.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64d -O2" } */
+/* { dg-final { scan-assembler "test:.*lu52i\.d.*\n\taddi\.w.*\n\.L2:" } } */
+
+
+extern long long b[10];
+static inline long long
+repeat_bytes (void)
+{
+ long long r = 0x0101010101010101;
+
+ return r;
+}
+
+static inline long long
+highbit_mask (long long m)
+{
+ return m & repeat_bytes ();
+}
+
+void test(long long *a)
+{
+ for (int i = 0; i < 10; i++)
+ b[i] = highbit_mask (a[i]);
+
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/pr107713-1.c b/gcc/testsuite/gcc.target/loongarch/pr107713-1.c
new file mode 100644
index 0000000..d1536c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/pr107713-1.c
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+/* { dg-require-effective-target pthread } */
+/* { dg-options "-pthread" } */
+
+#include <pthread.h>
+
+char x, x1, x2;
+
+void *
+work1 (void *)
+{
+ for (int i = 0; i < 100; i++)
+ x1 = __atomic_exchange_n (&x, x1, __ATOMIC_SEQ_CST);
+ return NULL;
+}
+
+void *
+work2 (void *)
+{
+ for (int i = 0; i < 100; i++)
+ x2 = __atomic_exchange_n (&x, x2, __ATOMIC_SEQ_CST);
+ return NULL;
+}
+
+void
+test (void)
+{
+ x = 0;
+ x1 = 1;
+ x2 = 2;
+ pthread_t w1, w2;
+ if (pthread_create (&w1, NULL, work1, NULL) != 0)
+ __builtin_abort ();
+ if (pthread_create (&w2, NULL, work2, NULL) != 0)
+ __builtin_abort ();
+ if (pthread_join (w1, NULL) != 0)
+ __builtin_abort ();
+ if (pthread_join (w2, NULL) != 0)
+ __builtin_abort ();
+ if ((x ^ x1 ^ x2) != 3)
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 10000; i++)
+ test ();
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/pr107713-2.c b/gcc/testsuite/gcc.target/loongarch/pr107713-2.c
new file mode 100644
index 0000000..82d44db
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/pr107713-2.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-times "beq|bne" 1 } } */
+
+char
+t (char *p, char x)
+{
+ return __atomic_exchange_n (p, x, __ATOMIC_RELAXED);
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-1.c b/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-1.c
new file mode 100644
index 0000000..6ee589c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-1.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+/* { dg-require-effective-target alloca } */
+/* { dg-skip-if "" { *-*-* } { "-fstack-check" } { "" } } */
+
+#define SIZE y
+#include "stack-check-alloca.h"
+
+/* { dg-final { scan-assembler-times {stp*t*r*\.d\t\$r0,\$r\d{1,2},-8} 1 } } */
+/* { dg-final { scan-assembler-times {stx\.d\t\$r0,\$r3,\$r12} 1 } } */
+
+/* Dynamic alloca, expect loop, and 1 probes with top at sp.
+ 1st probe is inside the loop for the full guard-size allocations, second
+ probe is for the case where residual is zero. */
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-2.c b/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-2.c
new file mode 100644
index 0000000..8deaa58
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+/* { dg-require-effective-target alloca } */
+/* { dg-skip-if "" { *-*-* } { "-fstack-check" } { "" } } */
+
+#define SIZE 0
+#include "stack-check-alloca.h"
+
+/* { dg-final { scan-assembler-not {stp*t*r*\.d\t\$r0,\$r3,4088} } } */
+
+/* Alloca of 0 should emit no probes, boundary condition. */
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-3.c b/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-3.c
new file mode 100644
index 0000000..e326ba9a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-3.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+/* { dg-require-effective-target alloca } */
+/* { dg-skip-if "" { *-*-* } { "-fstack-check" } { "" } } */
+
+#define SIZE 100
+#include "stack-check-alloca.h"
+
+/* { dg-final { scan-assembler-times {st\.d\t\$r0,\$r3,104} 1 } } */
+
+/* Alloca is less than guard-size, 1 probe at the top of the new allocation. */
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-4.c b/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-4.c
new file mode 100644
index 0000000..b9f7572
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-4.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+/* { dg-require-effective-target alloca } */
+/* { dg-skip-if "" { *-*-* } { "-fstack-check" } { "" } } */
+
+#define SIZE 64 * 1024
+#include "stack-check-alloca.h"
+
+/* { dg-final { scan-assembler-times {stp*t*r*\.d\t\$r0,\$r\d{1,2},-8} 1 } } */
+
+/* Alloca is exactly one guard-size, 1 probe expected at top. */
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-5.c b/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-5.c
new file mode 100644
index 0000000..0ff6e49
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-5.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+/* { dg-require-effective-target alloca } */
+/* { dg-skip-if "" { *-*-* } { "-fstack-check" } { "" } } */
+
+#define SIZE 65 * 1024
+#include "stack-check-alloca.h"
+
+/* { dg-final { scan-assembler-times {stp*t*r*\.d\t\$r0,\$r\d{1,2},-8} 1 } } */
+/* { dg-final { scan-assembler-times {stp*t*r*\.d\t\$r0,\$r3,1016} 1 } } */
+
+/* Alloca is more than one guard-page. 2 probes expected. */
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-6.c b/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-6.c
new file mode 100644
index 0000000..c5cf74f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-alloca-6.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+/* { dg-require-effective-target alloca } */
+/* { dg-skip-if "" { *-*-* } { "-fstack-check" } { "" } } */
+
+#define SIZE 127 * 64 * 1024
+#include "stack-check-alloca.h"
+
+/* { dg-final { scan-assembler-times {stp*t*r*\.d\t\$r0,\$r\d{1,2},-8} 1 } } */
+
+/* Large alloca of a constant amount which is a multiple of a guard-size.
+ Loop expected with top probe. */
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-alloca.h b/gcc/testsuite/gcc.target/loongarch/stack-check-alloca.h
new file mode 100644
index 0000000..8c75f6c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-alloca.h
@@ -0,0 +1,15 @@
+
+/* Avoid inclusion of alloca.h, unavailable on some systems. */
+#define alloca __builtin_alloca
+
+__attribute__((noinline, noipa))
+void g (char* ptr, int y)
+{
+ ptr[y] = '\0';
+}
+
+void f_caller (int y)
+{
+ char* pStr = alloca(SIZE);
+ g (pStr, y);
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-cfa-1.c b/gcc/testsuite/gcc.target/loongarch/stack-check-cfa-1.c
new file mode 100644
index 0000000..f0c6877
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-cfa-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -funwind-tables" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+/* { dg-skip-if "" { *-*-* } { "-fstack-check" } { "" } } */
+
+#define SIZE 128*1024
+#include "stack-check-prologue.h"
+
+/* { dg-final { scan-assembler-times {\.cfi_def_cfa_offset 131088} 1 } } */
+/* { dg-final { scan-assembler-times {\.cfi_def_cfa_offset 0} 1 } } */
+
+/* Checks that the CFA notes are correct for every sp adjustment. */
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-cfa-2.c b/gcc/testsuite/gcc.target/loongarch/stack-check-cfa-2.c
new file mode 100644
index 0000000..c6e07bc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-cfa-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -funwind-tables" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+/* { dg-skip-if "" { *-*-* } { "-fstack-check" } { "" } } */
+
+#define SIZE 1280*1024 + 512
+#include "stack-check-prologue.h"
+
+/* { dg-final { scan-assembler-times {\.cfi_def_cfa_offset 1311248} 1 } } */
+/* { dg-final { scan-assembler-times {\.cfi_def_cfa_offset 0} 1 } } */
+
+/* Checks that the CFA notes are correct for every sp adjustment. */
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-1.c b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-1.c
new file mode 100644
index 0000000..351bc1f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+/* { dg-skip-if "" { *-*-* } { "-fstack-check" } { "" } } */
+
+#define SIZE 128
+#include "stack-check-prologue.h"
+
+/* { dg-final { scan-assembler-times {stp*t*r*\.d\t\$r0,\$r3,0} 0 } } */
+
+/* SIZE is smaller than guard-size so no probe expected. */
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-2.c b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-2.c
new file mode 100644
index 0000000..6bba659
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+/* { dg-skip-if "" { *-*-* } { "-fstack-check" } { "" } } */
+
+#define SIZE 63 * 1024
+#include "stack-check-prologue.h"
+
+/* { dg-final { scan-assembler-times {stp*t*r*.d\t\$r0,\$r3,0} 0 } } */
+
+/* SIZE is smaller than guard-size so no probe expected. */
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-3.c b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-3.c
new file mode 100644
index 0000000..164956c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+/* { dg-skip-if "" { *-*-* } { "-fstack-check" } { "" } } */
+
+#define SIZE 64 * 1024
+#include "stack-check-prologue.h"
+
+/* { dg-final { scan-assembler-times {stp*t*r*\.d\t\$r0,\$r3,0} 1 } } */
+
+/* SIZE is equal to guard-size, 1 probe expected, boundary condition. */
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-4.c b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-4.c
new file mode 100644
index 0000000..f53da6b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-4.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+/* { dg-skip-if "" { *-*-* } { "-fstack-check" } { "" } } */
+
+#define SIZE 65 * 1024
+#include "stack-check-prologue.h"
+
+/* { dg-final { scan-assembler-times {stp*t*r*\.d\t\$r0,\$r3,0} 1 } } */
+
+/* SIZE is more than guard-size 1 probe expected. */
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-5.c b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-5.c
new file mode 100644
index 0000000..c092317
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-5.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+/* { dg-skip-if "" { *-*-* } { "-fstack-check" } { "" } } */
+
+#define SIZE 127 * 1024
+#include "stack-check-prologue.h"
+
+/* { dg-final { scan-assembler-times {stp*t*r*\.d\t\$r0,\$r3,0} 1 } } */
+
+/* SIZE is more than 1x guard-size and remainder small than guard-size,
+ 1 probe expected, unrolled, no loop. */
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-6.c b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-6.c
new file mode 100644
index 0000000..70a2f53
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-6.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+/* { dg-skip-if "" { *-*-* } { "-fstack-check" } { "" } } */
+
+#define SIZE 128 * 1024
+#include "stack-check-prologue.h"
+
+/* { dg-final { scan-assembler-times {stp*t*r*\.d\t\$r0,\$r3,0} 2 } } */
+
+/* SIZE is more than 2x guard-size and no remainder, unrolled, no loop. */
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-7.c b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-7.c
new file mode 100644
index 0000000..e2df89a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue-7.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+/* { dg-skip-if "" { *-*-* } { "-fstack-check" } { "" } } */
+
+#define SIZE 6 * 64 * 1024
+#include "stack-check-prologue.h"
+
+/* { dg-final { scan-assembler-times {stp*t*r*.d\t\$r0,\$r3,0} 1 } } */
+
+/* SIZE is more than 4x guard-size and no remainder, 1 probe expected in a loop
+ and no residual probe. */
diff --git a/gcc/testsuite/gcc.target/loongarch/stack-check-prologue.h b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue.h
new file mode 100644
index 0000000..b7e06ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/stack-check-prologue.h
@@ -0,0 +1,5 @@
+int f_test (int x)
+{
+ char arr[SIZE];
+ return arr[x];
+}
diff --git a/gcc/testsuite/gcc.target/mips/pr106462.c b/gcc/testsuite/gcc.target/mips/pr106462.c
new file mode 100644
index 0000000..c910540
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr106462.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=64 -msingle-float" } */
+
+extern void bar (float x, short y);
+
+void foo (int argc)
+{
+ short c = argc * 2;
+ float a = (float)(short)c, b = 9.5;
+
+ bar (b/a, c);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/cbranchcc4-1.c b/gcc/testsuite/gcc.target/powerpc/cbranchcc4-1.c
new file mode 100644
index 0000000..6c2cd13
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cbranchcc4-1.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+/* Verify there is no ICE with cbranchcc4 enabled. */
+
+int foo (double d)
+{
+ if (d == 0.0)
+ return 0;
+
+ d = ((d) >= 0 ? (d) : -(d));
+
+ if (d < 1.0)
+ return 1;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/cbranchcc4-2.c b/gcc/testsuite/gcc.target/powerpc/cbranchcc4-2.c
new file mode 100644
index 0000000..528ba1a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/cbranchcc4-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-rtl-ce1" } */
+/* { dg-final { scan-rtl-dump "noce_try_store_flag_constants" "ce1" } } */
+
+/* The inner branch should be detected by ifcvt then be converted to a setcc
+ with a plus by noce_try_store_flag_constants. */
+
+int test (unsigned int a, unsigned int b)
+{
+ return (a < b ? 0 : (a > b ? 2 : 1));
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-vec-length-epil-8.c b/gcc/testsuite/gcc.target/powerpc/p9-vec-length-epil-8.c
index 961df0d..8b9c910 100644
--- a/gcc/testsuite/gcc.target/powerpc/p9-vec-length-epil-8.c
+++ b/gcc/testsuite/gcc.target/powerpc/p9-vec-length-epil-8.c
@@ -8,5 +8,5 @@
#include "p9-vec-length-8.h"
-/* { dg-final { scan-assembler-times {\mlxvl\M} 21 } } */
+/* { dg-final { scan-assembler-times {\mlxvl\M} 16 } } */
/* { dg-final { scan-assembler-times {\mstxvl\M} 7 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr100866-1.c b/gcc/testsuite/gcc.target/powerpc/pr100866-1.c
new file mode 100644
index 0000000..63872f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr100866-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power8" } */
+/* { dg-final { scan-assembler-not {\mxxlnor\M} } } */
+
+#include <altivec.h>
+
+vector unsigned int revb (vector unsigned int a)
+{
+ return vec_revb(a);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr100866-2.c b/gcc/testsuite/gcc.target/powerpc/pr100866-2.c
new file mode 100644
index 0000000..4357d1b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr100866-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power8" } */
+/* { dg-final { scan-assembler {\mvspltish\M} } } */
+/* { dg-final { scan-assembler {\mvrlh\M} } } */
+
+#include <altivec.h>
+
+vector unsigned short revb(vector unsigned short a)
+{
+ return vec_revb(a);
+}
+
diff --git a/gcc/testsuite/gcc.target/powerpc/pr105586.c b/gcc/testsuite/gcc.target/powerpc/pr105586.c
index bd397f5..3f88a09 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr105586.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr105586.c
@@ -1,4 +1,5 @@
/* { dg-options "-mdejagnu-tune=power4 -O2 -fcompare-debug -fno-if-conversion -fno-guess-branch-probability" } */
+/* { dg-require-effective-target int128 } */
extern int bar(int i);
diff --git a/gcc/testsuite/gcc.target/powerpc/pr107412.c b/gcc/testsuite/gcc.target/powerpc/pr107412.c
new file mode 100644
index 0000000..4526ea8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr107412.c
@@ -0,0 +1,19 @@
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-mdejagnu-cpu=power9 -O2 -ftree-vectorize -fno-vect-cost-model -funroll-loops -fno-tree-loop-distribute-patterns --param vect-partial-vector-usage=2 -fdump-tree-optimized" } */
+
+/* Verify there is only one IFN call LEN_LOAD and IFN_STORE separately. */
+
+#define N 16
+int src[N];
+int dest[N];
+
+void
+foo ()
+{
+ for (int i = 0; i < (N - 1); i++)
+ dest[i] = src[i];
+}
+
+/* { dg-final { scan-tree-dump-times {\mLEN_LOAD\M} 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times {\mLEN_STORE\M} 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/branch-1.c b/gcc/testsuite/gcc.target/riscv/branch-1.c
new file mode 100644
index 0000000..b4a3a94
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/branch-1.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" } } */
+
+void g();
+
+void f(long long a)
+{
+ if (a & 0xff00)
+ g();
+}
+
+void f2(long long a)
+{
+ if (a & (-4ull << 3))
+ g();
+}
+
+void f3(long long a)
+{
+ if (a & 0xffff00)
+ g();
+}
+
+void f4(long long a)
+{
+ if (a & 0x7ff800)
+ g();
+}
+
+/* { dg-final { scan-assembler-times "slli\t" 2 } } */
+/* { dg-final { scan-assembler-times "srli\t" 3 } } */
+/* { dg-final { scan-assembler-times "andi\t" 1 } } */
+/* { dg-final { scan-assembler-times "\tli\t" 1 } } */
+/* { dg-final { scan-assembler-not "addi\t" } } */
+/* { dg-final { scan-assembler-not "and\t" } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/builtin_pause.c b/gcc/testsuite/gcc.target/riscv/builtin_pause.c
new file mode 100644
index 0000000..9250937
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/builtin_pause.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void test_pause()
+{
+ __builtin_riscv_pause ();
+}
+
+/* { dg-final { scan-assembler "pause" } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/pr107786-2.c b/gcc/testsuite/gcc.target/riscv/pr107786-2.c
new file mode 100644
index 0000000..ee316a6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr107786-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" } } */
+
+int c;
+
+int main() {
+ for (;;) {
+ short h = c * 100;
+ if (h & 0x7ff0)
+ break;
+ }
+}
+
+/* { dg-final { scan-assembler-times "andi\t" 1 } } */
+/* { dg-final { scan-assembler-times "srli\t" 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/pr107786.c b/gcc/testsuite/gcc.target/riscv/pr107786.c
new file mode 100644
index 0000000..5246ec7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr107786.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" } } */
+
+int c;
+
+int main() {
+ for (;;) {
+ char h = c * 100;
+ if (h)
+ break;
+ }
+}
+
+/* { dg-final { scan-assembler-times "andi\t" 1 } } */
+/* { dg-final { scan-assembler-not "srli\t" } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/pr93304.c b/gcc/testsuite/gcc.target/riscv/pr93304.c
index ce2dc4d..76975ff 100644
--- a/gcc/testsuite/gcc.target/riscv/pr93304.c
+++ b/gcc/testsuite/gcc.target/riscv/pr93304.c
@@ -16,4 +16,4 @@ foo (void)
regradless of the REG_ALLOC_ORDER.
In theory, t2 should not used in such small program if regrename
not executed incorrectly, because t0-a2 should be enough. */
-/* { dg-final { scan-assembler-not "t2" } } */
+/* { dg-final { scan-assembler-not {\t[a-zA-Z0-9]+\t.*t2} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c b/gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c
new file mode 100644
index 0000000..954e1dd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32im -mabi=ilp32" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+
+/* This test only applies to RV32. Some of 64bit constants in this test will be put
+into the constant pool in RV64, since RV64 might need one extra instruction to load
+64bit constant. */
+
+unsigned long long
+rv32_mov_64bit_int1 (void)
+{
+ return 0x739290001LL;
+}
+
+unsigned long long
+rv32_mov_64bit_int2 (void)
+{
+ return 0x839290001LL;
+}
+
+unsigned long long
+rv32_mov_64bit_int3 (void)
+{
+ return 0x3929000139290000LL;
+}
+
+unsigned long long
+rv32_mov_64bit_int4 (void)
+{
+ return 0x3929001139290000LL;
+}
+
+unsigned long long
+rv32_mov_64bit_int5 (void)
+{
+ return 0x14736def39290000LL;
+}
+
+/* { dg-final { scan-assembler-not "lw\t" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/dup-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/dup-1.c
new file mode 100644
index 0000000..2a83afa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/dup-1.c
@@ -0,0 +1,521 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -O3 -fgimple" } */
+
+#include "riscv_vector.h"
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f1 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint8mf8_t> ((vint8mf8_t *)out_2(D)) = _Literal (vint8mf8_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f2 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint8mf4_t> ((vint8mf4_t *)out_2(D)) = _Literal (vint8mf4_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f3 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint8mf2_t> ((vint8mf2_t *)out_2(D)) = _Literal (vint8mf2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f4 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint8m1_t> ((vint8m1_t *)out_2(D)) = _Literal (vint8m1_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f5 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint8m2_t> ((vint8m2_t *)out_2(D)) = _Literal (vint8m2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f6 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint8m4_t> ((vint8m4_t *)out_2(D)) = _Literal (vint8m4_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f7 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint8m8_t> ((vint8m8_t *)out_2(D)) = _Literal (vint8m8_t) 0;
+ return;
+
+}
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f8 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint8mf8_t> ((vuint8mf8_t *)out_2(D)) = _Literal (vuint8mf8_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f9 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint8mf4_t> ((vuint8mf4_t *)out_2(D)) = _Literal (vuint8mf4_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f10 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint8mf2_t> ((vuint8mf2_t *)out_2(D)) = _Literal (vuint8mf2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f11 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint8m1_t> ((vuint8m1_t *)out_2(D)) = _Literal (vuint8m1_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f12 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint8m2_t> ((vuint8m2_t *)out_2(D)) = _Literal (vuint8m2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f13 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint8m4_t> ((vuint8m4_t *)out_2(D)) = _Literal (vuint8m4_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f14 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint8m8_t> ((vuint8m8_t *)out_2(D)) = _Literal (vuint8m8_t) 0;
+ return;
+
+}
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f15 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint16mf4_t> ((vint16mf4_t *)out_2(D)) = _Literal (vint16mf4_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f16 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint16mf2_t> ((vint16mf2_t *)out_2(D)) = _Literal (vint16mf2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f17 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint16m1_t> ((vint16m1_t *)out_2(D)) = _Literal (vint16m1_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f18 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint16m2_t> ((vint16m2_t *)out_2(D)) = _Literal (vint16m2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f19 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint16m4_t> ((vint16m4_t *)out_2(D)) = _Literal (vint16m4_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f20 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint16m8_t> ((vint16m8_t *)out_2(D)) = _Literal (vint16m8_t) 0;
+ return;
+
+}
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f21 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint16mf4_t> ((vuint16mf4_t *)out_2(D)) = _Literal (vuint16mf4_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f22 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint16mf2_t> ((vuint16mf2_t *)out_2(D)) = _Literal (vuint16mf2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f23 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint16m1_t> ((vuint16m1_t *)out_2(D)) = _Literal (vuint16m1_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f24 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint16m2_t> ((vuint16m2_t *)out_2(D)) = _Literal (vuint16m2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f25 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint16m4_t> ((vuint16m4_t *)out_2(D)) = _Literal (vuint16m4_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f26 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint16m8_t> ((vuint16m8_t *)out_2(D)) = _Literal (vuint16m8_t) 0;
+ return;
+
+}
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f27 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint32mf2_t> ((vint32mf2_t *)out_2(D)) = _Literal (vint32mf2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f28 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint32m1_t> ((vint32m1_t *)out_2(D)) = _Literal (vint32m1_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f29 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint32m2_t> ((vint32m2_t *)out_2(D)) = _Literal (vint32m2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f30 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint32m4_t> ((vint32m4_t *)out_2(D)) = _Literal (vint32m4_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f31 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint32m8_t> ((vint32m8_t *)out_2(D)) = _Literal (vint32m8_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f32 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint32mf2_t> ((vuint32mf2_t *)out_2(D)) = _Literal (vuint32mf2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f33 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint32m1_t> ((vuint32m1_t *)out_2(D)) = _Literal (vuint32m1_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f34 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint32m2_t> ((vuint32m2_t *)out_2(D)) = _Literal (vuint32m2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f35 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint32m4_t> ((vuint32m4_t *)out_2(D)) = _Literal (vuint32m4_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f36 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint32m8_t> ((vuint32m8_t *)out_2(D)) = _Literal (vuint32m8_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f37 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint64m1_t> ((vint64m1_t *)out_2(D)) = _Literal (vint64m1_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f38 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint64m2_t> ((vint64m2_t *)out_2(D)) = _Literal (vint64m2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f39 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint64m4_t> ((vint64m4_t *)out_2(D)) = _Literal (vint64m4_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f40 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vint64m8_t> ((vint64m8_t *)out_2(D)) = _Literal (vint64m8_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f41 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint64m1_t> ((vuint64m1_t *)out_2(D)) = _Literal (vuint64m1_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f42 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint64m2_t> ((vuint64m2_t *)out_2(D)) = _Literal (vuint64m2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f43 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint64m4_t> ((vuint64m4_t *)out_2(D)) = _Literal (vuint64m4_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f44 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vuint64m8_t> ((vuint64m8_t *)out_2(D)) = _Literal (vuint64m8_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f45 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vfloat32m1_t> ((vfloat32m1_t *)out_2(D)) = _Literal (vfloat32m1_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f46 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vfloat32m2_t> ((vfloat32m2_t *)out_2(D)) = _Literal (vfloat32m2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f47 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vfloat32m4_t> ((vfloat32m4_t *)out_2(D)) = _Literal (vfloat32m4_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f48 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vfloat32m8_t> ((vfloat32m8_t *)out_2(D)) = _Literal (vfloat32m8_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f49 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vfloat64m1_t> ((vfloat64m1_t *)out_2(D)) = _Literal (vfloat64m1_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f50 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vfloat64m2_t> ((vfloat64m2_t *)out_2(D)) = _Literal (vfloat64m2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f51 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vfloat64m4_t> ((vfloat64m4_t *)out_2(D)) = _Literal (vfloat64m4_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f52 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vfloat64m8_t> ((vfloat64m8_t *)out_2(D)) = _Literal (vfloat64m8_t) 0;
+ return;
+
+}
+
+/* { dg-final { scan-assembler-times {vmv\.v\.i\s+(?:v[0-9]|v[1-2][0-9]|v3[0-1]),\s*0} 52 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/dup-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/dup-2.c
new file mode 100644
index 0000000..c690303
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/dup-2.c
@@ -0,0 +1,75 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -O3 -fgimple" } */
+
+#include "riscv_vector.h"
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f1 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vbool1_t> ((vbool1_t *)out_2(D)) = _Literal (vbool1_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f2 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vbool2_t> ((vbool2_t *)out_2(D)) = _Literal (vbool2_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f3 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vbool4_t> ((vbool4_t *)out_2(D)) = _Literal (vbool4_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f4 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vbool8_t> ((vbool8_t *)out_2(D)) = _Literal (vbool8_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f5 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vbool16_t> ((vbool16_t *)out_2(D)) = _Literal (vbool16_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f6 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vbool32_t> ((vbool32_t *)out_2(D)) = _Literal (vbool32_t) 0;
+ return;
+
+}
+
+
+void __GIMPLE (ssa,guessed_local(1073741824))
+f7 (void * out)
+{
+ __BB(2,guessed_local(1073741824)):
+ __MEM <vbool64_t> ((vbool64_t *)out_2(D)) = _Literal (vbool64_t) 0;
+ return;
+
+}
+
+/* { dg-final { scan-assembler-times {vmclr\.m\s+(?:v[0-9]|v[1-2][0-9]|v3[0-1])} 7 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/macro.h b/gcc/testsuite/gcc.target/riscv/rvv/base/macro.h
new file mode 100644
index 0000000..a032ac3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/macro.h
@@ -0,0 +1,6 @@
+#define exhaust_vector_regs() \
+ asm volatile("#" :: \
+ : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \
+ "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", \
+ "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", \
+ "v26", "v27", "v28", "v29", "v30", "v31");
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-1.c
new file mode 100644
index 0000000..b1220c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-1.c
@@ -0,0 +1,385 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -mpreferred-stack-boundary=3 -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "riscv_vector.h"
+#include "macro.h"
+
+/*
+** spill_1:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** ...
+** csrr\ta2,vlenb
+** srli\ta2,a2,3
+** slli\ta3,a2,3
+** sub\ta3,a3,a2
+** add\ta3,a3,sp
+** vse8.v\tv24,0\(a3\)
+** ...
+** csrr\ta2,vlenb
+** srli\ta2,a2,3
+** slli\ta3,a2,3
+** sub\ta3,a3,a2
+** add\ta3,a3,sp
+** vle8.v\tv24,0\(a3\)
+** vse8.v\tv24,0\(a1\)
+** csrr\tt0,vlenb
+** add\tsp,sp,t0
+** ...
+** jr\tra
+*/
+void
+spill_1 (int8_t *in, int8_t *out)
+{
+ vint8mf8_t v1 = *(vint8mf8_t*)in;
+ exhaust_vector_regs ();
+ *(vint8mf8_t*)out = v1;
+}
+
+/*
+** spill_2:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** vsetvli\ta5,zero,e8,mf4,ta,ma
+** vle8.v\tv24,0\(a0\)
+** csrr\ta2,vlenb
+** srli\ta2,a2,2
+** slli\ta3,a2,2
+** sub\ta3,a3,a2
+** add\ta3,a3,sp
+** vse8.v\tv24,0\(a3\)
+** ...
+** csrr\ta2,vlenb
+** srli\ta2,a2,2
+** slli\ta3,a2,2
+** sub\ta3,a3,a2
+** add\ta3,a3,sp
+** vle8.v\tv24,0\(a3\)
+** vse8.v\tv24,0\(a1\)
+** csrr\tt0,vlenb
+** add\tsp,sp,t0
+** ...
+** jr\tra
+*/
+void
+spill_2 (int8_t *in, int8_t *out)
+{
+ vint8mf4_t v1 = *(vint8mf4_t*)in;
+ exhaust_vector_regs ();
+ *(vint8mf4_t*)out = v1;
+}
+
+/*
+** spill_3:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** vsetvli\ta5,zero,e8,mf2,ta,ma
+** vle8.v\tv24,0\(a0\)
+** csrr\ta3,vlenb
+** srli\ta3,a3,1
+** add\ta3,a3,sp
+** vse8.v\tv24,0\(a3\)
+** ...
+** csrr\ta3,vlenb
+** srli\ta3,a3,1
+** add\ta3,a3,sp
+** vle8.v\tv24,0\(a3\)
+** vse8.v\tv24,0\(a1\)
+** csrr\tt0,vlenb
+** add\tsp,sp,t0
+** ...
+** jr\tra
+*/
+void
+spill_3 (int8_t *in, int8_t *out)
+{
+ vint8mf2_t v1 = *(vint8mf2_t*)in;
+ exhaust_vector_regs ();
+ *(vint8mf2_t*)out = v1;
+}
+
+/*
+** spill_4:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** ...
+** vs1r.v\tv24,0\(sp\)
+** ...
+** vl1re8.v\tv2,0\(sp\)
+** vs1r.v\tv2,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_4 (int8_t *in, int8_t *out)
+{
+ register vint8m1_t v1 asm("v1") = *(vint8m1_t*)in;
+ asm volatile ("# %0"::"vr"(v1));
+ exhaust_vector_regs ();
+ register vint8m1_t v2 asm("v2") = v1;
+ *(vint8m1_t*)out = v2;
+ asm volatile ("# %0"::"vr"(v2));
+}
+
+/*
+** spill_5:
+** csrr\tt0,vlenb
+** slli\tt1,t0,1
+** sub\tsp,sp,t1
+** ...
+** vs2r.v\tv24,0\(sp\)
+** ...
+** vl2re8.v\tv4,0\(sp\)
+** vs2r.v\tv4,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_5 (int8_t *in, int8_t *out)
+{
+ register vint8m2_t v2 asm("v2") = *(vint8m2_t*)in;
+ asm volatile ("# %0"::"vr"(v2));
+ exhaust_vector_regs ();
+ register vint8m2_t v4 asm("v4") = v2;
+ *(vint8m2_t*)out = v4;
+ asm volatile ("# %0"::"vr"(v4));
+}
+
+/*
+** spill_6:
+** csrr\tt0,vlenb
+** slli\tt1,t0,2
+** sub\tsp,sp,t1
+** ...
+** vs4r.v\tv24,0\(sp\)
+** ...
+** vl4re8.v\tv8,0\(sp\)
+** vs4r.v\tv8,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_6 (int8_t *in, int8_t *out)
+{
+ register vint8m4_t v4 asm("v4") = *(vint8m4_t*)in;
+ asm volatile ("# %0"::"vr"(v4));
+ exhaust_vector_regs ();
+ register vint8m4_t v8 asm("v8") = v4;
+ *(vint8m4_t*)out = v8;
+ asm volatile ("# %0"::"vr"(v8));
+}
+
+/*
+** spill_7:
+** csrr\tt0,vlenb
+** slli\tt1,t0,3
+** sub\tsp,sp,t1
+** ...
+** vs8r.v\tv24,0\(sp\)
+** ...
+** vl8re8.v\tv16,0\(sp\)
+** vs8r.v\tv16,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_7 (int8_t *in, int8_t *out)
+{
+ register vint8m8_t v8 asm("v8") = *(vint8m8_t*)in;
+ asm volatile ("# %0"::"vr"(v8));
+ exhaust_vector_regs ();
+ register vint8m8_t v16 asm("v16") = v8;
+ *(vint8m8_t*)out = v16;
+ asm volatile ("# %0"::"vr"(v16));
+}
+
+/*
+** spill_8:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** vsetvli\ta5,zero,e8,mf8,ta,ma
+** vle8.v\tv24,0\(a0\)
+** csrr\ta2,vlenb
+** srli\ta2,a2,3
+** slli\ta3,a2,3
+** sub\ta3,a3,a2
+** add\ta3,a3,sp
+** vse8.v\tv24,0\(a3\)
+** ...
+** csrr\ta2,vlenb
+** srli\ta2,a2,3
+** slli\ta3,a2,3
+** sub\ta3,a3,a2
+** add\ta3,a3,sp
+** vle8.v\tv24,0\(a3\)
+** vse8.v\tv24,0\(a1\)
+** csrr\tt0,vlenb
+** add\tsp,sp,t0
+** ...
+** jr\tra
+*/
+void
+spill_8 (uint8_t *in, uint8_t *out)
+{
+ vuint8mf8_t v1 = *(vuint8mf8_t*)in;
+ exhaust_vector_regs ();
+ *(vuint8mf8_t*)out = v1;
+}
+
+/*
+** spill_9:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** vsetvli\ta5,zero,e8,mf4,ta,ma
+** vle8.v\tv24,0\(a0\)
+** csrr\ta2,vlenb
+** srli\ta2,a2,2
+** slli\ta3,a2,2
+** sub\ta3,a3,a2
+** add\ta3,a3,sp
+** vse8.v\tv24,0\(a3\)
+** ...
+** csrr\ta2,vlenb
+** srli\ta2,a2,2
+** slli\ta3,a2,2
+** sub\ta3,a3,a2
+** add\ta3,a3,sp
+** vle8.v\tv24,0\(a3\)
+** vse8.v\tv24,0\(a1\)
+** csrr\tt0,vlenb
+** add\tsp,sp,t0
+** ...
+** jr\tra
+*/
+void
+spill_9 (uint8_t *in, uint8_t *out)
+{
+ vuint8mf4_t v1 = *(vuint8mf4_t*)in;
+ exhaust_vector_regs ();
+ *(vuint8mf4_t*)out = v1;
+}
+
+/*
+** spill_10:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** vsetvli\ta5,zero,e8,mf2,ta,ma
+** vle8.v\tv24,0\(a0\)
+** csrr\ta3,vlenb
+** srli\ta3,a3,1
+** add\ta3,a3,sp
+** vse8.v\tv24,0\(a3\)
+** ...
+** csrr\ta3,vlenb
+** srli\ta3,a3,1
+** add\ta3,a3,sp
+** vle8.v\tv24,0\(a3\)
+** vse8.v\tv24,0\(a1\)
+** csrr\tt0,vlenb
+** add\tsp,sp,t0
+** ...
+** jr\tra
+*/
+void
+spill_10 (uint8_t *in, uint8_t *out)
+{
+ vuint8mf2_t v1 = *(vuint8mf2_t*)in;
+ exhaust_vector_regs ();
+ *(vuint8mf2_t*)out = v1;
+}
+
+/*
+** spill_11:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** ...
+** vs1r.v\tv24,0\(sp\)
+** ...
+** vl1re8.v\tv2,0\(sp\)
+** vs1r.v\tv2,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_11 (uint8_t *in, uint8_t *out)
+{
+ register vuint8m1_t v1 asm("v1") = *(vuint8m1_t*)in;
+ asm volatile ("# %0"::"vr"(v1));
+ exhaust_vector_regs ();
+ register vuint8m1_t v2 asm("v2") = v1;
+ *(vuint8m1_t*)out = v2;
+ asm volatile ("# %0"::"vr"(v2));
+}
+
+/*
+** spill_12:
+** csrr\tt0,vlenb
+** slli\tt1,t0,1
+** sub\tsp,sp,t1
+** ...
+** vs2r.v\tv24,0\(sp\)
+** ...
+** vl2re8.v\tv4,0\(sp\)
+** vs2r.v\tv4,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_12 (uint8_t *in, uint8_t *out)
+{
+ register vuint8m2_t v2 asm("v2") = *(vuint8m2_t*)in;
+ asm volatile ("# %0"::"vr"(v2));
+ exhaust_vector_regs ();
+ register vuint8m2_t v4 asm("v4") = v2;
+ *(vuint8m2_t*)out = v4;
+ asm volatile ("# %0"::"vr"(v4));
+}
+
+/*
+** spill_13:
+** csrr\tt0,vlenb
+** slli\tt1,t0,2
+** sub\tsp,sp,t1
+** ...
+** vs4r.v\tv24,0\(sp\)
+** ...
+** vl4re8.v\tv8,0\(sp\)
+** vs4r.v\tv8,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_13 (uint8_t *in, uint8_t *out)
+{
+ register vuint8m4_t v4 asm("v4") = *(vuint8m4_t*)in;
+ asm volatile ("# %0"::"vr"(v4));
+ exhaust_vector_regs ();
+ register vuint8m4_t v8 asm("v8") = v4;
+ *(vuint8m4_t*)out = v8;
+ asm volatile ("# %0"::"vr"(v8));
+}
+
+/*
+** spill_14:
+** csrr\tt0,vlenb
+** slli\tt1,t0,3
+** sub\tsp,sp,t1
+** ...
+** vs8r.v\tv24,0\(sp\)
+** ...
+** vl8re8.v\tv16,0\(sp\)
+** vs8r.v\tv16,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_14 (uint8_t *in, uint8_t *out)
+{
+ register vuint8m8_t v8 asm("v8") = *(vuint8m8_t*)in;
+ asm volatile ("# %0"::"vr"(v8));
+ exhaust_vector_regs ();
+ register vuint8m8_t v16 asm("v16") = v8;
+ *(vuint8m8_t*)out = v16;
+ asm volatile ("# %0"::"vr"(v16));
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-10.c
new file mode 100644
index 0000000..d37857e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-10.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -mpreferred-stack-boundary=3 -fno-schedule-insns -fno-schedule-insns2 -O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "riscv_vector.h"
+
+void f (char*);
+
+/*
+** stach_check_alloca_1:
+** addi\tsp,sp,-32
+** sw\tra,4\(sp\)
+** sw\ts0,0\(sp\)
+** addi\ts0,sp,8
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** ...
+** addi\ta2,a2,15
+** andi\ta2,a2,-8
+** sub\tsp,sp,a2
+** ...
+** lw\tra,4\(sp\)
+** lw\ts0,0\(sp\)
+** addi\tsp,sp,32
+** jr\tra
+*/
+void stach_check_alloca_1 (vuint8m1_t data, uint8_t *base, int y, ...)
+{
+ vuint8m8_t v0, v8, v16, v24;
+ asm volatile ("nop"
+ : "=vr" (v0), "=vr" (v8), "=vr" (v16), "=vr" (v24)
+ :
+ :);
+ asm volatile ("nop"
+ :
+ : "vr" (v0), "vr" (v8), "vr" (v16), "vr" (v24)
+ :);
+ *(vuint8m1_t *)base = data;
+ char* pStr = (char*)__builtin_alloca(y);
+ f(pStr);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-11.c
new file mode 100644
index 0000000..f522349
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-11.c
@@ -0,0 +1,59 @@
+/* { dg-do compile } */
+/* { dg-options "-msave-restore -march=rv32gcv -mabi=ilp32 -msave-restore -fno-schedule-insns -fno-schedule-insns2 -O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+#include "riscv_vector.h"
+
+void fn2 (float a1, float a2, float a3, float a4,
+ float a5, float a6, float a7, float a8);
+void fn3 (char*);
+
+/*
+** stack_save_restore_2:
+** call\tt0,__riscv_save_2
+** csrr\tt0,vlenb
+** slli\tt1,t0,1
+** sub\tsp,sp,t1
+** li\tt0,-8192
+** addi\tt0,t0,192
+** add\tsp,sp,t0
+** ...
+** csrr\tt0,vlenb
+** slli\tt1,t0,1
+** add\tsp,sp,t1
+** li\tt0,8192
+** addi\tt0,t0,-192
+** add\tsp,sp,t0
+** tail\t__riscv_restore_2
+*/
+int stack_save_restore_2 (float a1, float a2, float a3, float a4,
+ float a5, float a6, float a7, float a8,
+ vuint8m1_t data, uint8_t *base)
+{
+ char d[8000];
+ float f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13;
+ asm volatile ("nop"
+ : "=f" (f1), "=f" (f2), "=f" (f3), "=f" (f4), "=f" (f5), "=f" (f6),
+ "=f" (f7), "=f" (f8), "=f" (f9), "=f" (f10), "=f" (f11),
+ "=f" (f12), "=f" (f13)
+ :
+ :);
+ asm volatile ("nop"
+ :
+ : "f" (f1), "f" (f2), "f" (f3), "f" (f4), "f" (f5), "f" (f6),
+ "f" (f7), "f" (f8), "f" (f9), "f" (f10), "f" (f11),
+ "f" (f12), "f" (f13)
+ :);
+ vuint8m8_t v0, v8, v16, v24;
+ asm volatile ("nop"
+ : "=vr" (v0), "=vr" (v8), "=vr" (v16), "=vr" (v24)
+ :
+ :);
+ asm volatile ("nop"
+ :
+ : "vr" (v0), "vr" (v8), "vr" (v16), "vr" (v24)
+ :);
+ *(vuint8m1_t *)base = data;
+ fn2 (a1, a2, a3, a4, a5, a6, a7, a8);
+ fn3(d);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-12.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-12.c
new file mode 100644
index 0000000..de6e060
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-12.c
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -msave-restore -fno-schedule-insns -fno-schedule-insns2 -O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+
+void fn2 (float a1, float a2, float a3, float a4,
+ float a5, float a6, float a7, float a8);
+void fn3 (char*);
+
+
+/*
+** stack_save_restore_1:
+** call\tt0,__riscv_save_0
+** li\tt0,-8192
+** addi\tt0,t0,192
+** add\tsp,sp,t0
+** ...
+** li\ta0,-8192
+** addi\ta0,a0,192
+** li\ta5,8192
+** addi\ta5,a5,-192
+** add\ta5,a5,a0
+** add\ta0,a5,sp
+** ...
+** tail\t__riscv_restore_0
+*/
+int stack_save_restore_1 (float a1, float a2, float a3, float a4,
+ float a5, float a6, float a7, float a8)
+{
+ char d[8000];
+ float f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13;
+ asm volatile ("nop"
+ : "=f" (f1), "=f" (f2), "=f" (f3), "=f" (f4), "=f" (f5), "=f" (f6),
+ "=f" (f7), "=f" (f8), "=f" (f9), "=f" (f10), "=f" (f11),
+ "=f" (f12), "=f" (f13)
+ :
+ :);
+ asm volatile ("nop"
+ :
+ : "f" (f1), "f" (f2), "f" (f3), "f" (f4), "f" (f5), "f" (f6),
+ "f" (f7), "f" (f8), "f" (f9), "f" (f10), "f" (f11),
+ "f" (f12), "f" (f13)
+ :);
+ fn2 (a1, a2, a3, a4, a5, a6, a7, a8);
+ fn3(d);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-2.c
new file mode 100644
index 0000000..ca1904b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-2.c
@@ -0,0 +1,320 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -mpreferred-stack-boundary=3 -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "riscv_vector.h"
+#include "macro.h"
+
+/*
+** spill_2:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** vsetvli\ta5,zero,e16,mf4,ta,ma
+** vle16.v\tv24,0\(a0\)
+** csrr\ta2,vlenb
+** srli\ta2,a2,2
+** slli\ta3,a2,2
+** sub\ta3,a3,a2
+** add\ta3,a3,sp
+** vse16.v\tv24,0\(a3\)
+** ...
+** csrr\ta2,vlenb
+** srli\ta2,a2,2
+** slli\ta3,a2,2
+** sub\ta3,a3,a2
+** add\ta3,a3,sp
+** vle16.v\tv24,0\(a3\)
+** vse16.v\tv24,0\(a1\)
+** csrr\tt0,vlenb
+** add\tsp,sp,t0
+** ...
+** jr\tra
+*/
+void
+spill_2 (int16_t *in, int16_t *out)
+{
+ vint16mf4_t v1 = *(vint16mf4_t*)in;
+ exhaust_vector_regs ();
+ *(vint16mf4_t*)out = v1;
+}
+
+/*
+** spill_3:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** vsetvli\ta5,zero,e16,mf2,ta,ma
+** vle16.v\tv24,0\(a0\)
+** csrr\ta3,vlenb
+** srli\ta3,a3,1
+** add\ta3,a3,sp
+** vse16.v\tv24,0\(a3\)
+** ...
+** csrr\ta3,vlenb
+** srli\ta3,a3,1
+** add\ta3,a3,sp
+** vle16.v\tv24,0\(a3\)
+** vse16.v\tv24,0\(a1\)
+** csrr\tt0,vlenb
+** add\tsp,sp,t0
+** ...
+** jr\tra
+*/
+void
+spill_3 (int16_t *in, int16_t *out)
+{
+ vint16mf2_t v1 = *(vint16mf2_t*)in;
+ exhaust_vector_regs ();
+ *(vint16mf2_t*)out = v1;
+}
+
+/*
+** spill_4:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** ...
+** vs1r.v\tv24,0\(sp\)
+** ...
+** vl1re16.v\tv2,0\(sp\)
+** vs1r.v\tv2,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_4 (int16_t *in, int16_t *out)
+{
+ register vint16m1_t v1 asm("v1") = *(vint16m1_t*)in;
+ asm volatile ("# %0"::"vr"(v1));
+ exhaust_vector_regs ();
+ register vint16m1_t v2 asm("v2") = v1;
+ *(vint16m1_t*)out = v2;
+ asm volatile ("# %0"::"vr"(v2));
+}
+
+/*
+** spill_5:
+** csrr\tt0,vlenb
+** slli\tt1,t0,1
+** sub\tsp,sp,t1
+** ...
+** vs2r.v\tv24,0\(sp\)
+** ...
+** vl2re16.v\tv4,0\(sp\)
+** vs2r.v\tv4,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_5 (int16_t *in, int16_t *out)
+{
+ register vint16m2_t v2 asm("v2") = *(vint16m2_t*)in;
+ asm volatile ("# %0"::"vr"(v2));
+ exhaust_vector_regs ();
+ register vint16m2_t v4 asm("v4") = v2;
+ *(vint16m2_t*)out = v4;
+ asm volatile ("# %0"::"vr"(v4));
+}
+
+/*
+** spill_6:
+** csrr\tt0,vlenb
+** slli\tt1,t0,2
+** sub\tsp,sp,t1
+** ...
+** vs4r.v\tv24,0\(sp\)
+** ...
+** vl4re16.v\tv8,0\(sp\)
+** vs4r.v\tv8,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_6 (int16_t *in, int16_t *out)
+{
+ register vint16m4_t v4 asm("v4") = *(vint16m4_t*)in;
+ asm volatile ("# %0"::"vr"(v4));
+ exhaust_vector_regs ();
+ register vint16m4_t v8 asm("v8") = v4;
+ *(vint16m4_t*)out = v8;
+ asm volatile ("# %0"::"vr"(v8));
+}
+
+/*
+** spill_7:
+** csrr\tt0,vlenb
+** slli\tt1,t0,3
+** sub\tsp,sp,t1
+** ...
+** vs8r.v\tv24,0\(sp\)
+** ...
+** vl8re16.v\tv16,0\(sp\)
+** vs8r.v\tv16,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_7 (int16_t *in, int16_t *out)
+{
+ register vint16m8_t v8 asm("v8") = *(vint16m8_t*)in;
+ asm volatile ("# %0"::"vr"(v8));
+ exhaust_vector_regs ();
+ register vint16m8_t v16 asm("v16") = v8;
+ *(vint16m8_t*)out = v16;
+ asm volatile ("# %0"::"vr"(v16));
+}
+
+/*
+** spill_9:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** vsetvli\ta5,zero,e16,mf4,ta,ma
+** vle16.v\tv24,0\(a0\)
+** csrr\ta2,vlenb
+** srli\ta2,a2,2
+** slli\ta3,a2,2
+** sub\ta3,a3,a2
+** add\ta3,a3,sp
+** vse16.v\tv24,0\(a3\)
+** ...
+** csrr\ta2,vlenb
+** srli\ta2,a2,2
+** slli\ta3,a2,2
+** sub\ta3,a3,a2
+** add\ta3,a3,sp
+** vle16.v\tv24,0\(a3\)
+** vse16.v\tv24,0\(a1\)
+** csrr\tt0,vlenb
+** add\tsp,sp,t0
+** ...
+** jr\tra
+*/
+void
+spill_9 (uint16_t *in, uint16_t *out)
+{
+ vuint16mf4_t v1 = *(vuint16mf4_t*)in;
+ exhaust_vector_regs ();
+ *(vuint16mf4_t*)out = v1;
+}
+
+/*
+** spill_10:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** vsetvli\ta5,zero,e16,mf2,ta,ma
+** vle16.v\tv24,0\(a0\)
+** csrr\ta3,vlenb
+** srli\ta3,a3,1
+** add\ta3,a3,sp
+** vse16.v\tv24,0\(a3\)
+** ...
+** csrr\ta3,vlenb
+** srli\ta3,a3,1
+** add\ta3,a3,sp
+** vle16.v\tv24,0\(a3\)
+** vse16.v\tv24,0\(a1\)
+** csrr\tt0,vlenb
+** add\tsp,sp,t0
+** ...
+** jr\tra
+*/
+void
+spill_10 (uint16_t *in, uint16_t *out)
+{
+ vuint16mf2_t v1 = *(vuint16mf2_t*)in;
+ exhaust_vector_regs ();
+ *(vuint16mf2_t*)out = v1;
+}
+
+/*
+** spill_11:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** ...
+** vs1r.v\tv24,0\(sp\)
+** ...
+** vl1re16.v\tv2,0\(sp\)
+** vs1r.v\tv2,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_11 (uint16_t *in, uint16_t *out)
+{
+ register vuint16m1_t v1 asm("v1") = *(vuint16m1_t*)in;
+ asm volatile ("# %0"::"vr"(v1));
+ exhaust_vector_regs ();
+ register vuint16m1_t v2 asm("v2") = v1;
+ *(vuint16m1_t*)out = v2;
+ asm volatile ("# %0"::"vr"(v2));
+}
+
+/*
+** spill_12:
+** csrr\tt0,vlenb
+** slli\tt1,t0,1
+** sub\tsp,sp,t1
+** ...
+** vs2r.v\tv24,0\(sp\)
+** ...
+** vl2re16.v\tv4,0\(sp\)
+** vs2r.v\tv4,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_12 (uint16_t *in, uint16_t *out)
+{
+ register vuint16m2_t v2 asm("v2") = *(vuint16m2_t*)in;
+ asm volatile ("# %0"::"vr"(v2));
+ exhaust_vector_regs ();
+ register vuint16m2_t v4 asm("v4") = v2;
+ *(vuint16m2_t*)out = v4;
+ asm volatile ("# %0"::"vr"(v4));
+}
+
+/*
+** spill_13:
+** csrr\tt0,vlenb
+** slli\tt1,t0,2
+** sub\tsp,sp,t1
+** ...
+** vs4r.v\tv24,0\(sp\)
+** ...
+** vl4re16.v\tv8,0\(sp\)
+** vs4r.v\tv8,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_13 (uint16_t *in, uint16_t *out)
+{
+ register vuint16m4_t v4 asm("v4") = *(vuint16m4_t*)in;
+ asm volatile ("# %0"::"vr"(v4));
+ exhaust_vector_regs ();
+ register vuint16m4_t v8 asm("v8") = v4;
+ *(vuint16m4_t*)out = v8;
+ asm volatile ("# %0"::"vr"(v8));
+}
+
+/*
+** spill_14:
+** csrr\tt0,vlenb
+** slli\tt1,t0,3
+** sub\tsp,sp,t1
+** ...
+** vs8r.v\tv24,0\(sp\)
+** ...
+** vl8re16.v\tv16,0\(sp\)
+** vs8r.v\tv16,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_14 (uint16_t *in, uint16_t *out)
+{
+ register vuint16m8_t v8 asm("v8") = *(vuint16m8_t*)in;
+ asm volatile ("# %0"::"vr"(v8));
+ exhaust_vector_regs ();
+ register vuint16m8_t v16 asm("v16") = v8;
+ *(vuint16m8_t*)out = v16;
+ asm volatile ("# %0"::"vr"(v16));
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-3.c
new file mode 100644
index 0000000..2039ca3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-3.c
@@ -0,0 +1,254 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -mpreferred-stack-boundary=3 -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "riscv_vector.h"
+#include "macro.h"
+
+/*
+** spill_3:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** vsetvli\ta5,zero,e32,mf2,ta,ma
+** vle32.v\tv24,0\(a0\)
+** csrr\ta3,vlenb
+** srli\ta3,a3,1
+** add\ta3,a3,sp
+** vse32.v\tv24,0\(a3\)
+** ...
+** csrr\ta3,vlenb
+** srli\ta3,a3,1
+** add\ta3,a3,sp
+** vle32.v\tv24,0\(a3\)
+** vse32.v\tv24,0\(a1\)
+** csrr\tt0,vlenb
+** add\tsp,sp,t0
+** ...
+** jr\tra
+*/
+void
+spill_3 (int32_t *in, int32_t *out)
+{
+ vint32mf2_t v1 = *(vint32mf2_t*)in;
+ exhaust_vector_regs ();
+ *(vint32mf2_t*)out = v1;
+}
+
+/*
+** spill_4:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** ...
+** vs1r.v\tv24,0\(sp\)
+** ...
+** vl1re32.v\tv2,0\(sp\)
+** vs1r.v\tv2,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_4 (int32_t *in, int32_t *out)
+{
+ register vint32m1_t v1 asm("v1") = *(vint32m1_t*)in;
+ asm volatile ("# %0"::"vr"(v1));
+ exhaust_vector_regs ();
+ register vint32m1_t v2 asm("v2") = v1;
+ *(vint32m1_t*)out = v2;
+ asm volatile ("# %0"::"vr"(v2));
+}
+
+/*
+** spill_5:
+** csrr\tt0,vlenb
+** slli\tt1,t0,1
+** sub\tsp,sp,t1
+** ...
+** vs2r.v\tv24,0\(sp\)
+** ...
+** vl2re32.v\tv4,0\(sp\)
+** vs2r.v\tv4,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_5 (int32_t *in, int32_t *out)
+{
+ register vint32m2_t v2 asm("v2") = *(vint32m2_t*)in;
+ asm volatile ("# %0"::"vr"(v2));
+ exhaust_vector_regs ();
+ register vint32m2_t v4 asm("v4") = v2;
+ *(vint32m2_t*)out = v4;
+ asm volatile ("# %0"::"vr"(v4));
+}
+
+/*
+** spill_6:
+** csrr\tt0,vlenb
+** slli\tt1,t0,2
+** sub\tsp,sp,t1
+** ...
+** vs4r.v\tv24,0\(sp\)
+** ...
+** vl4re32.v\tv8,0\(sp\)
+** vs4r.v\tv8,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_6 (int32_t *in, int32_t *out)
+{
+ register vint32m4_t v4 asm("v4") = *(vint32m4_t*)in;
+ asm volatile ("# %0"::"vr"(v4));
+ exhaust_vector_regs ();
+ register vint32m4_t v8 asm("v8") = v4;
+ *(vint32m4_t*)out = v8;
+ asm volatile ("# %0"::"vr"(v8));
+}
+
+/*
+** spill_7:
+** csrr\tt0,vlenb
+** slli\tt1,t0,3
+** sub\tsp,sp,t1
+** ...
+** vs8r.v\tv24,0\(sp\)
+** ...
+** vl8re32.v\tv16,0\(sp\)
+** vs8r.v\tv16,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_7 (int32_t *in, int32_t *out)
+{
+ register vint32m8_t v8 asm("v8") = *(vint32m8_t*)in;
+ asm volatile ("# %0"::"vr"(v8));
+ exhaust_vector_regs ();
+ register vint32m8_t v16 asm("v16") = v8;
+ *(vint32m8_t*)out = v16;
+ asm volatile ("# %0"::"vr"(v16));
+}
+
+/*
+** spill_10:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** vsetvli\ta5,zero,e32,mf2,ta,ma
+** vle32.v\tv24,0\(a0\)
+** csrr\ta3,vlenb
+** srli\ta3,a3,1
+** add\ta3,a3,sp
+** vse32.v\tv24,0\(a3\)
+** ...
+** csrr\ta3,vlenb
+** srli\ta3,a3,1
+** add\ta3,a3,sp
+** vle32.v\tv24,0\(a3\)
+** vse32.v\tv24,0\(a1\)
+** csrr\tt0,vlenb
+** add\tsp,sp,t0
+** ...
+** jr\tra
+*/
+void
+spill_10 (uint32_t *in, uint32_t *out)
+{
+ vuint32mf2_t v1 = *(vuint32mf2_t*)in;
+ exhaust_vector_regs ();
+ *(vuint32mf2_t*)out = v1;
+}
+
+/*
+** spill_11:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** ...
+** vs1r.v\tv24,0\(sp\)
+** ...
+** vl1re32.v\tv2,0\(sp\)
+** vs1r.v\tv2,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_11 (uint32_t *in, uint32_t *out)
+{
+ register vuint32m1_t v1 asm("v1") = *(vuint32m1_t*)in;
+ asm volatile ("# %0"::"vr"(v1));
+ exhaust_vector_regs ();
+ register vuint32m1_t v2 asm("v2") = v1;
+ *(vuint32m1_t*)out = v2;
+ asm volatile ("# %0"::"vr"(v2));
+}
+
+/*
+** spill_12:
+** csrr\tt0,vlenb
+** slli\tt1,t0,1
+** sub\tsp,sp,t1
+** ...
+** vs2r.v\tv24,0\(sp\)
+** ...
+** vl2re32.v\tv4,0\(sp\)
+** vs2r.v\tv4,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_12 (uint32_t *in, uint32_t *out)
+{
+ register vuint32m2_t v2 asm("v2") = *(vuint32m2_t*)in;
+ asm volatile ("# %0"::"vr"(v2));
+ exhaust_vector_regs ();
+ register vuint32m2_t v4 asm("v4") = v2;
+ *(vuint32m2_t*)out = v4;
+ asm volatile ("# %0"::"vr"(v4));
+}
+
+/*
+** spill_13:
+** csrr\tt0,vlenb
+** slli\tt1,t0,2
+** sub\tsp,sp,t1
+** ...
+** vs4r.v\tv24,0\(sp\)
+** ...
+** vl4re32.v\tv8,0\(sp\)
+** vs4r.v\tv8,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_13 (uint32_t *in, uint32_t *out)
+{
+ register vuint32m4_t v4 asm("v4") = *(vuint32m4_t*)in;
+ asm volatile ("# %0"::"vr"(v4));
+ exhaust_vector_regs ();
+ register vuint32m4_t v8 asm("v8") = v4;
+ *(vuint32m4_t*)out = v8;
+ asm volatile ("# %0"::"vr"(v8));
+}
+
+/*
+** spill_14:
+** csrr\tt0,vlenb
+** slli\tt1,t0,3
+** sub\tsp,sp,t1
+** ...
+** vs8r.v\tv24,0\(sp\)
+** ...
+** vl8re32.v\tv16,0\(sp\)
+** vs8r.v\tv16,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_14 (uint32_t *in, uint32_t *out)
+{
+ register vuint32m8_t v8 asm("v8") = *(vuint32m8_t*)in;
+ asm volatile ("# %0"::"vr"(v8));
+ exhaust_vector_regs ();
+ register vuint32m8_t v16 asm("v16") = v8;
+ *(vuint32m8_t*)out = v16;
+ asm volatile ("# %0"::"vr"(v16));
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-4.c
new file mode 100644
index 0000000..83c80b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-4.c
@@ -0,0 +1,196 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -mpreferred-stack-boundary=3 -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "riscv_vector.h"
+#include "macro.h"
+
+/*
+** spill_4:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** ...
+** vs1r.v\tv24,0\(sp\)
+** ...
+** vl1re64.v\tv2,0\(sp\)
+** vs1r.v\tv2,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_4 (int64_t *in, int64_t *out)
+{
+ register vint64m1_t v1 asm("v1") = *(vint64m1_t*)in;
+ asm volatile ("# %0"::"vr"(v1));
+ exhaust_vector_regs ();
+ register vint64m1_t v2 asm("v2") = v1;
+ *(vint64m1_t*)out = v2;
+ asm volatile ("# %0"::"vr"(v2));
+}
+
+/*
+** spill_5:
+** csrr\tt0,vlenb
+** slli\tt1,t0,1
+** sub\tsp,sp,t1
+** ...
+** vs2r.v\tv24,0\(sp\)
+** ...
+** vl2re64.v\tv4,0\(sp\)
+** vs2r.v\tv4,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_5 (int64_t *in, int64_t *out)
+{
+ register vint64m2_t v2 asm("v2") = *(vint64m2_t*)in;
+ asm volatile ("# %0"::"vr"(v2));
+ exhaust_vector_regs ();
+ register vint64m2_t v4 asm("v4") = v2;
+ *(vint64m2_t*)out = v4;
+ asm volatile ("# %0"::"vr"(v4));
+}
+
+/*
+** spill_6:
+** csrr\tt0,vlenb
+** slli\tt1,t0,2
+** sub\tsp,sp,t1
+** ...
+** vs4r.v\tv24,0\(sp\)
+** ...
+** vl4re64.v\tv8,0\(sp\)
+** vs4r.v\tv8,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_6 (int64_t *in, int64_t *out)
+{
+ register vint64m4_t v4 asm("v4") = *(vint64m4_t*)in;
+ asm volatile ("# %0"::"vr"(v4));
+ exhaust_vector_regs ();
+ register vint64m4_t v8 asm("v8") = v4;
+ *(vint64m4_t*)out = v8;
+ asm volatile ("# %0"::"vr"(v8));
+}
+
+/*
+** spill_7:
+** csrr\tt0,vlenb
+** slli\tt1,t0,3
+** sub\tsp,sp,t1
+** ...
+** vs8r.v\tv24,0\(sp\)
+** ...
+** vl8re64.v\tv16,0\(sp\)
+** vs8r.v\tv16,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_7 (int64_t *in, int64_t *out)
+{
+ register vint64m8_t v8 asm("v8") = *(vint64m8_t*)in;
+ asm volatile ("# %0"::"vr"(v8));
+ exhaust_vector_regs ();
+ register vint64m8_t v16 asm("v16") = v8;
+ *(vint64m8_t*)out = v16;
+ asm volatile ("# %0"::"vr"(v16));
+}
+
+/*
+** spill_11:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** ...
+** vs1r.v\tv24,0\(sp\)
+** ...
+** vl1re64.v\tv2,0\(sp\)
+** vs1r.v\tv2,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_11 (uint64_t *in, uint64_t *out)
+{
+ register vuint64m1_t v1 asm("v1") = *(vuint64m1_t*)in;
+ asm volatile ("# %0"::"vr"(v1));
+ exhaust_vector_regs ();
+ register vuint64m1_t v2 asm("v2") = v1;
+ *(vuint64m1_t*)out = v2;
+ asm volatile ("# %0"::"vr"(v2));
+}
+
+/*
+** spill_12:
+** csrr\tt0,vlenb
+** slli\tt1,t0,1
+** sub\tsp,sp,t1
+** ...
+** vs2r.v\tv24,0\(sp\)
+** ...
+** vl2re64.v\tv4,0\(sp\)
+** vs2r.v\tv4,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_12 (uint64_t *in, uint64_t *out)
+{
+ register vuint64m2_t v2 asm("v2") = *(vuint64m2_t*)in;
+ asm volatile ("# %0"::"vr"(v2));
+ exhaust_vector_regs ();
+ register vuint64m2_t v4 asm("v4") = v2;
+ *(vuint64m2_t*)out = v4;
+ asm volatile ("# %0"::"vr"(v4));
+}
+
+/*
+** spill_13:
+** csrr\tt0,vlenb
+** slli\tt1,t0,2
+** sub\tsp,sp,t1
+** ...
+** vs4r.v\tv24,0\(sp\)
+** ...
+** vl4re64.v\tv8,0\(sp\)
+** vs4r.v\tv8,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_13 (uint64_t *in, uint64_t *out)
+{
+ register vuint64m4_t v4 asm("v4") = *(vuint64m4_t*)in;
+ asm volatile ("# %0"::"vr"(v4));
+ exhaust_vector_regs ();
+ register vuint64m4_t v8 asm("v8") = v4;
+ *(vuint64m4_t*)out = v8;
+ asm volatile ("# %0"::"vr"(v8));
+}
+
+/*
+** spill_14:
+** csrr\tt0,vlenb
+** slli\tt1,t0,3
+** sub\tsp,sp,t1
+** ...
+** vs8r.v\tv24,0\(sp\)
+** ...
+** vl8re64.v\tv16,0\(sp\)
+** vs8r.v\tv16,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_14 (uint64_t *in, uint64_t *out)
+{
+ register vuint64m8_t v8 asm("v8") = *(vuint64m8_t*)in;
+ asm volatile ("# %0"::"vr"(v8));
+ exhaust_vector_regs ();
+ register vuint64m8_t v16 asm("v16") = v8;
+ *(vuint64m8_t*)out = v16;
+ asm volatile ("# %0"::"vr"(v16));
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-5.c
new file mode 100644
index 0000000..3c228a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-5.c
@@ -0,0 +1,130 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -mpreferred-stack-boundary=3 -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "riscv_vector.h"
+#include "macro.h"
+
+/*
+** spill_3:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** vsetvli\ta5,zero,e32,mf2,ta,ma
+** vle32.v\tv24,0\(a0\)
+** csrr\ta3,vlenb
+** srli\ta3,a3,1
+** add\ta3,a3,sp
+** vse32.v\tv24,0\(a3\)
+** ...
+** csrr\ta3,vlenb
+** srli\ta3,a3,1
+** add\ta3,a3,sp
+** vle32.v\tv24,0\(a3\)
+** vse32.v\tv24,0\(a1\)
+** csrr\tt0,vlenb
+** add\tsp,sp,t0
+** ...
+** jr\tra
+*/
+void
+spill_3 (float *in, float *out)
+{
+ vfloat32mf2_t v1 = *(vfloat32mf2_t*)in;
+ exhaust_vector_regs ();
+ *(vfloat32mf2_t*)out = v1;
+}
+
+/*
+** spill_4:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** ...
+** vs1r.v\tv24,0\(sp\)
+** ...
+** vl1re32.v\tv2,0\(sp\)
+** vs1r.v\tv2,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_4 (float *in, float *out)
+{
+ register vfloat32m1_t v1 asm("v1") = *(vfloat32m1_t*)in;
+ asm volatile ("# %0"::"vr"(v1));
+ exhaust_vector_regs ();
+ register vfloat32m1_t v2 asm("v2") = v1;
+ *(vfloat32m1_t*)out = v2;
+ asm volatile ("# %0"::"vr"(v2));
+}
+
+/*
+** spill_5:
+** csrr\tt0,vlenb
+** slli\tt1,t0,1
+** sub\tsp,sp,t1
+** ...
+** vs2r.v\tv24,0\(sp\)
+** ...
+** vl2re32.v\tv4,0\(sp\)
+** vs2r.v\tv4,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_5 (float *in, float *out)
+{
+ register vfloat32m2_t v2 asm("v2") = *(vfloat32m2_t*)in;
+ asm volatile ("# %0"::"vr"(v2));
+ exhaust_vector_regs ();
+ register vfloat32m2_t v4 asm("v4") = v2;
+ *(vfloat32m2_t*)out = v4;
+ asm volatile ("# %0"::"vr"(v4));
+}
+
+/*
+** spill_6:
+** csrr\tt0,vlenb
+** slli\tt1,t0,2
+** sub\tsp,sp,t1
+** ...
+** vs4r.v\tv24,0\(sp\)
+** ...
+** vl4re32.v\tv8,0\(sp\)
+** vs4r.v\tv8,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_6 (float *in, float *out)
+{
+ register vfloat32m4_t v4 asm("v4") = *(vfloat32m4_t*)in;
+ asm volatile ("# %0"::"vr"(v4));
+ exhaust_vector_regs ();
+ register vfloat32m4_t v8 asm("v8") = v4;
+ *(vfloat32m4_t*)out = v8;
+ asm volatile ("# %0"::"vr"(v8));
+}
+
+/*
+** spill_7:
+** csrr\tt0,vlenb
+** slli\tt1,t0,3
+** sub\tsp,sp,t1
+** ...
+** vs8r.v\tv24,0\(sp\)
+** ...
+** vl8re32.v\tv16,0\(sp\)
+** vs8r.v\tv16,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_7 (float *in, float *out)
+{
+ register vfloat32m8_t v8 asm("v8") = *(vfloat32m8_t*)in;
+ asm volatile ("# %0"::"vr"(v8));
+ exhaust_vector_regs ();
+ register vfloat32m8_t v16 asm("v16") = v8;
+ *(vfloat32m8_t*)out = v16;
+ asm volatile ("# %0"::"vr"(v16));
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-6.c
new file mode 100644
index 0000000..340029d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-6.c
@@ -0,0 +1,101 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -mpreferred-stack-boundary=3 -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "riscv_vector.h"
+#include "macro.h"
+
+/*
+** spill_4:
+** csrr\tt0,vlenb
+** sub\tsp,sp,t0
+** ...
+** vs1r.v\tv24,0\(sp\)
+** ...
+** vl1re64.v\tv2,0\(sp\)
+** vs1r.v\tv2,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_4 (double *in, double *out)
+{
+ register vfloat64m1_t v1 asm("v1") = *(vfloat64m1_t*)in;
+ asm volatile ("# %0"::"vr"(v1));
+ exhaust_vector_regs ();
+ register vfloat64m1_t v2 asm("v2") = v1;
+ *(vfloat64m1_t*)out = v2;
+ asm volatile ("# %0"::"vr"(v2));
+}
+
+/*
+** spill_5:
+** csrr\tt0,vlenb
+** slli\tt1,t0,1
+** sub\tsp,sp,t1
+** ...
+** vs2r.v\tv24,0\(sp\)
+** ...
+** vl2re64.v\tv4,0\(sp\)
+** vs2r.v\tv4,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_5 (double *in, double *out)
+{
+ register vfloat64m2_t v2 asm("v2") = *(vfloat64m2_t*)in;
+ asm volatile ("# %0"::"vr"(v2));
+ exhaust_vector_regs ();
+ register vfloat64m2_t v4 asm("v4") = v2;
+ *(vfloat64m2_t*)out = v4;
+ asm volatile ("# %0"::"vr"(v4));
+}
+
+/*
+** spill_6:
+** csrr\tt0,vlenb
+** slli\tt1,t0,2
+** sub\tsp,sp,t1
+** ...
+** vs4r.v\tv24,0\(sp\)
+** ...
+** vl4re64.v\tv8,0\(sp\)
+** vs4r.v\tv8,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_6 (double *in, double *out)
+{
+ register vfloat64m4_t v4 asm("v4") = *(vfloat64m4_t*)in;
+ asm volatile ("# %0"::"vr"(v4));
+ exhaust_vector_regs ();
+ register vfloat64m4_t v8 asm("v8") = v4;
+ *(vfloat64m4_t*)out = v8;
+ asm volatile ("# %0"::"vr"(v8));
+}
+
+/*
+** spill_7:
+** csrr\tt0,vlenb
+** slli\tt1,t0,3
+** sub\tsp,sp,t1
+** ...
+** vs8r.v\tv24,0\(sp\)
+** ...
+** vl8re64.v\tv16,0\(sp\)
+** vs8r.v\tv16,0\(a1\)
+** ...
+** jr\tra
+*/
+void
+spill_7 (double *in, double *out)
+{
+ register vfloat64m8_t v8 asm("v8") = *(vfloat64m8_t*)in;
+ asm volatile ("# %0"::"vr"(v8));
+ exhaust_vector_regs ();
+ register vfloat64m8_t v16 asm("v16") = v8;
+ *(vfloat64m8_t*)out = v16;
+ asm volatile ("# %0"::"vr"(v16));
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-7.c
new file mode 100644
index 0000000..cf1eea2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-7.c
@@ -0,0 +1,114 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -mpreferred-stack-boundary=3 -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "riscv_vector.h"
+#include "macro.h"
+
+/*
+** spill:
+** csrr\tt0,vlenb
+** slli\tt1,t0,4
+** sub\tsp,sp,t1
+** vsetvli\ta3,zero,e8,mf8,ta,ma
+** vle8.v\tv24,0\(a0\)
+** csrr\ta5,vlenb
+** srli\ta5,a5,3
+** add\ta5,a5,sp
+** vse8.v\tv24,0\(a5\)
+** addi\ta5,a0,1
+** vsetvli\ta4,zero,e8,mf4,ta,ma
+** vle8.v\tv24,0\(a5\)
+** csrr\ta5,vlenb
+** srli\ta5,a5,2
+** add\ta5,a5,sp
+** vse8.v\tv24,0\(a5\)
+** addi\ta2,a0,2
+** vsetvli\ta5,zero,e8,mf2,ta,ma
+** vle8.v\tv24,0\(a2\)
+** csrr\ta2,vlenb
+** srli\ta2,a2,1
+** add\ta2,a2,sp
+** vse8.v\tv24,0\(a2\)
+** addi\ta2,a0,3
+** vl1re8.v\tv24,0\(a2\)
+** csrr\ta2,vlenb
+** add\ta2,a2,sp
+** vs1r.v\tv24,0\(a2\)
+** addi\ta2,a0,4
+** vl2re8.v\tv24,0\(a2\)
+** csrr\tt3,vlenb
+** slli\ta2,t3,1
+** add\ta2,a2,sp
+** vs2r.v\tv24,0\(a2\)
+** addi\ta2,a0,5
+** vl4re8.v\tv24,0\(a2\)
+** mv\ta2,t3
+** slli\tt3,t3,2
+** add\tt3,t3,sp
+** vs4r.v\tv24,0\(t3\)
+** addi\ta0,a0,6
+** vl8re8.v\tv24,0\(a0\)
+** slli\ta0,a2,3
+** add\ta0,a0,sp
+** vs8r.v\tv24,0\(a0\)
+** ...
+** srli\ta0,a2,3
+** add\ta0,a0,sp
+** ...
+** vle8.v\tv27,0\(a0\)
+** vse8.v\tv27,0\(a1\)
+** addi\ta3,a1,1
+** srli\ta0,a2,2
+** add\ta0,a0,sp
+** ...
+** vle8.v\tv27,0\(a0\)
+** vse8.v\tv27,0\(a3\)
+** addi\ta4,a1,2
+** srli\ta3,a2,1
+** add\ta3,a3,sp
+** ...
+** vle8.v\tv27,0\(a3\)
+** vse8.v\tv27,0\(a4\)
+** addi\ta5,a1,3
+** add\ta4,a2,sp
+** vl1re8.v\tv25,0\(a4\)
+** vs1r.v\tv25,0\(a5\)
+** addi\ta5,a1,4
+** slli\ta4,a2,1
+** add\ta4,a4,sp
+** vl2re8.v\tv26,0\(a4\)
+** vs2r.v\tv26,0\(a5\)
+** addi\ta5,a1,5
+** vl4re8.v\tv28,0\(t3\)
+** vs4r.v\tv28,0\(a5\)
+** addi\ta1,a1,6
+** slli\ta5,a2,3
+** add\ta5,a5,sp
+** vl8re8.v\tv24,0\(a5\)
+** vs8r.v\tv24,0\(a1\)
+** csrr\tt0,vlenb
+** slli\tt1,t0,4
+** add\tsp,sp,t1
+** ...
+** jr\tra
+*/
+void
+spill (int8_t *in, int8_t *out)
+{
+ vint8mf8_t v0 = *(vint8mf8_t*)in;
+ vint8mf4_t v1 = *(vint8mf4_t*)(in + 1);
+ vint8mf2_t v2 = *(vint8mf2_t*)(in + 2);
+ vint8m1_t v3 = *(vint8m1_t*)(in + 3);
+ vint8m2_t v4 = *(vint8m2_t*)(in + 4);
+ vint8m4_t v8 = *(vint8m4_t*)(in + 5);
+ vint8m8_t v16 = *(vint8m8_t*)(in + 6);
+ exhaust_vector_regs ();
+ *(vint8mf8_t*)out = v0;
+ *(vint8mf4_t*)(out + 1) = v1;
+ *(vint8mf2_t*)(out + 2) = v2;
+ *(vint8m1_t*)(out + 3) = v3;
+ *(vint8m2_t*)(out + 4) = v4;
+ *(vint8m4_t*)(out + 5) = v8;
+ *(vint8m8_t*)(out + 6) = v16;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-8.c
new file mode 100644
index 0000000..ddc36e8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-8.c
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -fno-schedule-insns -fno-schedule-insns2 -O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+void f2 (char*);
+void f3 (char*, ...);
+
+/*
+** stach_check_alloca_1:
+** addi sp,sp,-48
+** sw ra,12\(sp\)
+** sw s0,8\(sp\)
+** addi s0,sp,16
+** ...
+** addi a0,a0,23
+** andi a0,a0,-16
+** sub sp,sp,a0
+** ...
+** addi sp,s0,-16
+** lw ra,12\(sp\)
+** lw s0,8\(sp\)
+** addi sp,sp,48
+** jr ra
+*/
+void stach_check_alloca_1 (int y, ...)
+{
+ char* pStr = (char*)__builtin_alloca(y);
+ f2(pStr);
+}
+
+/*
+** stach_check_alloca_2:
+** addi sp,sp,-48
+** sw ra,44\(sp\)
+** sw s0,40\(sp\)
+** addi s0,sp,48
+** addi a0,a0,23
+** andi a0,a0,-16
+** sub sp,sp,a0
+** ...
+** addi sp,s0,-48
+** lw ra,44\(sp\)
+** lw s0,40\(sp\)
+** addi sp,sp,48
+** jr ra
+*/
+void stach_check_alloca_2 (int y)
+{
+ char* pStr = (char*)__builtin_alloca(y);
+ f3(pStr, pStr, pStr, pStr, pStr, pStr, pStr, pStr, 2, pStr, pStr, pStr, 1);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-9.c
new file mode 100644
index 0000000..7111113
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-9.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -fno-schedule-insns -fno-schedule-insns2 -O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "riscv_vector.h"
+
+void f (char*);
+
+/*
+** stach_check_alloca_1:
+** addi\tsp,sp,-48
+** sw\tra,12\(sp\)
+** sw\ts0,8\(sp\)
+** addi\ts0,sp,16
+** csrr\tt0,vlenb
+** slli\tt1,t0,1
+** sub\tsp,sp,t1
+** ...
+** addi\ta2,a2,23
+** andi\ta2,a2,-16
+** sub\tsp,sp,a2
+** ...
+** lw\tra,12\(sp\)
+** lw\ts0,8\(sp\)
+** addi\tsp,sp,48
+** jr\tra
+*/
+void stach_check_alloca_1 (vuint8m1_t data, uint8_t *base, int y, ...)
+{
+ vuint8m8_t v0, v8, v16, v24;
+ asm volatile ("nop"
+ : "=vr" (v0), "=vr" (v8), "=vr" (v16), "=vr" (v24)
+ :
+ :);
+ asm volatile ("nop"
+ :
+ : "vr" (v0), "vr" (v8), "vr" (v16), "vr" (v24)
+ :);
+ *(vuint8m1_t *)base = data;
+ char* pStr = (char*)__builtin_alloca(y);
+ f(pStr);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-sp-adjust.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-sp-adjust.c
new file mode 100644
index 0000000..f8c9f63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-sp-adjust.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv" } */
+
+#include "spill-1.c"
+
+void
+spill_sp_adjust (int8_t *v)
+{
+ vint8mf8_t v1 = *(vint8mf8_t*)v;
+}
+
+/* Make sure we do not have a useless SP adjustment. */
+/* { dg-final { scan-assembler-not "addi\tsp,sp,0" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sge.c b/gcc/testsuite/gcc.target/riscv/sge.c
new file mode 100644
index 0000000..5f7e7ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sge.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+int
+sge (int x, int y)
+{
+ return x >= y;
+}
+
+/* { dg-final { scan-assembler "\\sxori\\sa0,a0,1\n\\sret\n" } } */
+/* { dg-final { scan-assembler-not "andi|sext\\.w" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sgeu.c b/gcc/testsuite/gcc.target/riscv/sgeu.c
new file mode 100644
index 0000000..234b9aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sgeu.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+int
+sgeu (unsigned int x, unsigned int y)
+{
+ return x >= y;
+}
+
+/* { dg-final { scan-assembler "\\sxori\\sa0,a0,1\n\\sret\n" } } */
+/* { dg-final { scan-assembler-not "andi|sext\\.w" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/shrink-wrap-1.c b/gcc/testsuite/gcc.target/riscv/shrink-wrap-1.c
new file mode 100644
index 0000000..e1e07c3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/shrink-wrap-1.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-fshrink-wrap" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Oz" } } */
+
+void g(void);
+
+void f(int x)
+{
+ if (x)
+ {
+ /* Force saving of some callee-saved registers. With shrink wrapping
+ enabled these only need to be saved if x is non-zero. */
+ register int s2 asm("18") = x;
+ register int s3 asm("19") = x;
+ register int s4 asm("20") = x;
+ asm("" : : "r"(s2));
+ asm("" : : "r"(s3));
+ asm("" : : "r"(s4));
+ g();
+ }
+}
+
+/* The resulting code should do nothing if X is 0. */
+/* { dg-final { scan-assembler "bne\ta0,zero,.*\n.*ret" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sle.c b/gcc/testsuite/gcc.target/riscv/sle.c
new file mode 100644
index 0000000..3259c19
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sle.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+int
+sle (int x, int y)
+{
+ return x <= y;
+}
+
+/* { dg-final { scan-assembler "\\sxori\\sa0,a0,1\n\\sret\n" } } */
+/* { dg-final { scan-assembler-not "andi|sext\\.w" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sleu.c b/gcc/testsuite/gcc.target/riscv/sleu.c
new file mode 100644
index 0000000..301b8c3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sleu.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+int
+sleu (unsigned int x, unsigned int y)
+{
+ return x <= y;
+}
+
+/* { dg-final { scan-assembler "\\sxori\\sa0,a0,1\n\\sret\n" } } */
+/* { dg-final { scan-assembler-not "andi|sext\\.w" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/stack_frame.c b/gcc/testsuite/gcc.target/riscv/stack_frame.c
new file mode 100644
index 0000000..485a52d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/stack_frame.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=rv32imafc -mabi=ilp32f" } */
+char my_getchar();
+float getf();
+
+float foo()
+{
+ char volatile array[3120];
+ float volatile farray[3120];
+ float sum = 0;
+ float f1 = getf();
+ float f2 = getf();
+ float f3 = getf();
+ float f4 = getf();
+
+ for (int i = 0; i < 3120; i++)
+ {
+ array[i] = my_getchar();
+ farray[i] = my_getchar() * 1.2;
+ sum += array[i] + farray[i] + f1 + f2 + f3 + f4;
+ }
+
+ return sum;
+}
+
+/* { dg-final { scan-assembler-not {,-[0-9]+\(sp\)} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zawrs.c b/gcc/testsuite/gcc.target/riscv/zawrs.c
new file mode 100644
index 0000000..0b7e266
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zawrs.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zawrs" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zawrs" { target { rv32 } } } */
+
+#ifndef __riscv_zawrs
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/zba-shNadd-04.c b/gcc/testsuite/gcc.target/riscv/zba-shNadd-04.c
new file mode 100644
index 0000000..abed149
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zba-shNadd-04.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zba -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+
+long long sub1(unsigned long long a, unsigned long long b)
+{
+ b = (b << 32) >> 31;
+ unsigned int x = a + b;
+ return x;
+}
+
+long long sub2(unsigned long long a, unsigned long long b)
+{
+ return (unsigned int)(a + (b << 1));
+}
+
+long long sub3(unsigned long long a, unsigned long long b)
+{
+ return (a + (b << 1)) & ~0u;
+}
+
+/* { dg-final { scan-assembler-times "sh1add" 3 } } */
+/* { dg-final { scan-assembler-times "zext.w\t" 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zba-shNadd-05.c b/gcc/testsuite/gcc.target/riscv/zba-shNadd-05.c
new file mode 100644
index 0000000..271c3a8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zba-shNadd-05.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zba -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" } } */
+
+long long f(int a, int b)
+{
+ return (a * 3) / b;
+}
+
+/* { dg-final { scan-assembler-times "sh1add\t" 1 } } */
+/* { dg-final { scan-assembler-times "divw\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zba-shNadd-07.c b/gcc/testsuite/gcc.target/riscv/zba-shNadd-07.c
new file mode 100644
index 0000000..98d35e1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zba-shNadd-07.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zba -mabi=lp64 -O2" } */
+
+unsigned long
+f1 (unsigned long i)
+{
+ return i * 200;
+}
+
+unsigned long
+f2 (unsigned long i)
+{
+ return i * 783;
+}
+
+unsigned long
+f3 (unsigned long i)
+{
+ return i * 784;
+}
+
+unsigned long
+f4 (unsigned long i)
+{
+ return i * 1574;
+}
+
+/* { dg-final { scan-assembler-times "sh2add" 2 } } */
+/* { dg-final { scan-assembler-times "sh1add" 2 } } */
+/* { dg-final { scan-assembler-times "slli" 5 } } */
+/* { dg-final { scan-assembler-times "mul" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zbb-min-max-02.c b/gcc/testsuite/gcc.target/riscv/zbb-min-max-02.c
new file mode 100644
index 0000000..b462859
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbb-min-max-02.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zba_zbb -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" } } */
+
+int f(unsigned int* a)
+{
+ const int C = 1000;
+ return *a * 3 > C ? C : *a * 3;
+}
+
+/* { dg-final { scan-assembler-times "minu" 1 } } */
+/* { dg-final { scan-assembler-times "sext.w" 1 } } */
+/* { dg-final { scan-assembler-not "zext.w" } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/zbb-srai-andn.c b/gcc/testsuite/gcc.target/riscv/zbb-srai-andn.c
new file mode 100644
index 0000000..afe9fba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbb-srai-andn.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zbb -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+
+long long foo0(long long a, long long b)
+{
+ if (a >= 0)
+ return b;
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times "srai\t" 1 } } */
+/* { dg-final { scan-assembler-times "andn\t" 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/zbs-bclri-01.c b/gcc/testsuite/gcc.target/riscv/zbs-bclri-01.c
new file mode 100644
index 0000000..12e2063
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbs-bclri-01.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zbs -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+
+/* bclri + bclri */
+long long f5 (long long a)
+{
+ return a & ~0x11000;
+}
+
+/* { dg-final { scan-assembler-times "bclri\t" 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/zbs-bclri-02.c b/gcc/testsuite/gcc.target/riscv/zbs-bclri-02.c
new file mode 100644
index 0000000..6125484
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbs-bclri-02.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zbs -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+
+long long f3(long long a)
+{
+ return a & ~0x1100;
+}
+
+long long f4 (long long a)
+{
+ return a & ~0x80000000000000ffull;
+}
+
+long long f5 (long long a)
+{
+ return a & ~0x8000001000000000ull;
+}
+
+long long f6 (long long a)
+{
+ return a & ~0xff7ffffffffffffull;
+}
+
+/* { dg-final { scan-assembler-times "bclri\t" 4 } } */
+/* { dg-final { scan-assembler-times "andi\t" 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/zbs-bext.c b/gcc/testsuite/gcc.target/riscv/zbs-bext.c
index 4798239..a8aadb6 100644
--- a/gcc/testsuite/gcc.target/riscv/zbs-bext.c
+++ b/gcc/testsuite/gcc.target/riscv/zbs-bext.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-march=rv64gc_zbs -mabi=lp64" } */
-/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
/* bext */
long
@@ -16,6 +16,29 @@ foo1 (long i)
return 1L & (i >> 20);
}
+long bext64_1(long a, char bitno)
+{
+ return (a & (1UL << bitno)) ? 1 : 0;
+}
+
+long bext64_2(long a, char bitno)
+{
+ return (a & (1UL << bitno)) ? 0 : 1;
+}
+
+long bext64_3(long a, char bitno)
+{
+ return (a & (1UL << bitno)) ? 0 : -1;
+}
+
+long bext64_4(long a, char bitno)
+{
+ return (a & (1UL << bitno)) ? -1 : 0;
+}
+
/* { dg-final { scan-assembler-times "bexti\t" 1 } } */
-/* { dg-final { scan-assembler-times "bext\t" 1 } } */
-/* { dg-final { scan-assembler-not "andi" } } */
+/* { dg-final { scan-assembler-times "bext\t" 5 } } */
+/* { dg-final { scan-assembler-times "xori\t|snez\t" 1 } } */
+/* { dg-final { scan-assembler-times "addi\t" 1 } } */
+/* { dg-final { scan-assembler-times "neg\t" 1 } } */
+/* { dg-final { scan-assembler-not "andi" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/zbs-bexti.c b/gcc/testsuite/gcc.target/riscv/zbs-bexti.c
new file mode 100644
index 0000000..d7a8963
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbs-bexti.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zbs -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+
+/* bexti */
+#define BIT_NO 21
+
+long bexti64_1(long a, char bitno)
+{
+ return (a & (1UL << BIT_NO)) ? 1 : 0;
+}
+
+long bexti64_2(long a, char bitno)
+{
+ return (a & (1UL << BIT_NO)) ? 0 : 1;
+}
+
+long bexti64_3(long a, char bitno)
+{
+ return (a & (1UL << BIT_NO)) ? 0 : -1;
+}
+
+long bexti64_4(long a, char bitno)
+{
+ return (a & (1UL << BIT_NO)) ? -1 : 0;
+}
+
+/* { dg-final { scan-assembler-times "bexti\t" 4 } } */
+/* { dg-final { scan-assembler-times "xori\t" 1 } } */
+/* { dg-final { scan-assembler-times "addi\t" 1 } } */
+/* { dg-final { scan-assembler-times "neg\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zbs-binvi.c b/gcc/testsuite/gcc.target/riscv/zbs-binvi.c
new file mode 100644
index 0000000..c2d6725
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbs-binvi.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zbs -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+
+long long f3(long long a)
+{
+ return a ^ 0x1100;
+}
+
+long long f4 (long long a)
+{
+ return a ^ 0x80000000000000ffull;
+}
+
+long long f5 (long long a)
+{
+ return a ^ 0x8000001000000000ull;
+}
+
+/* { dg-final { scan-assembler-times "binvi\t" 4 } } */
+/* { dg-final { scan-assembler-times "xori\t" 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/zbs-bseti-02.c b/gcc/testsuite/gcc.target/riscv/zbs-bseti-02.c
new file mode 100644
index 0000000..d362994
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbs-bseti-02.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zbs -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+
+/* bexti */
+int f(int* a, int b)
+{
+ return ((*a << b) | (1 << 14));
+}
+
+int g(int a, int b)
+{
+ return ((a + b)| (1 << 30));
+}
+
+int h(int a, int b)
+{
+ return ((a + b)| (1ULL << 33));
+}
+
+/* { dg-final { scan-assembler-times "addw\t" 2 } } */
+/* { dg-final { scan-assembler-times "sllw\t" 1 } } */
+/* { dg-final { scan-assembler-times "bseti\t" 2 } } */
+/* { dg-final { scan-assembler-not "sext.w\t" } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/zbs-bseti.c b/gcc/testsuite/gcc.target/riscv/zbs-bseti.c
new file mode 100644
index 0000000..5738add
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbs-bseti.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zbs -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+
+long long foo1 (long long a)
+{
+ return a | 0x1100;
+}
+
+long long foo2 (long long a)
+{
+ return a | 0x80000000000000ffull;
+}
+
+long long foo3 (long long a)
+{
+ return a | 0x8000000100000000ull;
+}
+
+long long foo4 (long long a)
+{
+ return a | 0xfff;
+}
+
+/* { dg-final { scan-assembler-times "bseti\t" 5 } } */
+/* { dg-final { scan-assembler-times "ori\t" 3 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c b/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
new file mode 100644
index 0000000..d249a84
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zbb_zbs -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" } } */
+
+void g();
+
+void f1 (long a)
+{
+ if ((a & ((1ul << 33) | (1 << 4))) == (1ul << 33))
+ g();
+}
+
+void f2 (long a)
+{
+ if ((a & 0x12) == 0x10)
+ g();
+}
+
+/* { dg-final { scan-assembler-times "bexti\t" 2 } } */
+/* { dg-final { scan-assembler-times "andn\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/abi-bf16.exp b/gcc/testsuite/gcc.target/x86_64/abi/bf16/abi-bf16.exp
index bd386f2..8edab85 100644
--- a/gcc/testsuite/gcc.target/x86_64/abi/bf16/abi-bf16.exp
+++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/abi-bf16.exp
@@ -36,9 +36,15 @@ set additional_flags "-W -Wall -msse2"
foreach src [lsort [glob -nocomplain $srcdir/$subdir/test_*.c]] {
if {[runtest_file_p $runtests $src]} {
- c-torture-execute [list $src \
- $srcdir/$subdir/asm-support.S] \
- $additional_flags
+ if { ([istarget *-*-darwin*]) } then {
+ c-torture-execute [list $src \
+ $srcdir/$subdir/asm-support-darwin.S] \
+ $additional_flags
+ } else {
+ c-torture-execute [list $src \
+ $srcdir/$subdir/asm-support.S] \
+ $additional_flags
+ }
}
}
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/args.h b/gcc/testsuite/gcc.target/x86_64/abi/bf16/args.h
index 11d7e2b..95f9a39 100644
--- a/gcc/testsuite/gcc.target/x86_64/abi/bf16/args.h
+++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/args.h
@@ -42,8 +42,8 @@ typedef union {
} X87_T;
extern void (*callthis)(void);
extern unsigned long long rax,rbx,rcx,rdx,rsi,rdi,rsp,rbp,r8,r9,r10,r11,r12,r13,r14,r15;
-XMM_T xmm_regs[16];
-X87_T x87_regs[8];
+extern XMM_T xmm_regs[16];
+extern X87_T x87_regs[8];
extern volatile unsigned long long volatile_var;
extern void snapshot (void);
extern void snapshot_ret (void);
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/asm-support-darwin.S b/gcc/testsuite/gcc.target/x86_64/abi/bf16/asm-support-darwin.S
new file mode 100644
index 0000000..bdaa02f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/asm-support-darwin.S
@@ -0,0 +1,97 @@
+ .text
+ .p2align 4,,15
+ .globl _snapshot
+_snapshot:
+LFB3:
+ movq %rax, _rax(%rip)
+ movq %rbx, _rbx(%rip)
+ movq %rcx, _rcx(%rip)
+ movq %rdx, _rdx(%rip)
+ movq %rdi, _rdi(%rip)
+ movq %rsi, _rsi(%rip)
+ movq %rbp, _rbp(%rip)
+ movq %rsp, _rsp(%rip)
+ movq %r8, _r8(%rip)
+ movq %r9, _r9(%rip)
+ movq %r10, _r10(%rip)
+ movq %r11, _r11(%rip)
+ movq %r12, _r12(%rip)
+ movq %r13, _r13(%rip)
+ movq %r14, _r14(%rip)
+ movq %r15, _r15(%rip)
+ movdqu %xmm0, _xmm_regs+0(%rip)
+ movdqu %xmm1, _xmm_regs+16(%rip)
+ movdqu %xmm2, _xmm_regs+32(%rip)
+ movdqu %xmm3, _xmm_regs+48(%rip)
+ movdqu %xmm4, _xmm_regs+64(%rip)
+ movdqu %xmm5, _xmm_regs+80(%rip)
+ movdqu %xmm6, _xmm_regs+96(%rip)
+ movdqu %xmm7, _xmm_regs+112(%rip)
+ movdqu %xmm8, _xmm_regs+128(%rip)
+ movdqu %xmm9, _xmm_regs+144(%rip)
+ movdqu %xmm10, _xmm_regs+160(%rip)
+ movdqu %xmm11, _xmm_regs+176(%rip)
+ movdqu %xmm12, _xmm_regs+192(%rip)
+ movdqu %xmm13, _xmm_regs+208(%rip)
+ movdqu %xmm14, _xmm_regs+224(%rip)
+ movdqu %xmm15, _xmm_regs+240(%rip)
+ jmp *_callthis(%rip)
+LFE3:
+
+ .p2align 4,,15
+ .globl _snapshot_ret
+_snapshot_ret:
+ movq %rdi, _rdi(%rip)
+ subq $8, %rsp
+ call *_callthis(%rip)
+ addq $8, %rsp
+ movq %rax, _rax(%rip)
+ movq %rdx, _rdx(%rip)
+ movdqu %xmm0, _xmm_regs+0(%rip)
+ movdqu %xmm1, _xmm_regs+16(%rip)
+ fstpt _x87_regs(%rip)
+ fstpt _x87_regs+16(%rip)
+ fldt _x87_regs+16(%rip)
+ fldt _x87_regs(%rip)
+ ret
+
+ .globl _callthis
+ .zerofill __DATA,__bss,_callthis,8,3
+ .globl _rax
+ .zerofill __DATA,__bss,_rax,8,3
+ .globl _rbx
+ .zerofill __DATA,__bss,_rbx,8,3
+ .globl _rcx
+ .zerofill __DATA,__bss,_rcx,8,3
+ .globl _rdx
+ .zerofill __DATA,__bss,_rdx,8,3
+ .globl _rsi
+ .zerofill __DATA,__bss,_rsi,8,3
+ .globl _rdi
+ .zerofill __DATA,__bss,_rdi,8,3
+ .globl _rsp
+ .zerofill __DATA,__bss,_rsp,8,3
+ .globl _rbp
+ .zerofill __DATA,__bss,_rbp,8,3
+ .globl _r8
+ .zerofill __DATA,__bss,_r8,8,3
+ .globl _r9
+ .zerofill __DATA,__bss,_r9,8,3
+ .globl _r10
+ .zerofill __DATA,__bss,_r10,8,3
+ .globl _r11
+ .zerofill __DATA,__bss,_r11,8,3
+ .globl _r12
+ .zerofill __DATA,__bss,_r12,8,3
+ .globl _r13
+ .zerofill __DATA,__bss,_r13,8,3
+ .globl _r14
+ .zerofill __DATA,__bss,_r14,8,3
+ .globl _r15
+ .zerofill __DATA,__bss,_r15,8,3
+ .globl _xmm_regs
+ .zerofill __DATA,__bss,_xmm_regs,256,5
+ .globl _x87_regs
+ .zerofill __DATA,__bss,_x87_regs,128,5
+ .globl _volatile_var
+ .zerofill __DATA,__bss,_volatile_var,8,3
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/abi-bf16-ymm.exp b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/abi-bf16-ymm.exp
index 309db8f..02b4505 100644
--- a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/abi-bf16-ymm.exp
+++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/abi-bf16-ymm.exp
@@ -36,9 +36,15 @@ set additional_flags "-W -Wall -mavx2"
foreach src [lsort [glob -nocomplain $srcdir/$subdir/test_*.c]] {
if {[runtest_file_p $runtests $src]} {
- c-torture-execute [list $src \
- $srcdir/$subdir/asm-support.S] \
- $additional_flags
+ if { ([istarget *-*-darwin*]) } then {
+ c-torture-execute [list $src \
+ $srcdir/$subdir/asm-support-darwin.S] \
+ $additional_flags
+ } else {
+ c-torture-execute [list $src \
+ $srcdir/$subdir/asm-support.S] \
+ $additional_flags
+ }
}
}
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/args.h b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/args.h
index 94627ff..1027742 100644
--- a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/args.h
+++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/args.h
@@ -50,8 +50,8 @@ typedef union {
} X87_T;
extern void (*callthis)(void);
extern unsigned long long rax,rbx,rcx,rdx,rsi,rdi,rsp,rbp,r8,r9,r10,r11,r12,r13,r14,r15;
-YMM_T ymm_regs[16];
-X87_T x87_regs[8];
+extern YMM_T ymm_regs[16];
+extern X87_T x87_regs[8];
extern volatile unsigned long long volatile_var;
extern void snapshot (void);
extern void snapshot_ret (void);
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/asm-support-darwin.S b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/asm-support-darwin.S
new file mode 100644
index 0000000..e136b57
--- /dev/null
+++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m256bf16/asm-support-darwin.S
@@ -0,0 +1,97 @@
+ .text
+ .p2align 4,,15
+ .globl _snapshot
+_snapshot:
+.LFB3:
+ movq %rax, _rax(%rip)
+ movq %rbx, _rbx(%rip)
+ movq %rcx, _rcx(%rip)
+ movq %rdx, _rdx(%rip)
+ movq %rdi, _rdi(%rip)
+ movq %rsi, _rsi(%rip)
+ movq %rbp, _rbp(%rip)
+ movq %rsp, _rsp(%rip)
+ movq %r8, _r8(%rip)
+ movq %r9, _r9(%rip)
+ movq %r10, _r10(%rip)
+ movq %r11, _r11(%rip)
+ movq %r12, _r12(%rip)
+ movq %r13, _r13(%rip)
+ movq %r14, _r14(%rip)
+ movq %r15, _r15(%rip)
+ vmovdqu %ymm0, _ymm_regs+0(%rip)
+ vmovdqu %ymm1, _ymm_regs+32(%rip)
+ vmovdqu %ymm2, _ymm_regs+64(%rip)
+ vmovdqu %ymm3, _ymm_regs+96(%rip)
+ vmovdqu %ymm4, _ymm_regs+128(%rip)
+ vmovdqu %ymm5, _ymm_regs+160(%rip)
+ vmovdqu %ymm6, _ymm_regs+192(%rip)
+ vmovdqu %ymm7, _ymm_regs+224(%rip)
+ vmovdqu %ymm8, _ymm_regs+256(%rip)
+ vmovdqu %ymm9, _ymm_regs+288(%rip)
+ vmovdqu %ymm10, _ymm_regs+320(%rip)
+ vmovdqu %ymm11, _ymm_regs+352(%rip)
+ vmovdqu %ymm12, _ymm_regs+384(%rip)
+ vmovdqu %ymm13, _ymm_regs+416(%rip)
+ vmovdqu %ymm14, _ymm_regs+448(%rip)
+ vmovdqu %ymm15, _ymm_regs+480(%rip)
+ jmp *_callthis(%rip)
+.LFE3:
+
+ .p2align 4,,15
+ .globl _snapshot_ret
+_snapshot_ret:
+ movq %rdi, _rdi(%rip)
+ subq $8, %rsp
+ call *_callthis(%rip)
+ addq $8, %rsp
+ movq %rax, _rax(%rip)
+ movq %rdx, _rdx(%rip)
+ vmovdqu %ymm0, _ymm_regs+0(%rip)
+ vmovdqu %ymm1, _ymm_regs+32(%rip)
+ fstpt _x87_regs(%rip)
+ fstpt _x87_regs+16(%rip)
+ fldt _x87_regs+16(%rip)
+ fldt _x87_regs(%rip)
+ ret
+
+ .globl _callthis
+ .zerofill __DATA,__bss,_callthis,8,3
+ .globl _rax
+ .zerofill __DATA,__bss,_rax,8,3
+ .globl _rbx
+ .zerofill __DATA,__bss,_rbx,8,3
+ .globl _rcx
+ .zerofill __DATA,__bss,_rcx,8,3
+ .globl _rdx
+ .zerofill __DATA,__bss,_rdx,8,3
+ .globl _rsi
+ .zerofill __DATA,__bss,_rsi,8,3
+ .globl _rdi
+ .zerofill __DATA,__bss,_rdi,8,3
+ .globl _rsp
+ .zerofill __DATA,__bss,_rsp,8,3
+ .globl _rbp
+ .zerofill __DATA,__bss,_rbp,8,3
+ .globl _r8
+ .zerofill __DATA,__bss,_r8,8,3
+ .globl _r9
+ .zerofill __DATA,__bss,_r9,8,3
+ .globl _r10
+ .zerofill __DATA,__bss,_r10,8,3
+ .globl _r11
+ .zerofill __DATA,__bss,_r11,8,3
+ .globl _r12
+ .zerofill __DATA,__bss,_r12,8,3
+ .globl _r13
+ .zerofill __DATA,__bss,_r13,8,3
+ .globl _r14
+ .zerofill __DATA,__bss,_r14,8,3
+ .globl _r15
+ .zerofill __DATA,__bss,_r15,8,3
+ .globl _ymm_regs
+ .zerofill __DATA,__bss,_ymm_regs,512,5
+ .globl _x87_regs
+ .zerofill __DATA,__bss,_x87_regs,128,5
+ .globl _volatile_var
+ .zerofill __DATA,__bss,_volatile_var,8,3
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/abi-bf16-zmm.exp b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/abi-bf16-zmm.exp
index b6e0fed..28abb4e 100644
--- a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/abi-bf16-zmm.exp
+++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/abi-bf16-zmm.exp
@@ -36,9 +36,15 @@ set additional_flags "-W -Wall -mavx512f"
foreach src [lsort [glob -nocomplain $srcdir/$subdir/test_*.c]] {
if {[runtest_file_p $runtests $src]} {
- c-torture-execute [list $src \
- $srcdir/$subdir/asm-support.S] \
- $additional_flags
+ if { ([istarget *-*-darwin*]) } then {
+ c-torture-execute [list $src \
+ $srcdir/$subdir/asm-support-darwin.S] \
+ $additional_flags
+ } else {
+ c-torture-execute [list $src \
+ $srcdir/$subdir/asm-support.S] \
+ $additional_flags
+ }
}
}
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/args.h b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/args.h
index 64b2478..f9710ba 100644
--- a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/args.h
+++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/args.h
@@ -51,8 +51,8 @@ typedef union {
} X87_T;
extern void (*callthis)(void);
extern unsigned long long rax,rbx,rcx,rdx,rsi,rdi,rsp,rbp,r8,r9,r10,r11,r12,r13,r14,r15;
-ZMM_T zmm_regs[32];
-X87_T x87_regs[8];
+extern ZMM_T zmm_regs[32];
+extern X87_T x87_regs[8];
extern volatile unsigned long long volatile_var;
extern void snapshot (void);
extern void snapshot_ret (void);
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/asm-support-darwin.S b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/asm-support-darwin.S
new file mode 100644
index 0000000..71b61b3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/x86_64/abi/bf16/m512bf16/asm-support-darwin.S
@@ -0,0 +1,113 @@
+ .text
+ .p2align 4,,15
+ .globl _snapshot
+_snapshot:
+.LFB3:
+ movq %rax, _rax(%rip)
+ movq %rbx, _rbx(%rip)
+ movq %rcx, _rcx(%rip)
+ movq %rdx, _rdx(%rip)
+ movq %rdi, _rdi(%rip)
+ movq %rsi, _rsi(%rip)
+ movq %rbp, _rbp(%rip)
+ movq %rsp, _rsp(%rip)
+ movq %r8, _r8(%rip)
+ movq %r9, _r9(%rip)
+ movq %r10, _r10(%rip)
+ movq %r11, _r11(%rip)
+ movq %r12, _r12(%rip)
+ movq %r13, _r13(%rip)
+ movq %r14, _r14(%rip)
+ movq %r15, _r15(%rip)
+ vmovdqu32 %zmm0, _zmm_regs+0(%rip)
+ vmovdqu32 %zmm1, _zmm_regs+64(%rip)
+ vmovdqu32 %zmm2, _zmm_regs+128(%rip)
+ vmovdqu32 %zmm3, _zmm_regs+192(%rip)
+ vmovdqu32 %zmm4, _zmm_regs+256(%rip)
+ vmovdqu32 %zmm5, _zmm_regs+320(%rip)
+ vmovdqu32 %zmm6, _zmm_regs+384(%rip)
+ vmovdqu32 %zmm7, _zmm_regs+448(%rip)
+ vmovdqu32 %zmm8, _zmm_regs+512(%rip)
+ vmovdqu32 %zmm9, _zmm_regs+576(%rip)
+ vmovdqu32 %zmm10, _zmm_regs+640(%rip)
+ vmovdqu32 %zmm11, _zmm_regs+704(%rip)
+ vmovdqu32 %zmm12, _zmm_regs+768(%rip)
+ vmovdqu32 %zmm13, _zmm_regs+832(%rip)
+ vmovdqu32 %zmm14, _zmm_regs+896(%rip)
+ vmovdqu32 %zmm15, _zmm_regs+960(%rip)
+ vmovdqu32 %zmm16, _zmm_regs+1024(%rip)
+ vmovdqu32 %zmm17, _zmm_regs+1088(%rip)
+ vmovdqu32 %zmm18, _zmm_regs+1152(%rip)
+ vmovdqu32 %zmm19, _zmm_regs+1216(%rip)
+ vmovdqu32 %zmm20, _zmm_regs+1280(%rip)
+ vmovdqu32 %zmm21, _zmm_regs+1344(%rip)
+ vmovdqu32 %zmm22, _zmm_regs+1408(%rip)
+ vmovdqu32 %zmm23, _zmm_regs+1472(%rip)
+ vmovdqu32 %zmm24, _zmm_regs+1536(%rip)
+ vmovdqu32 %zmm25, _zmm_regs+1600(%rip)
+ vmovdqu32 %zmm26, _zmm_regs+1664(%rip)
+ vmovdqu32 %zmm27, _zmm_regs+1728(%rip)
+ vmovdqu32 %zmm28, _zmm_regs+1792(%rip)
+ vmovdqu32 %zmm29, _zmm_regs+1856(%rip)
+ vmovdqu32 %zmm30, _zmm_regs+1920(%rip)
+ vmovdqu32 %zmm31, _zmm_regs+1984(%rip)
+ jmp *_callthis(%rip)
+.LFE3:
+
+ .p2align 4,,15
+ .globl _snapshot_ret
+_snapshot_ret:
+ movq %rdi, _rdi(%rip)
+ subq $8, %rsp
+ call *_callthis(%rip)
+ addq $8, %rsp
+ movq %rax, _rax(%rip)
+ movq %rdx, _rdx(%rip)
+ vmovdqu32 %zmm0, _zmm_regs+0(%rip)
+ vmovdqu32 %zmm1, _zmm_regs+64(%rip)
+ fstpt _x87_regs(%rip)
+ fstpt _x87_regs+16(%rip)
+ fldt _x87_regs+16(%rip)
+ fldt _x87_regs(%rip)
+ ret
+
+ .globl _callthis
+ .zerofill __DATA,__bss,_callthis,8,3
+ .globl _rax
+ .zerofill __DATA,__bss,_rax,8,3
+ .globl _rbx
+ .zerofill __DATA,__bss,_rbx,8,3
+ .globl _rcx
+ .zerofill __DATA,__bss,_rcx,8,3
+ .globl _rdx
+ .zerofill __DATA,__bss,_rdx,8,3
+ .globl _rsi
+ .zerofill __DATA,__bss,_rsi,8,3
+ .globl _rdi
+ .zerofill __DATA,__bss,_rdi,8,3
+ .globl _rsp
+ .zerofill __DATA,__bss,_rsp,8,3
+ .globl _rbp
+ .zerofill __DATA,__bss,_rbp,8,3
+ .globl _r8
+ .zerofill __DATA,__bss,_r8,8,3
+ .globl _r9
+ .zerofill __DATA,__bss,_r9,8,3
+ .globl _r10
+ .zerofill __DATA,__bss,_r10,8,3
+ .globl _r11
+ .zerofill __DATA,__bss,_r11,8,3
+ .globl _r12
+ .zerofill __DATA,__bss,_r12,8,3
+ .globl _r13
+ .zerofill __DATA,__bss,_r13,8,3
+ .globl _r14
+ .zerofill __DATA,__bss,_r14,8,3
+ .globl _r15
+ .zerofill __DATA,__bss,_r15,8,3
+ .globl _zmm_regs
+ .zerofill __DATA,__bss,_zmm_regs,2048,6
+ .globl _x87_regs
+ .zerofill __DATA,__bss,_x87_regs,128,5
+ .globl _volatile_var
+ .zerofill __DATA,__bss,_volatile_var,8,3
diff --git a/gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch2.d b/gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch2.d
index 9e90c15..7b83fff 100644
--- a/gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch2.d
+++ b/gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch2.d
@@ -191,41 +191,6 @@ void test_blendvector()
blendvector!(byte16, byte16, byte16)(0, 0, 0);
}
-void test_comparison()
-{
- equalMask!int(0, 0); // { dg-warning "mismatch in return type" }
- equalMask!double(0, 0); // { dg-warning "mismatch in return type" }
- equalMask!int4(0, 0);
- equalMask!short8(0, 0);
- equalMask!float4(0, 0);
- equalMask!byte16(0, 0);
- equalMask!fake4(f, f); // { dg-warning "mismatch in return type" }
-
- notEqualMask!int(0, 0); // { dg-warning "mismatch in return type" }
- notEqualMask!double(0, 0); // { dg-warning "mismatch in return type" }
- notEqualMask!int4(0, 0);
- notEqualMask!short8(0, 0);
- notEqualMask!float4(0, 0);
- notEqualMask!byte16(0, 0);
- notEqualMask!fake4(f, f); // { dg-warning "mismatch in return type" }
-
- greaterMask!int(0, 0); // { dg-warning "mismatch in return type" }
- greaterMask!double(0, 0); // { dg-warning "mismatch in return type" }
- greaterMask!int4(0, 0);
- greaterMask!short8(0, 0);
- greaterMask!float4(0, 0);
- greaterMask!byte16(0, 0);
- greaterMask!fake4(f, f); // { dg-warning "mismatch in return type" }
-
- greaterOrEqualMask!int(0, 0); // { dg-warning "mismatch in return type" }
- greaterOrEqualMask!double(0, 0); // { dg-warning "mismatch in return type" }
- greaterOrEqualMask!int4(0, 0);
- greaterOrEqualMask!short8(0, 0);
- greaterOrEqualMask!float4(0, 0);
- greaterOrEqualMask!byte16(0, 0);
- greaterOrEqualMask!fake4(f, f); // { dg-warning "mismatch in return type" }
-}
-
// The following declarations of the simd intrinsics are without any guards
// to verify `d/intrinsics.cc` is doing checks to prevent invalid lowerings.
V loadUnaligned(V)(const V*);
@@ -243,8 +208,3 @@ __vector(E!V1[M.length]) shufflevector(V1, V2, M...)(V1, V2, M) if (isV!V1 && is
V convertvector(V, T)(T);
V0 blendvector(V0, V1, M)(V0, V1, M);
-
-V equalMask(V)(V, V);
-V notEqualMask(V)(V, V);
-V greaterMask(V)(V, V);
-V greaterOrEqualMask(V)(V, V);
diff --git a/gcc/testsuite/gdc.dg/attr_register2.d b/gcc/testsuite/gdc.dg/attr_register2.d
index 9061a64..22c518f 100644
--- a/gcc/testsuite/gdc.dg/attr_register2.d
+++ b/gcc/testsuite/gdc.dg/attr_register2.d
@@ -6,6 +6,6 @@ import gcc.attributes;
@register("ebx") extern int var2; // { dg-error "explicit register variable .var2. declared .extern." }
-@register("r12") __gshared int var3 = 0x2a; // { dg-error "global register variable has initial value" }
+@register("ebp") __gshared int var3 = 0x2a; // { dg-error "global register variable has initial value" }
-@register("r12") __gshared int[256] var4 = void; // { dg-error "data type of .var4. isn.t suitable for a register" }
+@register("ebp") __gshared int[256] var4 = void; // { dg-error "data type of .var4. isn.t suitable for a register" }
diff --git a/gcc/testsuite/gdc.dg/imports/pr108050/mod1.d b/gcc/testsuite/gdc.dg/imports/pr108050/mod1.d
new file mode 100644
index 0000000..f27a13d
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/pr108050/mod1.d
@@ -0,0 +1,2 @@
+module imports.pr108050.mod1;
+string[] split() { return null; }
diff --git a/gcc/testsuite/gdc.dg/imports/pr108050/mod2.d b/gcc/testsuite/gdc.dg/imports/pr108050/mod2.d
new file mode 100644
index 0000000..29d8aa8
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/pr108050/mod2.d
@@ -0,0 +1,2 @@
+module imports.pr108050.mod2;
+string[] split() { return null; }
diff --git a/gcc/testsuite/gdc.dg/imports/pr108050/package.d b/gcc/testsuite/gdc.dg/imports/pr108050/package.d
new file mode 100644
index 0000000..b8b03b8
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/pr108050/package.d
@@ -0,0 +1,2 @@
+module imports.pr108050;
+public import imports.pr108050.mod1, imports.pr108050.mod2;
diff --git a/gcc/testsuite/gdc.dg/pr107592.d b/gcc/testsuite/gdc.dg/pr107592.d
new file mode 100644
index 0000000..59f3447
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr107592.d
@@ -0,0 +1,13 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107592
+// { dg-do compile }
+
+void test107592(Things...)(Things things)
+{
+ label:
+ foreach (thing; things)
+ {
+ continue label;
+ }
+}
+
+alias a107592 = test107592!(string);
diff --git a/gcc/testsuite/gdc.dg/pr108050.d b/gcc/testsuite/gdc.dg/pr108050.d
new file mode 100644
index 0000000..69134e7
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr108050.d
@@ -0,0 +1,4 @@
+// { dg-do compile }
+// { dg-additional-sources "imports/pr108050/package.d imports/pr108050/mod1.d imports/pr108050/mod2.d" }
+// { dg-options "-g" }
+import imports.pr108050 : split;
diff --git a/gcc/testsuite/gdc.dg/simd2a.d b/gcc/testsuite/gdc.dg/simd2a.d
index 0fb391c..d64f704 100644
--- a/gcc/testsuite/gdc.dg/simd2a.d
+++ b/gcc/testsuite/gdc.dg/simd2a.d
@@ -18,12 +18,12 @@ void test2a()
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2b.d b/gcc/testsuite/gdc.dg/simd2b.d
index 41a4eb3..71abd78 100644
--- a/gcc/testsuite/gdc.dg/simd2b.d
+++ b/gcc/testsuite/gdc.dg/simd2b.d
@@ -18,12 +18,12 @@ void test2b()
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2c.d b/gcc/testsuite/gdc.dg/simd2c.d
index a995709..4806b48 100644
--- a/gcc/testsuite/gdc.dg/simd2c.d
+++ b/gcc/testsuite/gdc.dg/simd2c.d
@@ -18,12 +18,12 @@ void test2c()
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2d.d b/gcc/testsuite/gdc.dg/simd2d.d
index d578734..ce447e1 100644
--- a/gcc/testsuite/gdc.dg/simd2d.d
+++ b/gcc/testsuite/gdc.dg/simd2d.d
@@ -18,12 +18,12 @@ void test2d()
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2e.d b/gcc/testsuite/gdc.dg/simd2e.d
index d33574a..464d1a5 100644
--- a/gcc/testsuite/gdc.dg/simd2e.d
+++ b/gcc/testsuite/gdc.dg/simd2e.d
@@ -18,12 +18,12 @@ void test2e()
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2f.d b/gcc/testsuite/gdc.dg/simd2f.d
index 5845249..d7e67fc 100644
--- a/gcc/testsuite/gdc.dg/simd2f.d
+++ b/gcc/testsuite/gdc.dg/simd2f.d
@@ -18,12 +18,12 @@ void test2f()
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2g.d b/gcc/testsuite/gdc.dg/simd2g.d
index ce438f2..3d15869 100644
--- a/gcc/testsuite/gdc.dg/simd2g.d
+++ b/gcc/testsuite/gdc.dg/simd2g.d
@@ -18,12 +18,12 @@ void test2g()
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2h.d b/gcc/testsuite/gdc.dg/simd2h.d
index c631c76..849b6ad 100644
--- a/gcc/testsuite/gdc.dg/simd2h.d
+++ b/gcc/testsuite/gdc.dg/simd2h.d
@@ -18,12 +18,12 @@ void test2h()
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
v1 = v2 << 1;
v1 = v2 >> 1;
v1 = v2 >>> 1;
diff --git a/gcc/testsuite/gdc.dg/simd2i.d b/gcc/testsuite/gdc.dg/simd2i.d
index 6946c79..03130b7 100644
--- a/gcc/testsuite/gdc.dg/simd2i.d
+++ b/gcc/testsuite/gdc.dg/simd2i.d
@@ -18,12 +18,12 @@ void test2i()
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
static assert(!__traits(compiles, v1 << 1));
static assert(!__traits(compiles, v1 >> 1));
static assert(!__traits(compiles, v1 >>> 1));
diff --git a/gcc/testsuite/gdc.dg/simd2j.d b/gcc/testsuite/gdc.dg/simd2j.d
index ecfdbf3..f86a448 100644
--- a/gcc/testsuite/gdc.dg/simd2j.d
+++ b/gcc/testsuite/gdc.dg/simd2j.d
@@ -18,12 +18,12 @@ void test2j()
static assert(!__traits(compiles, v1 ^^ v2));
static assert(!__traits(compiles, v1 is v2));
static assert(!__traits(compiles, v1 !is v2));
- static assert(!__traits(compiles, v1 == v2));
- static assert(!__traits(compiles, v1 != v2));
- static assert(!__traits(compiles, v1 < v2));
- static assert(!__traits(compiles, v1 > v2));
- static assert(!__traits(compiles, v1 <= v2));
- static assert(!__traits(compiles, v1 >= v2));
+ v1 = v1 == v2;
+ v1 = v1 != v2;
+ v1 = v1 < v2;
+ v1 = v1 > v2;
+ v1 = v1 <= v2;
+ v1 = v1 >= v2;
static assert(!__traits(compiles, v1 << 1));
static assert(!__traits(compiles, v1 >> 1));
static assert(!__traits(compiles, v1 >>> 1));
diff --git a/gcc/testsuite/gdc.dg/torture/imports/pr108055conv.d b/gcc/testsuite/gdc.dg/torture/imports/pr108055conv.d
new file mode 100644
index 0000000..93ebba7
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/imports/pr108055conv.d
@@ -0,0 +1,26 @@
+module imports.pr108055conv;
+
+T toStr(T, S)(S src)
+{
+ static if (is(typeof(T.init[0]) E))
+ {
+ struct Appender
+ {
+ inout(E)[] data;
+ }
+
+ import imports.pr108055spec;
+ import imports.pr108055write;
+
+ auto w = Appender();
+ FormatSpec!E f;
+ formatValue(w, src, f);
+ return w.data;
+ }
+}
+
+T to(T, A)(A args)
+{
+ return toStr!T(args);
+}
+
diff --git a/gcc/testsuite/gdc.dg/torture/imports/pr108055spec.d b/gcc/testsuite/gdc.dg/torture/imports/pr108055spec.d
new file mode 100644
index 0000000..801c581
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/imports/pr108055spec.d
@@ -0,0 +1,18 @@
+module imports.pr108055spec;
+
+template Unqual(T : const U, U)
+{
+ alias Unqual = U;
+}
+
+template FormatSpec(Char)
+if (!is(Unqual!Char == Char))
+{
+ alias FormatSpec = FormatSpec!(Unqual!Char);
+}
+
+struct FormatSpec(Char)
+if (is(Unqual!Char == Char))
+{
+ const(Char)[] nested;
+}
diff --git a/gcc/testsuite/gdc.dg/torture/imports/pr108055write.d b/gcc/testsuite/gdc.dg/torture/imports/pr108055write.d
new file mode 100644
index 0000000..fe41d7b
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/imports/pr108055write.d
@@ -0,0 +1,19 @@
+module imports.pr108055write;
+import imports.pr108055spec;
+
+void formatValueImpl(Writer, T, Char)(ref Writer , const(T) ,
+ scope const ref FormatSpec!Char )
+{
+ T val;
+ char spec;
+
+ (ref val) @trusted {
+ return (cast(const char*) &val)[0 .. val.sizeof];
+ }(val);
+
+}
+
+void formatValue(Writer, T, Char)(Writer w, T val, Char f)
+{
+ formatValueImpl(w, val, f);
+}
diff --git a/gcc/testsuite/gdc.dg/torture/pr108055.d b/gcc/testsuite/gdc.dg/torture/pr108055.d
new file mode 100644
index 0000000..c4ffad2
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/pr108055.d
@@ -0,0 +1,12 @@
+// { dg-do link }
+// { dg-additional-files "imports/pr108055conv.d imports/pr108055spec.d imports/pr108055write.d" }
+// { dg-additional-options "-I[srcdir] -fno-druntime" }
+import imports.pr108055conv;
+
+extern(C) int main()
+{
+ float zis;
+ static if (is(typeof(to!string(&zis))))
+ to!string(&zis);
+ return 0;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/nogc.d b/gcc/testsuite/gdc.test/compilable/nogc.d
index 6ce5094..88cf122 100644
--- a/gcc/testsuite/gdc.test/compilable/nogc.d
+++ b/gcc/testsuite/gdc.test/compilable/nogc.d
@@ -40,7 +40,8 @@ void foo_compiles() {}
static assert(!__traits(compiles, delete p));
int[int] aa;
- static assert(!__traits(compiles, aa[0]));
+ static assert( __traits(compiles, aa[0]));
+ static assert(!__traits(compiles, (aa[0] = 10)));
int[] a;
static assert(!__traits(compiles, a.length = 1));
diff --git a/gcc/testsuite/gdc.test/compilable/test15712.d b/gcc/testsuite/gdc.test/compilable/test15712.d
new file mode 100644
index 0000000..07321e5
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test15712.d
@@ -0,0 +1,12 @@
+// REQUIRED_ARGS: -unittest
+
+// https://issues.dlang.org/show_bug.cgi?id=15712
+// extern(C) attribute inside extern(C) unittest is incorrectly ignored
+
+extern(C):
+
+unittest
+{
+ extern(C) static void foo() {}
+ static assert(__traits(getLinkage, foo) == "C");
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23431.d b/gcc/testsuite/gdc.test/compilable/test23431.d
new file mode 100644
index 0000000..8fafcb2
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23431.d
@@ -0,0 +1,14 @@
+// https://issues.dlang.org/show_bug.cgi?id=23431
+// REQUIRED_ARGS: -lowmem
+void test23431()
+{
+ int a;
+ try
+ {
+ throw new Exception("test1");
+ a++;
+ }
+ finally
+ {
+ }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23431_minimal.d b/gcc/testsuite/gdc.test/compilable/test23431_minimal.d
new file mode 100644
index 0000000..0293f12
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23431_minimal.d
@@ -0,0 +1,28 @@
+// https://issues.dlang.org/show_bug.cgi?id=23431
+// REQUIRED_ARGS: -lowmem
+module object;
+
+alias string = immutable(char)[];
+class Throwable { }
+class Exception : Throwable
+{
+ this(string )
+ {
+ }
+}
+
+class Error { }
+
+void test23431()
+{
+ int a;
+
+ try
+ {
+ throw new Exception("test1");
+ a++;
+ }
+ finally
+ {
+ }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23433.d b/gcc/testsuite/gdc.test/compilable/test23433.d
new file mode 100644
index 0000000..713267c
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23433.d
@@ -0,0 +1,16 @@
+// https://issues.dlang.org/show_bug.cgi?id=23433
+module object;
+
+class Throwable { }
+class Exception : Throwable { this(immutable(char)[]) { } }
+
+void test23433()
+{
+ try
+ {
+ throw new Exception("ice");
+ }
+ finally
+ {
+ }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23439.d b/gcc/testsuite/gdc.test/compilable/test23439.d
new file mode 100644
index 0000000..eba292c
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23439.d
@@ -0,0 +1,8 @@
+// https://issues.dlang.org/show_bug.cgi?id=23439
+// PERMUTE_ARGS: -lowmem
+class C23439
+{
+ noreturn f23439;
+}
+
+__gshared ice23439 = new C23439();
diff --git a/gcc/testsuite/gdc.test/compilable/test23534.d b/gcc/testsuite/gdc.test/compilable/test23534.d
new file mode 100644
index 0000000..f76a692
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23534.d
@@ -0,0 +1,6 @@
+// https://issues.dlang.org/show_bug.cgi?id=23534
+
+enum E { a = 1, b = 2 }
+
+// `E.a` is not 0
+static assert(!__traits(isZeroInit, E));
diff --git a/gcc/testsuite/gdc.test/compilable/test4375.d b/gcc/testsuite/gdc.test/compilable/test4375.d
index 2a132fb..d7753ca 100644
--- a/gcc/testsuite/gdc.test/compilable/test4375.d
+++ b/gcc/testsuite/gdc.test/compilable/test4375.d
@@ -202,7 +202,7 @@ label1:
assert(78);
else
assert(79);
- false; false
+ false;
)
if (true)
assert(80);
diff --git a/gcc/testsuite/gdc.test/compilable/vgc2.d b/gcc/testsuite/gdc.test/compilable/vgc2.d
index c895914..eeba627 100644
--- a/gcc/testsuite/gdc.test/compilable/vgc2.d
+++ b/gcc/testsuite/gdc.test/compilable/vgc2.d
@@ -93,8 +93,7 @@ void testAssocArray()
/*
TEST_OUTPUT:
---
-compilable/vgc2.d(102): vgc: indexing an associative array may cause a GC allocation
-compilable/vgc2.d(103): vgc: indexing an associative array may cause a GC allocation
+compilable/vgc2.d(101): vgc: assigning an associative array element may cause a GC allocation
---
*/
void testIndex(int[int] aa)
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag14818.d b/gcc/testsuite/gdc.test/fail_compilation/diag14818.d
index 660066a..f9b535a 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag14818.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag14818.d
@@ -1,11 +1,17 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag14818.d(34): Error: none of the overloads of `func` are callable using argument types `(string)`
-fail_compilation/diag14818.d(12): Candidate is: `diag14818.foo(int _param_0)`
-fail_compilation/diag14818.d(13): `diag14818.bar(double _param_0)`
-fail_compilation/diag14818.d(35): Error: overload alias `diag14818.X` does not match any template declaration
-fail_compilation/diag14818.d(36): Error: overloadset `diag14818.M` does not match any template declaration
+fail_compilation/diag14818.d(40): Error: none of the overloads of `func` are callable using argument types `(string)`
+fail_compilation/diag14818.d(18): Candidates are: `diag14818.foo(int _param_0)`
+fail_compilation/diag14818.d(19): `diag14818.bar(double _param_0)`
+fail_compilation/diag14818.d(41): Error: template instance `diag14818.X!string` does not match any template declaration
+fail_compilation/diag14818.d(41): Candidates are:
+fail_compilation/diag14818.d(24): Foo(T) if (is(T == int))
+fail_compilation/diag14818.d(25): Bar(T) if (is(T == double))
+fail_compilation/diag14818.d(42): Error: template instance `diag14818.Y!string` does not match any template declaration
+fail_compilation/diag14818.d(42): Candidates are:
+fail_compilation/diag14818.d(25): Bar(T) if (is(T == double))
+fail_compilation/diag14818.d(24): Foo(T) if (is(T == int))
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8101.d b/gcc/testsuite/gdc.test/fail_compilation/diag8101.d
index 301472c..9644fdd 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag8101.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag8101.d
@@ -2,7 +2,7 @@
TEST_OUTPUT:
---
fail_compilation/diag8101.d(57): Error: function `diag8101.f_0(int)` is not callable using argument types `()`
-fail_compilation/diag8101.d(57): too few arguments, expected `1`, got `0`
+fail_compilation/diag8101.d(57): too few arguments, expected 1, got 0
fail_compilation/diag8101.d(58): Error: none of the overloads of `f_1` are callable using argument types `()`
fail_compilation/diag8101.d(33): Candidates are: `diag8101.f_1(int)`
fail_compilation/diag8101.d(34): `diag8101.f_1(int, int)`
@@ -62,3 +62,6 @@ void main()
t_1();
t_2();
}
+
+// ignored
+deprecated void f_2(char);
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag_funclit.d b/gcc/testsuite/gdc.test/fail_compilation/diag_funclit.d
index 1279d7c..f00f91a 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag_funclit.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag_funclit.d
@@ -2,19 +2,19 @@
TEST_OUTPUT:
---
fail_compilation/diag_funclit.d(103): Error: function literal `__lambda1(x, y, z)` is not callable using argument types `()`
-fail_compilation/diag_funclit.d(103): too few arguments, expected `3`, got `0`
+fail_compilation/diag_funclit.d(103): too few arguments, expected 3, got 0
fail_compilation/diag_funclit.d(106): Error: function literal `__lambda2(x, y, z)` is not callable using argument types `(int, string, int, int)`
-fail_compilation/diag_funclit.d(106): too many arguments, expected `3`, got `4`
+fail_compilation/diag_funclit.d(106): too many arguments, expected 3, got 4
fail_compilation/diag_funclit.d(108): Error: function literal `__lambda3(x, y, string z = "Hello")` is not callable using argument types `(int, int, string, string)`
-fail_compilation/diag_funclit.d(108): too many arguments, expected `3`, got `4`
+fail_compilation/diag_funclit.d(108): too many arguments, expected 3, got 4
fail_compilation/diag_funclit.d(110): Error: function literal `__lambda4(x, y, string z = "Hello")` is not callable using argument types `(int)`
-fail_compilation/diag_funclit.d(110): too few arguments, expected `3`, got `1`
+fail_compilation/diag_funclit.d(110): too few arguments, expected 3, got 1
fail_compilation/diag_funclit.d(112): Error: function literal `__lambda5(x, y, z)` is not callable using argument types `(int)`
-fail_compilation/diag_funclit.d(112): too few arguments, expected `3`, got `1`
+fail_compilation/diag_funclit.d(112): too few arguments, expected 3, got 1
fail_compilation/diag_funclit.d(115): Error: function literal `__lambda6(x, y, ...)` is not callable using argument types `(int)`
-fail_compilation/diag_funclit.d(115): too few arguments, expected `2`, got `1`
+fail_compilation/diag_funclit.d(115): too few arguments, expected 2, got 1
fail_compilation/diag_funclit.d(117): Error: function literal `__lambda7(x, y, string z = "Hey", ...)` is not callable using argument types `(int)`
-fail_compilation/diag_funclit.d(117): too few arguments, expected `3`, got `1`
+fail_compilation/diag_funclit.d(117): too few arguments, expected 3, got 1
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diagin.d b/gcc/testsuite/gdc.test/fail_compilation/diagin.d
index 1418ced..0d1f8f1 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diagin.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diagin.d
@@ -3,7 +3,7 @@ PERMUTE_ARGS: -preview=in
TEST_OUTPUT:
---
fail_compilation/diagin.d(14): Error: function `diagin.foo(in int)` is not callable using argument types `()`
-fail_compilation/diagin.d(14): too few arguments, expected `1`, got `0`
+fail_compilation/diagin.d(14): too few arguments, expected 1, got 0
fail_compilation/diagin.d(16): Error: none of the overloads of template `diagin.foo1` are callable using argument types `!()(bool[])`
fail_compilation/diagin.d(20): Candidate is: `foo1(T)(in T v, string)`
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail12.d b/gcc/testsuite/gdc.test/fail_compilation/fail12.d
index d752d38..7b082ae 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail12.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail12.d
@@ -1,7 +1,9 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail12.d(17): Error: function `fail12.main.Foo!(y).abc` at fail_compilation/fail12.d(9) conflicts with function `fail12.main.Foo!(y).abc` at fail_compilation/fail12.d(9)
+fail_compilation/fail12.d(19): Error: `abc` matches conflicting symbols:
+fail_compilation/fail12.d(11): function `fail12.main.Foo!(y).abc`
+fail_compilation/fail12.d(11): function `fail12.main.Foo!(y).abc`
---
*/
template Foo(alias b)
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail15414.d b/gcc/testsuite/gdc.test/fail_compilation/fail15414.d
new file mode 100644
index 0000000..1fb6e23
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail15414.d
@@ -0,0 +1,21 @@
+// https://issues.dlang.org/show_bug.cgi?id=15414
+
+// REQUIRED_ARGS: -de
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail15414.d(20): Deprecation: `__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `fun`
+fail_compilation/fail15414.d(20): the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from
+---
+*/
+
+@("gigi")
+void fun() {}
+@("mimi")
+void fun(int) {}
+
+void main()
+{
+ auto t = __traits(getAttributes, fun);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail15616b.d b/gcc/testsuite/gdc.test/fail_compilation/fail15616b.d
index faad0f1..4b20968 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail15616b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail15616b.d
@@ -22,7 +22,6 @@ fail_compilation/fail15616b.d(26): `foo(T)(T a)`
`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
` > is(T == char)
` `~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
-fail_compilation/fail15616b.d(44): All possible candidates are marked as `deprecated` or `@disable`
Tip: not satisfied constraints are marked with `>`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail1900.d b/gcc/testsuite/gdc.test/fail_compilation/fail1900.d
index fd0d6ac..edc4630 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail1900.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail1900.d
@@ -30,7 +30,9 @@ void test1900a()
/*
TEST_OUTPUT:
---
-fail_compilation/fail1900.d(42): Error: template `imports.fail1900b.Bar(short n)` at fail_compilation/imports/fail1900b.d(2) conflicts with template `imports.fail1900a.Bar(int n)` at fail_compilation/imports/fail1900a.d(2)
+fail_compilation/fail1900.d(44): Error: `Bar` matches conflicting symbols:
+fail_compilation/imports/fail1900b.d(2): template `imports.fail1900b.Bar(short n)`
+fail_compilation/imports/fail1900a.d(2): template `imports.fail1900a.Bar(int n)`
---
*/
@@ -45,7 +47,9 @@ void test1900b()
/*
TEST_OUTPUT:
---
-fail_compilation/fail1900.d(66): Error: template `fail1900.Mix2b!().Baz(int x)` at fail_compilation/fail1900.d(58) conflicts with template `fail1900.Mix2a!().Baz(byte x)` at fail_compilation/fail1900.d(54)
+fail_compilation/fail1900.d(70): Error: `Baz` matches conflicting symbols:
+fail_compilation/fail1900.d(62): template `fail1900.Mix2b!().Baz(int x)`
+fail_compilation/fail1900.d(58): template `fail1900.Mix2a!().Baz(byte x)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22366.d b/gcc/testsuite/gdc.test/fail_compilation/fail22366.d
index 6960d5e..675ba83 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail22366.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22366.d
@@ -1,15 +1,33 @@
-// REQUIRED_ARGS: -dip1000
-
/*
+REQUIRED_ARGS: -preview=dip1000
TEST_OUTPUT:
---
-fail_compilation/fail22366.d(13): Error: scope variable `x` may not be copied into allocated memory
+fail_compilation/fail22366.d(22): Error: scope variable `s` may not be copied into allocated memory
+fail_compilation/fail22366.d(25): Error: scope variable `s` may not be copied into allocated memory
+fail_compilation/fail22366.d(26): Error: scope variable `s` may not be copied into allocated memory
+fail_compilation/fail22366.d(27): Error: scope variable `s` may not be copied into allocated memory
+fail_compilation/fail22366.d(28): Error: scope variable `s` may not be copied into allocated memory
+fail_compilation/fail22366.d(31): Error: scope variable `s` may not be copied into allocated memory
+fail_compilation/fail22366.d(32): Error: scope variable `s` may not be copied into allocated memory
---
*/
-int* fun(scope int* x) @safe
+// Test escaping scope variables through AA keys / values
+// https://issues.dlang.org/show_bug.cgi?id=22366
+// https://issues.dlang.org/show_bug.cgi?id=23531
+
+void fun(scope string s) @safe
{
- int*[int] aa;
- aa[0] = x; // should give an error
- return aa[0];
+ int[string] aa;
+ aa[s] ^^= 3;
+
+ string[string] saa;
+ saa[""] = s;
+ saa[""] ~= s;
+ saa[s] = "";
+ saa[s] ~= "";
+
+ string[string][string] snaa;
+ snaa[s][""] = "";
+ snaa[""][s] = "";
}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23439.d b/gcc/testsuite/gdc.test/fail_compilation/fail23439.d
new file mode 100644
index 0000000..b070e58
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23439.d
@@ -0,0 +1,13 @@
+// https://issues.dlang.org/show_bug.cgi?id=23439
+// PERMUTE_ARGS: -lowmem
+/* TEST_OUTPUT:
+---
+fail_compilation/fail23439.d(13): Error: variable `fail23439.ice23439` is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead.
+---
+*/
+class C23439
+{
+ noreturn f23439;
+}
+
+static ice23439 = new C23439();
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail320.d b/gcc/testsuite/gdc.test/fail_compilation/fail320.d
index 24020b4..31dd065 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail320.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail320.d
@@ -2,10 +2,15 @@
EXTRA_FILES: imports/fail320a.d imports/fail320b.d
TEST_OUTPUT:
---
-fail_compilation/fail320.d(11): Error: no overload matches for `foo`
+fail_compilation/fail320.d(16): Error: no overload matches for `foo("")`
+fail_compilation/fail320.d(16): Candidates are:
+fail_compilation/imports/fail320b.d(1): foo(T)(string)
+fail_compilation/imports/fail320b.d(2): foo(alias a)()
+fail_compilation/imports/fail320a.d(1): foo(int)
+fail_compilation/imports/fail320a.d(2): foo(bool)
---
*/
import imports.fail320a;
import imports.fail320b;
-void main() { foo(); }
+void main() { foo(""); }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail54.d b/gcc/testsuite/gdc.test/fail_compilation/fail54.d
index e52c533..e232523 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail54.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail54.d
@@ -1,7 +1,12 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail54.d(22): Error: incompatible types for `(0) == (Exception)`: cannot use `==` with types
+fail_compilation/fail54.d(27): Error: incompatible types for `(0) == (Exception)`: cannot use `==` with types
+fail_compilation/fail54.d(28): Error: incompatible types for `("") == (int)`: cannot use `==` with types
+fail_compilation/fail54.d(29): Error: incompatible types for `(true) == (int)`: cannot use `==` with types
+fail_compilation/fail54.d(29): while evaluating: `static assert(true == (int))`
+fail_compilation/fail54.d(30): Error: incompatible types for `(true) == (int[string])`: cannot use `==` with types
+fail_compilation/fail54.d(30): while evaluating: `static assert(true == (int[string]))`
---
*/
@@ -20,4 +25,7 @@ module dstress.nocompile.bug_mtype_507_C;
void test()
{
0 == Exception;
+ "" == int;
+ static assert(is(int) == int);
+ static assert(is(int[string]) == int[string]);
}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail99.d b/gcc/testsuite/gdc.test/fail_compilation/fail99.d
index e4cba95..a12fa3f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail99.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail99.d
@@ -2,7 +2,7 @@
TEST_OUTPUT:
---
fail_compilation/fail99.d(13): Error: delegate `dg(int)` is not callable using argument types `()`
-fail_compilation/fail99.d(13): too few arguments, expected `1`, got `0`
+fail_compilation/fail99.d(13): too few arguments, expected 1, got 0
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d b/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d
index e76a779..c3c735e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d
@@ -327,6 +327,7 @@ fail_compilation/fail_arrayop2.d(342): Error: array operation `[1] * 6` without
fail_compilation/fail_arrayop2.d(345): Error: array operation `[1] * 6` without destination memory not allowed
fail_compilation/fail_arrayop2.d(348): Error: array operation `[1] * 6` without destination memory not allowed
fail_compilation/fail_arrayop2.d(349): Error: array operation `[1] * 6` without destination memory not allowed
+fail_compilation/fail_arrayop2.d(350): Deprecation: `[1] * 6` has no effect
fail_compilation/fail_arrayop2.d(350): Error: array operation `[1] * 6` without destination memory not allowed
fail_compilation/fail_arrayop2.d(353): Error: array operation `[1] * 6` without destination memory not allowed
fail_compilation/fail_arrayop2.d(356): Error: array operation `[1] * 6` without destination memory not allowed
@@ -336,8 +337,7 @@ fail_compilation/fail_arrayop2.d(367): Error: `"uvt"[] - '\x01'` cannot be inter
---
*/
// Test all statements, which can take arrays as their operands.
-void test15407stmt()
-{
+void test15407stmt() {
// ExpStatement - exp
[1] * 6;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_pretty_errors.d b/gcc/testsuite/gdc.test/fail_compilation/fail_pretty_errors.d
index d25e8f7..e9533c0 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail_pretty_errors.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail_pretty_errors.d
@@ -2,16 +2,20 @@
REQUIRED_ARGS: -verrors=context
TEST_OUTPUT:
---
-fail_compilation/fail_pretty_errors.d(20): Error: undefined identifier `a`
+fail_compilation/fail_pretty_errors.d(24): Error: undefined identifier `a`
a = 1;
^
-fail_compilation/fail_pretty_errors.d-mixin-25(25): Error: undefined identifier `b`
-fail_compilation/fail_pretty_errors.d(30): Error: cannot implicitly convert expression `5` of type `int` to `string`
+fail_compilation/fail_pretty_errors.d-mixin-29(29): Error: undefined identifier `b`
+fail_compilation/fail_pretty_errors.d(34): Error: cannot implicitly convert expression `5` of type `int` to `string`
string x = 5;
^
-fail_compilation/fail_pretty_errors.d(35): Error: mixin `fail_pretty_errors.testMixin2.mixinTemplate!()` error instantiating
+fail_compilation/fail_pretty_errors.d(39): Error: mixin `fail_pretty_errors.testMixin2.mixinTemplate!()` error instantiating
mixin mixinTemplate;
^
+fail_compilation/fail_pretty_errors.d(45): Error: invalid array operation `"" + ""` (possible missing [])
+ auto x = ""+"";
+ ^
+fail_compilation/fail_pretty_errors.d(45): did you mean to concatenate (`"" ~ ""`) instead ?
---
*/
@@ -34,3 +38,9 @@ void testMixin2()
{
mixin mixinTemplate;
}
+
+void f()
+{
+ // check supplemental error doesn't show context
+ auto x = ""+"";
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice10922.d b/gcc/testsuite/gdc.test/fail_compilation/ice10922.d
index f3a7a57..e76d4ac 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice10922.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice10922.d
@@ -2,7 +2,7 @@
TEST_OUTPUT:
---
fail_compilation/ice10922.d(10): Error: function `ice10922.__lambda4(in uint n)` is not callable using argument types `()`
-fail_compilation/ice10922.d(10): too few arguments, expected `1`, got `0`
+fail_compilation/ice10922.d(10): too few arguments, expected 1, got 0
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice13459.d b/gcc/testsuite/gdc.test/fail_compilation/ice13459.d
index 2c42dd3..d34fc60 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice13459.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice13459.d
@@ -3,7 +3,7 @@ TEST_OUTPUT:
---
fail_compilation/ice13459.d(12): Error: undefined identifier `B`
fail_compilation/ice13459.d(18): Error: none of the overloads of `opSlice` are callable using argument types `(int, int)`
-fail_compilation/ice13459.d(11): Candidates are: `ice13459.A.opSlice()`
+fail_compilation/ice13459.d(11): Candidate is: `ice13459.A.opSlice()`
---
*/
struct A
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice9540.d b/gcc/testsuite/gdc.test/fail_compilation/ice9540.d
index ce70507..5276e83 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice9540.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice9540.d
@@ -2,7 +2,7 @@
TEST_OUTPUT:
---
fail_compilation/ice9540.d(35): Error: function `ice9540.A.test.AddFront!(this, f).AddFront.dg(int _param_0)` is not callable using argument types `()`
-fail_compilation/ice9540.d(35): too few arguments, expected `1`, got `0`
+fail_compilation/ice9540.d(35): too few arguments, expected 1, got 0
fail_compilation/ice9540.d(26): Error: template instance `ice9540.A.test.AddFront!(this, f)` error instantiating
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/fail320a.d b/gcc/testsuite/gdc.test/fail_compilation/imports/fail320a.d
index 91972ed..d9e700d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/imports/fail320a.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/fail320a.d
@@ -1 +1,2 @@
void foo(int) { }
+void foo(bool) { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/fail320b.d b/gcc/testsuite/gdc.test/fail_compilation/imports/fail320b.d
index 9efc51c..b65463f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/imports/fail320b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/fail320b.d
@@ -1 +1,2 @@
-void foo(T)(){}
+void foo(T)(string){}
+void foo(alias a)(){}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/lexer23465.d b/gcc/testsuite/gdc.test/fail_compilation/lexer23465.d
new file mode 100644
index 0000000..526b770
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/lexer23465.d
@@ -0,0 +1,21 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/lexer23465.d(19): Error: char 0x1f37a not allowed in identifier
+fail_compilation/lexer23465.d(19): Error: character 0x1f37a is not a valid token
+fail_compilation/lexer23465.d(20): Error: character '\' is not a valid token
+fail_compilation/lexer23465.d(21): Error: unterminated /+ +/ comment
+fail_compilation/lexer23465.d(22): Error: found `End of File` instead of array initializer
+fail_compilation/lexer23465.d(22): Error: semicolon needed to end declaration of `arr`, instead of `End of File`
+fail_compilation/lexer23465.d(17): `arr` declared here
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=23465
+// Invalid token error points to wrong line
+
+int[] arr = [
+ 0,
+ x🍺,
+ 3\,
+ 5, /+
diff --git a/gcc/testsuite/gdc.test/fail_compilation/misc1.d b/gcc/testsuite/gdc.test/fail_compilation/misc1.d
index 9a319eb..21d02cd 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/misc1.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/misc1.d
@@ -3,6 +3,11 @@ TEST_OUTPUT:
---
fail_compilation/misc1.d(108): Error: `5` has no effect
fail_compilation/misc1.d(109): Error: `1 + 2` has no effect
+fail_compilation/misc1.d(115): Deprecation: `1 * 1` has no effect
+fail_compilation/misc1.d(116): Deprecation: `__lambda3` has no effect
+fail_compilation/misc1.d(122): Deprecation: `false` has no effect
+fail_compilation/misc1.d(125): Deprecation: `*sp++` has no effect
+fail_compilation/misc1.d(126): Deprecation: `j` has no effect
---
*/
@@ -18,3 +23,20 @@ void issue12490()
5, hasSideEffect12490();
1 + 2, hasSideEffect12490();
}
+
+void issue23480()
+{
+ int j;
+ for({} j; 1*1) {}
+ for({j=2; int d = 3;} j+d<7; {j++; d++;}) {}
+ for (
+ if (true) // (o_O)
+ assert(78);
+ else
+ assert(79);
+ false; false
+ ) {}
+ // unnecessary deref
+ for (ubyte* sp; 0; *sp++) {}
+ for (;; j) {}
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/nogc2.d b/gcc/testsuite/gdc.test/fail_compilation/nogc2.d
index 2a3ea8a..9016dd9 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/nogc2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/nogc2.d
@@ -92,8 +92,7 @@ fail_compilation/nogc2.d(87): Error: associative array literal in `@nogc` functi
/*
TEST_OUTPUT:
---
-fail_compilation/nogc2.d(101): Error: indexing an associative array in `@nogc` function `nogc2.testIndex` may cause a GC allocation
-fail_compilation/nogc2.d(102): Error: indexing an associative array in `@nogc` function `nogc2.testIndex` may cause a GC allocation
+fail_compilation/nogc2.d(100): Error: assigning an associative array element in `@nogc` function `nogc2.testIndex` may cause a GC allocation
---
*/
@nogc void testIndex(int[int] aa)
diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope.d b/gcc/testsuite/gdc.test/fail_compilation/retscope.d
index ece6a8c..7bc5e96 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/retscope.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/retscope.d
@@ -454,7 +454,7 @@ fail_compilation/retscope.d(1311): Error: scope variable `u2` assigned to `ek` w
/*
TEST_OUTPUT:
---
-fail_compilation/retscope.d(1405): Error: reference to local variable `buf` assigned to non-scope parameter `__anonymous_param` calling `myprintf`
+fail_compilation/retscope.d(1405): Error: reference to local variable `buf` assigned to non-scope anonymous parameter calling `myprintf`
---
*/
@@ -472,7 +472,7 @@ fail_compilation/retscope.d(1405): Error: reference to local variable `buf` assi
/*
TEST_OUTPUT:
---
-fail_compilation/retscope.d(1509): Error: reference to stack allocated value returned by `(*fp15)()` assigned to non-scope parameter `__anonymous_param`
+fail_compilation/retscope.d(1509): Error: reference to stack allocated value returned by `(*fp15)()` assigned to non-scope anonymous parameter
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope2.d b/gcc/testsuite/gdc.test/fail_compilation/retscope2.d
index 1cb76d6..829fb6a 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/retscope2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/retscope2.d
@@ -86,8 +86,8 @@ fail_compilation/retscope2.d(504): Error: scope variable `c` may not be returned
/*
TEST_OUTPUT:
---
-fail_compilation/retscope2.d(604): Error: scope variable `_param_0` assigned to non-scope parameter `__anonymous_param` calling `foo600`
-fail_compilation/retscope2.d(604): Error: scope variable `_param_1` assigned to non-scope parameter `__anonymous_param` calling `foo600`
+fail_compilation/retscope2.d(604): Error: scope variable `_param_0` assigned to non-scope anonymous parameter calling `foo600`
+fail_compilation/retscope2.d(604): Error: scope variable `_param_1` assigned to non-scope anonymous parameter calling `foo600`
fail_compilation/retscope2.d(614): Error: template instance `retscope2.test600!(int*, int*)` error instantiating
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/templateoverload.d b/gcc/testsuite/gdc.test/fail_compilation/templateoverload.d
new file mode 100644
index 0000000..420e0b8
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/templateoverload.d
@@ -0,0 +1,22 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/templateoverload.d(17): Error: template instance `T!1` does not match any template declaration
+fail_compilation/templateoverload.d(17): Candidates are:
+fail_compilation/templateoverload.d(14): T(X)
+fail_compilation/templateoverload.d(15): T()
+fail_compilation/templateoverload.d(22): Error: template instance `V!int` does not match any template declaration
+fail_compilation/templateoverload.d(22): Candidates are:
+fail_compilation/templateoverload.d(19): V(int i)
+fail_compilation/templateoverload.d(20): V(T, alias a)
+---
+*/
+template T(X) {}
+template T() {}
+
+alias t = T!1;
+
+template V(int i) {}
+template V(T, alias a) {}
+
+alias v = V!int;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test19646.d b/gcc/testsuite/gdc.test/fail_compilation/test19646.d
index ee0b042..c9d0e08 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test19646.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test19646.d
@@ -1,11 +1,17 @@
/* TEST_OUTPUT:
---
fail_compilation/test19646.d(11): Error: cast from `const(int)*` to `int*` not allowed in safe code
+fail_compilation/test19646.d(17): Error: `@safe` variable `z` cannot be initialized by calling `@system` function `f`
---
https://issues.dlang.org/show_bug.cgi?id=19646
*/
@safe:
-
const x = 42;
int* y = cast(int*)&x;
+
+@system:
+
+@system int* f() { return cast(int*) 0xDEADBEEF; };
+
+@safe int* z = f();
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21008.d b/gcc/testsuite/gdc.test/fail_compilation/test21008.d
index 998cf17..641c802 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test21008.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21008.d
@@ -5,12 +5,12 @@ fail_compilation/test21008.d(110): Error: function `test21008.C.after` circular
fail_compilation/test21008.d(117): Error: need `this` for `toString` of type `string()`
fail_compilation/test21008.d(117): Error: need `this` for `toHash` of type `nothrow @trusted $?:32=uint|64=ulong$()`
fail_compilation/test21008.d(117): Error: function `object.Object.opCmp(Object o)` is not callable using argument types `()`
-fail_compilation/test21008.d(117): too few arguments, expected `1`, got `0`
+fail_compilation/test21008.d(117): too few arguments, expected 1, got 0
fail_compilation/test21008.d(117): Error: function `object.Object.opEquals(Object o)` is not callable using argument types `()`
-fail_compilation/test21008.d(117): too few arguments, expected `1`, got `0`
+fail_compilation/test21008.d(117): too few arguments, expected 1, got 0
fail_compilation/test21008.d(117): Error: `Monitor` has no effect
fail_compilation/test21008.d(117): Error: function `object.Object.factory(string classname)` is not callable using argument types `()`
-fail_compilation/test21008.d(117): too few arguments, expected `1`, got `0`
+fail_compilation/test21008.d(117): too few arguments, expected 1, got 0
fail_compilation/test21008.d(105): called from here: `handleMiddlewareAnnotation()`
fail_compilation/test21008.d(108): Error: class `test21008.C` no size because of forward reference
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21062.d b/gcc/testsuite/gdc.test/fail_compilation/test21062.d
new file mode 100644
index 0000000..5ab5307
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21062.d
@@ -0,0 +1,24 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test21062.d(16): Error: no identifier for declarator `bool`
+fail_compilation/test21062.d(16): `synchronized` is a keyword, perhaps append `_` to make it an identifier
+fail_compilation/test21062.d(17): Error: no identifier for declarator `ubyte*`
+fail_compilation/test21062.d(17): `out` is a keyword, perhaps append `_` to make it an identifier
+fail_compilation/test21062.d(21): Error: no identifier for declarator `uint`
+fail_compilation/test21062.d(21): `in` is a keyword, perhaps append `_` to make it an identifier
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=21062
+// Confusing error when using a keyword as an identifier for a declaration
+
+bool synchronized;
+ubyte* out;
+
+void main()
+{
+ foreach(uint in; [])
+ {
+ }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23491.d b/gcc/testsuite/gdc.test/fail_compilation/test23491.d
new file mode 100644
index 0000000..b66d8a8
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test23491.d
@@ -0,0 +1,19 @@
+/**
+REQUIRED_ARGS: -preview=dip1000
+TEST_OUTPUT:
+---
+fail_compilation/test23491.d(16): Error: reference to local variable `buffer` assigned to non-scope anonymous parameter
+fail_compilation/test23491.d(17): Error: reference to local variable `buffer` assigned to non-scope anonymous parameter calling `sinkF`
+fail_compilation/test23491.d(18): Error: reference to local variable `buffer` assigned to non-scope parameter `buf`
+---
+*/
+
+void sinkF(char[]) @safe;
+
+void toString(void delegate (char[]) @safe sink, void delegate(char[] buf) @safe sinkNamed) @safe
+{
+ char[20] buffer = void;
+ sink(buffer[]);
+ sinkF(buffer[]);
+ sinkNamed(buffer[]);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23536.d b/gcc/testsuite/gdc.test/fail_compilation/test23536.d
new file mode 100644
index 0000000..fa1740b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test23536.d
@@ -0,0 +1,19 @@
+/* TEST_OUTPUT:
+---
+fail_compilation/test23536.d(104): Error: function `test23536.S.nonctor` cannot be a non-static member function for `pragma(crt_constructor)`
+fail_compilation/test23536.d(106): Error: function `test23536.S.nondtor` cannot be a non-static member function for `pragma(crt_destructor)`
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=23536
+
+#line 100
+
+struct S
+{
+ int x;
+ extern (C) pragma(crt_constructor) void nonctor() { } // should not compile
+ extern (C) pragma(crt_constructor) static void stactor() { } // should compile
+ extern (C) pragma(crt_destructor) void nondtor() { } // should not compile
+ extern (C) pragma(crt_destructor) static void stadtor() { } // should compile
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/throwexp.d b/gcc/testsuite/gdc.test/fail_compilation/throwexp.d
new file mode 100644
index 0000000..b1216ce
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/throwexp.d
@@ -0,0 +1,12 @@
+/+ TEST_OUTPUT:
+---
+fail_compilation/throwexp.d(11): Error: to be thrown `ret()` must be non-null
+fail_compilation/throwexp.d(12): Error: to be thrown `null` must be non-null
+---
++/
+auto ret()
+{
+ return Exception.init;
+}
+enum y = throw ret();
+enum x = throw Exception.init;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/warn14905.d b/gcc/testsuite/gdc.test/fail_compilation/warn14905.d
deleted file mode 100644
index 55520ba..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/warn14905.d
+++ /dev/null
@@ -1,23 +0,0 @@
-// REQUIRED_ARGS: -o- -w
-
-/*
-TEST_OUTPUT:
----
-fail_compilation/warn14905.d(16): Warning: statement is not reachable in template instance warn14905.fun!"a".fun
-fail_compilation/warn14905.d(16): Warning: statement is not reachable in template instance warn14905.fun!"b".fun
-Error: warnings are treated as errors
- Use -wi if you wish to treat warnings only as informational.
----
-*/
-
-bool fun(string s)()
-{
- return true;
- return false;
-}
-
-void main()
-{
- cast(void)fun!"a";
- cast(void)fun!"b";
-}
diff --git a/gcc/testsuite/gdc.test/runnable/lexer.d b/gcc/testsuite/gdc.test/runnable/lexer.d
index 8975146..c6ca550 100644
--- a/gcc/testsuite/gdc.test/runnable/lexer.d
+++ b/gcc/testsuite/gdc.test/runnable/lexer.d
@@ -2,8 +2,8 @@
/*
TEST_OUTPUT:
---
-runnable/lexer.d(81): Deprecation: `version( <integer> )` is deprecated, use version identifiers instead
-runnable/lexer.d(82): Deprecation: `debug( <integer> )` is deprecated, use debug identifiers instead
+runnable/lexer.d(86): Deprecation: `version( <integer> )` is deprecated, use version identifiers instead
+runnable/lexer.d(87): Deprecation: `debug( <integer> )` is deprecated, use debug identifiers instead
---
*/
@@ -36,6 +36,11 @@ HERE";
//writefln("'%s'", s);
assert(s == "foo\n");
+ // https://issues.dlang.org/show_bug.cgi?id=19623
+ s = q"übel
+foo
+übel";
+ assert(s == "foo\n");
s = q{ foo(xxx) };
assert(s ==" foo(xxx) ");
diff --git a/gcc/testsuite/gdc.test/runnable/test21301.d b/gcc/testsuite/gdc.test/runnable/test21301.d
new file mode 100644
index 0000000..073fd63
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test21301.d
@@ -0,0 +1,116 @@
+/* RUN_OUTPUT:
+---
+int AAAA0000
+int AAAA0001
+int AAAA0002
+int AAAA0003
+float FFFF0004
+float FFFF0005
+float FFFF0006
+float FFFF0007
+float FFFF0008
+float FFFF0009
+float FFFF0010
+float FFFF0011
+float FFFF0012
+float FFFF0013
+float FFFF0014
+float FFFF0015
+int AAAA0016
+int AAAA0017
+int AAAA0018
+int AAAA0019
+int AAAA0020
+int AAAA0021
+---
+ */
+
+// https://issues.dlang.org/show_bug.cgi?id=21301
+
+//extern (C)
+void func(
+ int p0, int[3] p1, float[3] p2, float p3, float p4, float p5, float p6, float p7,
+ float p8, float p9, float p10, float p11, int p12, int[2] p13, int p14, int p15, int p16
+) {
+ print(p0);
+
+ print(p1[0]);
+ print(p1[1]);
+ print(p1[2]);
+
+ print(p2[0]);
+ print(p2[1]);
+ print(p2[2]);
+
+ print(p3);
+ print(p4);
+ print(p5);
+ print(p6);
+ print(p7);
+ print(p8);
+ print(p9);
+ print(p10);
+ print(p11);
+ print(p12);
+ print(p13[0]);
+ print(p13[1]);
+ print(p14);
+ print(p15);
+ print(p16);
+}
+
+static if (0)
+{
+void print(int x);
+void print(float x);
+}
+else
+{
+import core.stdc.stdio;
+
+union U
+{
+ int[22] i = [
+ 0xAAAA_0000,
+ 0xAAAA_0001,
+ 0xAAAA_0002,
+ 0xAAAA_0003,
+ 0xFFFF_0004,
+ 0xFFFF_0005,
+ 0xFFFF_0006,
+ 0xFFFF_0007,
+ 0xFFFF_0008,
+ 0xFFFF_0009,
+ 0xFFFF_0010,
+ 0xFFFF_0011,
+ 0xFFFF_0012,
+ 0xFFFF_0013,
+ 0xFFFF_0014,
+ 0xFFFF_0015,
+ 0xAAAA_0016,
+ 0xAAAA_0017,
+ 0xAAAA_0018,
+ 0xAAAA_0019,
+ 0xAAAA_0020,
+ 0xAAAA_0021,
+ ];
+
+ float[22] f;
+}
+
+void print(int x) { printf("int %08X\n", x); }
+void print(float x) { printf("float %08X\n", *(cast(int*) &x)); }
+
+int main()
+{
+ func(U.init.i[0],
+ [U.init.i[1], U.init.i[2], U.init.i[3]],
+ [U.init.f[4], U.init.f[5], U.init.f[6]],
+ U.init.f[7], U.init.f[8], U.init.f[9], U.init.f[10], U.init.f[11], U.init.f[12], U.init.f[13],
+ U.init.f[14], U.init.f[15], U.init.i[16],
+ [U.init.i[17], U.init.i[18]],
+ U.init.i[19], U.init.i[20], U.init.i[21]
+ );
+ return 0;
+}
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test21506.d b/gcc/testsuite/gdc.test/runnable/test21506.d
new file mode 100644
index 0000000..8f3394d
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test21506.d
@@ -0,0 +1,40 @@
+/* RUN_OUTPUT:
+---
+value: -5
+value: -5
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=21506
+
+import core.stdc.stdio;
+import core.stdc.stdarg;
+
+extern(C++)
+{
+
+void print(long a, va_list args){
+ vprintf("value: %d\n", args);
+}
+void proxy0(long a, long b, long c, long d, bool e, ...){
+ va_list ap;
+ va_start(ap, e);
+ print(a, ap);
+ va_end(ap);
+// print(a, _argptr);
+}
+void proxy1(long d, bool e, ...){
+ va_list ap;
+ va_start(ap, e);
+ print(d, ap);
+ va_end(ap);
+// print(d, _argptr);
+}
+
+}
+
+void main(){
+ int var = -5;
+ proxy0(1, 2, 3, 4, true, var);
+ proxy1(4, true, var);
+}
diff --git a/gcc/testsuite/gfortran.dg/PR94104a.f90 b/gcc/testsuite/gfortran.dg/PR94104a.f90
new file mode 100644
index 0000000..a1e578a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/PR94104a.f90
@@ -0,0 +1,29 @@
+! { dg-do compile }
+! { dg-options "-std=f2003" }
+!
+! PR fortran/94104
+!
+
+program diag_p
+ implicit none
+
+ integer, parameter :: n = 7
+
+ integer :: a(n)
+ integer, target :: b(n)
+
+ a = 1
+ print *, sumf(a) ! { dg-error "Actual argument for 'a' at .1. must be a pointer" }
+ print *, sumf(b) ! { dg-error "Fortran 2008: Non-pointer actual argument at .1. to pointer dummy 'a'" }
+
+contains
+
+ function sumf(a) result(s)
+ integer, pointer, intent(in) :: a(:)
+
+ integer :: s
+
+ s = sum(a)
+ end function sumf
+
+end program diag_p
diff --git a/gcc/testsuite/gfortran.dg/PR94104b.f90 b/gcc/testsuite/gfortran.dg/PR94104b.f90
new file mode 100644
index 0000000..ee7d640
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/PR94104b.f90
@@ -0,0 +1,29 @@
+! { dg-do compile }
+! { dg-options "-std=f2008" }
+!
+! PR fortran/94104
+!
+
+program diag_p
+ implicit none
+
+ integer, parameter :: n = 7
+
+ integer :: a(n)
+ integer, target :: b(n)
+
+ a = 1
+ print *, sumf(a) ! { dg-error "Actual argument for 'a' at .1. must be a pointer or a valid target" }
+ print *, sumf(b)
+
+contains
+
+ function sumf(a) result(s)
+ integer, pointer, intent(in) :: a(:)
+
+ integer :: s
+
+ s = sum(a)
+ end function sumf
+
+end program diag_p
diff --git a/gcc/testsuite/gfortran.dg/coarray/pr107441-caf.f90 b/gcc/testsuite/gfortran.dg/coarray/pr107441-caf.f90
new file mode 100644
index 0000000..23b2242
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray/pr107441-caf.f90
@@ -0,0 +1,27 @@
+! { dg-do run }
+!
+! PR fortran/107441
+! Check that with -fcoarray=lib, coarray metadata arguments are passed
+! in the right order to procedures.
+!
+! Contributed by M.Morin
+
+program p
+ integer :: ci[*]
+ ci = 17
+ call s(1, ci, "abcd")
+contains
+ subroutine s(ra, ca, c)
+ integer :: ra, ca[*]
+ character(*) :: c
+ ca[1] = 13
+ if (ra /= 1) stop 1
+ if (this_image() == 1) then
+ if (ca /= 13) stop 2
+ else
+ if (ca /= 17) stop 3
+ end if
+ if (len(c) /= 4) stop 4
+ if (c /= "abcd") stop 5
+ end subroutine s
+end program p
diff --git a/gcc/testsuite/gfortran.dg/contiguous_12.f90 b/gcc/testsuite/gfortran.dg/contiguous_12.f90
new file mode 100644
index 0000000..9c477a7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/contiguous_12.f90
@@ -0,0 +1,7 @@
+! { dg-do compile }
+! PR fortran/108025
+
+subroutine foo (x)
+ real, contiguous :: x(:)
+ contiguous :: x ! { dg-error "Duplicate CONTIGUOUS attribute" }
+end
diff --git a/gcc/testsuite/gfortran.dg/elemental_dependency_7.f90 b/gcc/testsuite/gfortran.dg/elemental_dependency_7.f90
new file mode 100644
index 0000000..ad45ea52
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/elemental_dependency_7.f90
@@ -0,0 +1,28 @@
+! { dg-do run }
+! PR fortran/107819 - ICE in gfc_check_argument_var_dependency
+! Contributed by G.Steinmetz
+!
+! Note: the testcase is considered non-conforming for m>1 due to aliasing
+
+program p
+ implicit none
+ integer, parameter :: m = 1
+ integer :: i
+ integer :: a(m) = [(-i,i=1,m)]
+ integer :: n(m) = [(i,i=m,1,-1)]
+ integer :: b(m)
+ b = a
+ call s (a(n), a) ! { dg-warning "might interfere with actual argument" }
+
+ ! Compare to separate application of subroutine in element order
+ do i = 1, size (b)
+ call s (b(n(i)), b(i))
+ end do
+ if (any (a /= b)) stop 1
+contains
+ elemental subroutine s (x, y)
+ integer, value :: x
+ integer, intent(out) :: y
+ y = x
+ end
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/copyprivate-1.f90 b/gcc/testsuite/gfortran.dg/gomp/copyprivate-1.f90
new file mode 100644
index 0000000..eb2c865
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/copyprivate-1.f90
@@ -0,0 +1,21 @@
+! based on pr59467.f90 but COPYPRIVATE on the directive
+! { dg-additional-options "-fdump-tree-original" }
+
+ FUNCTION t()
+ INTEGER :: a, b, t
+ a = 0
+ b = 0
+ t = b
+ b = 0
+ !$OMP PARALLEL REDUCTION(+:b)
+ !$OMP SINGLE COPYPRIVATE (b)
+ !$OMP ATOMIC WRITE
+ b = 6
+ !$OMP END SINGLE
+ !$OMP END PARALLEL
+ t = t + b
+ END FUNCTION
+
+! { dg-final { scan-tree-dump-times "#pragma omp parallel reduction\\(\\+:b\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp single copyprivate\\(b\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp atomic relaxed" 1 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/copyprivate-2.f90 b/gcc/testsuite/gfortran.dg/gomp/copyprivate-2.f90
new file mode 100644
index 0000000..130f371
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/copyprivate-2.f90
@@ -0,0 +1,97 @@
+ FUNCTION t()
+ INTEGER :: a, b, t
+ a = 0
+ t = b
+ b = 0
+ !$OMP PARALLEL REDUCTION(+:b)
+ !$OMP SINGLE COPYPRIVATE (b) NOWAIT ! { dg-error "NOWAIT clause must not be used with COPYPRIVATE clause" }
+ !$OMP ATOMIC WRITE
+ b = 6
+ !$OMP END SINGLE
+ !$OMP END PARALLEL
+ t = t + b
+ END FUNCTION
+
+ FUNCTION t2()
+ INTEGER :: a, b, t2
+ a = 0
+ t2 = b
+ b = 0
+ !$OMP PARALLEL REDUCTION(+:b)
+ !$OMP SINGLE NOWAIT COPYPRIVATE (b) ! { dg-error "NOWAIT clause must not be used with COPYPRIVATE clause" }
+ !$OMP ATOMIC WRITE
+ b = 6
+ !$OMP END SINGLE
+ !$OMP END PARALLEL
+ t2 = t2 + b
+ END FUNCTION
+
+ FUNCTION t3()
+ INTEGER :: a, b, t3
+ a = 0
+ t3 = b
+ b = 0
+ !$OMP PARALLEL REDUCTION(+:b)
+ !$OMP SINGLE COPYPRIVATE (b) ! { dg-error "NOWAIT clause must not be used with COPYPRIVATE clause" }
+ !$OMP ATOMIC WRITE
+ b = 6
+ !$OMP END SINGLE NOWAIT
+ !$OMP END PARALLEL
+ t3 = t3 + b
+ END FUNCTION
+
+ FUNCTION t4()
+ INTEGER :: a, b, t4
+ a = 0
+ t4 = b
+ b = 0
+ !$OMP PARALLEL REDUCTION(+:b)
+ !$OMP SINGLE
+ !$OMP ATOMIC WRITE
+ b = 6
+ !$OMP END SINGLE NOWAIT COPYPRIVATE (b) ! { dg-error "NOWAIT clause must not be used with COPYPRIVATE clause" }
+ !$OMP END PARALLEL
+ t4 = t4 + b
+ END FUNCTION
+
+ FUNCTION t5()
+ INTEGER :: a, b, t5
+ a = 0
+ t5 = b
+ b = 0
+ !$OMP PARALLEL REDUCTION(+:b)
+ !$OMP SINGLE
+ !$OMP ATOMIC WRITE
+ b = 6
+ !$OMP END SINGLE COPYPRIVATE (b) NOWAIT ! { dg-error "NOWAIT clause must not be used with COPYPRIVATE clause" }
+ !$OMP END PARALLEL
+ t5 = t5 + b
+ END FUNCTION
+
+ FUNCTION t6()
+ INTEGER :: a, b, t6
+ a = 0
+ t6 = b
+ b = 0
+ !$OMP PARALLEL REDUCTION(+:b)
+ !$OMP SINGLE NOWAIT
+ !$OMP ATOMIC WRITE
+ b = 6
+ !$OMP END SINGLE COPYPRIVATE (b) ! { dg-error "NOWAIT clause must not be used with COPYPRIVATE clause" }
+ !$OMP END PARALLEL
+ t6 = t6 + b
+ END FUNCTION
+
+ FUNCTION t7()
+ INTEGER :: a, b, t7
+ a = 0
+ t7 = b
+ b = 0
+ !$OMP PARALLEL REDUCTION(+:b)
+ !$OMP SINGLE COPYPRIVATE (b)
+ !$OMP ATOMIC WRITE
+ b = 7
+ !$OMP END SINGLE COPYPRIVATE (b) ! { dg-error "Symbol 'b' present on multiple clauses" }
+ !$OMP END PARALLEL
+ t7 = t7 + b
+ END FUNCTION
diff --git a/gcc/testsuite/gfortran.dg/gomp/defaultmap-4.f90 b/gcc/testsuite/gfortran.dg/gomp/defaultmap-4.f90
index 7b182b5..9081159 100644
--- a/gcc/testsuite/gfortran.dg/gomp/defaultmap-4.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/defaultmap-4.f90
@@ -141,5 +141,5 @@ end
! { dg-final { scan-tree-dump-times "map\\(to:\\.strxparr \\\[len:" 2 "gimple" } }
! { dg-final { scan-tree-dump-times "map\\(to:strxparr \\\[pointer set, len:" 2 "gimple" } }
! { dg-final { scan-tree-dump-times "map\\(to:\\.strxp \\\[len:" 2 "gimple" } }
-! { dg-final { scan-tree-dump-times "#pragma omp target num_teams\\(1\\) thread_limit\\(0\\) defaultmap\\(alloc\\)" 1 "gimple" } }
-! { dg-final { scan-tree-dump-times "#pragma omp target num_teams\\(1\\) thread_limit\\(0\\) defaultmap\\(alloc:scalar\\) defaultmap\\(to:aggregate\\) defaultmap\\(tofrom:allocatable\\) defaultmap\\(firstprivate:pointer\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target num_teams\\(-2\\) thread_limit\\(0\\) defaultmap\\(alloc\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target num_teams\\(-2\\) thread_limit\\(0\\) defaultmap\\(alloc:scalar\\) defaultmap\\(to:aggregate\\) defaultmap\\(tofrom:allocatable\\) defaultmap\\(firstprivate:pointer\\)" 1 "gimple" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/defaultmap-5.f90 b/gcc/testsuite/gfortran.dg/gomp/defaultmap-5.f90
index 1391274..91566ed 100644
--- a/gcc/testsuite/gfortran.dg/gomp/defaultmap-5.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/defaultmap-5.f90
@@ -141,5 +141,5 @@ end
! { dg-final { scan-tree-dump-times "map\\(to:strxparr \\\[pointer set, len:" 2 "gimple" } }
! { dg-final { scan-tree-dump-times "map\\(to:\\*strxp \\\[len:" 1 "gimple" } }
! { dg-final { scan-tree-dump-times "map\\(to:\\.strxp \\\[len:" 1 "gimple" } }
-! { dg-final { scan-tree-dump-times "#pragma omp target num_teams\\(1\\) thread_limit\\(0\\) defaultmap\\(to\\)" 1 "gimple" } }
-! { dg-final { scan-tree-dump-times "#pragma omp target num_teams\\(1\\) thread_limit\\(0\\) defaultmap\\(to:scalar\\) defaultmap\\(tofrom:aggregate\\) defaultmap\\(firstprivate:allocatable\\) defaultmap\\(default:pointer\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target num_teams\\(-2\\) thread_limit\\(0\\) defaultmap\\(to\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target num_teams\\(-2\\) thread_limit\\(0\\) defaultmap\\(to:scalar\\) defaultmap\\(tofrom:aggregate\\) defaultmap\\(firstprivate:allocatable\\) defaultmap\\(default:pointer\\)" 1 "gimple" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/defaultmap-6.f90 b/gcc/testsuite/gfortran.dg/gomp/defaultmap-6.f90
index 9a81d0f..867e41a 100644
--- a/gcc/testsuite/gfortran.dg/gomp/defaultmap-6.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/defaultmap-6.f90
@@ -101,4 +101,4 @@ end
! { dg-final { scan-tree-dump-times "map\\(to:\\.strxparr \\\[len:" 1 "gimple" } }
! { dg-final { scan-tree-dump-times "map\\(to:strxparr \\\[pointer set, len:" 1 "gimple" } }
! { dg-final { scan-tree-dump-times "map\\(to:\\.strxp \\\[len:" 1 "gimple" } }
-! { dg-final { scan-tree-dump-times "#pragma omp target num_teams\\(1\\) thread_limit\\(0\\) defaultmap\\(default\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target num_teams\\(-2\\) thread_limit\\(0\\) defaultmap\\(default\\)" 1 "gimple" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/nowait-2.f90 b/gcc/testsuite/gfortran.dg/gomp/nowait-2.f90
index d18459b..c688117 100644
--- a/gcc/testsuite/gfortran.dg/gomp/nowait-2.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/nowait-2.f90
@@ -154,162 +154,3 @@ end do
!$omp end target data
end
-
-! invalid nowait
-
-subroutine foo
-implicit none
-integer :: i, a(5)
-!$omp atomic write
-i = 5
-!$omp end atomic nowait ! { dg-error "Unexpected junk" }
-
-!$omp critical
-!$omp end critical nowait ! { dg-error "Unexpected junk" }
-
-!$omp distribute
-do i = 1, 5
-end do
-!$omp end distribute nowait ! { dg-error "Unexpected junk" }
-
-!$omp distribute parallel do
-do i = 1, 5
-end do
-!$omp end distribute parallel do nowait ! { dg-error "Unexpected junk" }
-
-!$omp distribute parallel do simd
-do i = 1, 5
-end do
-!$omp end distribute parallel do simd nowait ! { dg-error "Unexpected junk" }
-
-!$omp parallel sections
- !$omp section
- block; end block
-!$omp end parallel sections nowait ! { dg-error "Unexpected junk" }
-
-!$omp distribute simd
-do i = 1, 5
-end do
-!$omp end distribute simd nowait ! { dg-error "Unexpected junk" }
-
-!$omp masked
-!$omp end masked nowait ! { dg-error "Unexpected junk" }
-
-!$omp masked taskloop
-do i = 1, 5
-end do
-!$omp end masked taskloop nowait ! { dg-error "Unexpected junk" }
-
-!$omp masked taskloop simd
-do i = 1, 5
-end do
-!$omp end masked taskloop simd nowait ! { dg-error "Unexpected junk" }
-
-!$omp master
-!$omp end master nowait ! { dg-error "Unexpected junk" }
-
-!$omp master taskloop
-do i = 1, 5
-end do
-!$omp end master taskloop nowait ! { dg-error "Unexpected junk" }
-
-!$omp master taskloop simd
-do i = 1, 5
-end do
-!$omp end master taskloop simd nowait ! { dg-error "Unexpected junk" }
-
-!$omp ordered
-!$omp end ordered nowait ! { dg-error "Unexpected junk" }
-
-!$omp parallel
-!$omp end parallel nowait ! { dg-error "Unexpected junk" }
-
-!$omp parallel workshare
-a(:) = 5
-!$omp end parallel workshare nowait ! { dg-error "Unexpected junk" }
-
-!$omp parallel do
-do i = 1, 5
-end do
-!$omp end parallel do nowait ! { dg-error "Unexpected junk" }
-
-!$omp parallel do simd
-do i = 1, 5
-end do
-!$omp end parallel do simd nowait ! { dg-error "Unexpected junk" }
-
-!$omp parallel masked
-!$omp end parallel masked nowait ! { dg-error "Unexpected junk" }
-
-!$omp parallel masked taskloop
-do i = 1, 5
-end do
-!$omp end parallel masked taskloop nowait ! { dg-error "Unexpected junk" }
-
-!$omp parallel masked taskloop simd
-do i = 1, 5
-end do
-!$omp end parallel masked taskloop simd nowait ! { dg-error "Unexpected junk" }
-
-!$omp parallel master
-!$omp end parallel master nowait ! { dg-error "Unexpected junk" }
-
-!$omp parallel master taskloop
-do i = 1, 5
-end do
-!$omp end parallel master taskloop nowait ! { dg-error "Unexpected junk" }
-
-!$omp parallel master taskloop simd
-do i = 1, 5
-end do
-!$omp end parallel master taskloop simd nowait ! { dg-error "Unexpected junk" }
-
-!$omp simd
-do i = 1, 5
-end do
-!$omp end simd nowait ! { dg-error "Unexpected junk" }
-
-!$omp task
-!$omp end task nowait ! { dg-error "Unexpected junk" }
-
-!$omp taskgroup
-!$omp end taskgroup nowait ! { dg-error "Unexpected junk" }
-
-!$omp taskloop
-do i = 1, 5
-end do
-!$omp end taskloop nowait ! { dg-error "Unexpected junk" }
-
-!$omp taskloop simd
-do i = 1, 5
-end do
-!$omp end taskloop simd nowait ! { dg-error "Unexpected junk" }
-
-!$omp teams
-!$omp end teams nowait ! { dg-error "Unexpected junk" }
-
-!$omp teams distribute
-do i = 1, 5
-end do
-!$omp end teams distribute nowait ! { dg-error "Unexpected junk" }
-
-!$omp teams distribute parallel do
-do i = 1, 5
-end do
-!$omp end teams distribute parallel do nowait ! { dg-error "Unexpected junk" }
-
-!$omp teams distribute parallel do simd
-do i = 1, 5
-end do
-!$omp end teams distribute parallel do simd nowait ! { dg-error "Unexpected junk" }
-
-!$omp teams distribute simd
-do i = 1, 5
-end do
-!$omp end teams distribute simd nowait ! { dg-error "Unexpected junk" }
-
-!$omp target data map(tofrom:i)
-!$omp end target data nowait ! { dg-error "Unexpected junk" }
-
-end ! { dg-error "Unexpected END statement" }
-! { dg-prune-output "Unexpected end of file" }
diff --git a/gcc/testsuite/gfortran.dg/gomp/nowait-4.f90 b/gcc/testsuite/gfortran.dg/gomp/nowait-4.f90
new file mode 100644
index 0000000..bebb9d7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/nowait-4.f90
@@ -0,0 +1,158 @@
+! invalid nowait
+
+subroutine foo
+implicit none
+integer :: i, a(5)
+!$omp atomic write
+i = 5
+!$omp end atomic nowait ! { dg-error "Unexpected junk" }
+
+!$omp critical
+!$omp end critical nowait ! { dg-error "Unexpected junk" }
+
+!$omp distribute
+do i = 1, 5
+end do
+!$omp end distribute nowait ! { dg-error "Unexpected junk" }
+
+!$omp distribute parallel do
+do i = 1, 5
+end do
+!$omp end distribute parallel do nowait ! { dg-error "Unexpected junk" }
+
+!$omp distribute parallel do simd
+do i = 1, 5
+end do
+!$omp end distribute parallel do simd nowait ! { dg-error "Unexpected junk" }
+
+!$omp parallel sections
+ !$omp section
+ block; end block
+!$omp end parallel sections nowait ! { dg-error "Unexpected junk" }
+
+!$omp distribute simd
+do i = 1, 5
+end do
+!$omp end distribute simd nowait ! { dg-error "Unexpected junk" }
+
+!$omp masked
+!$omp end masked nowait ! { dg-error "Unexpected junk" }
+
+!$omp masked taskloop
+do i = 1, 5
+end do
+!$omp end masked taskloop nowait ! { dg-error "Unexpected junk" }
+
+!$omp masked taskloop simd
+do i = 1, 5
+end do
+!$omp end masked taskloop simd nowait ! { dg-error "Unexpected junk" }
+
+!$omp master
+!$omp end master nowait ! { dg-error "Unexpected junk" }
+
+!$omp master taskloop
+do i = 1, 5
+end do
+!$omp end master taskloop nowait ! { dg-error "Unexpected junk" }
+
+!$omp master taskloop simd
+do i = 1, 5
+end do
+!$omp end master taskloop simd nowait ! { dg-error "Unexpected junk" }
+
+!$omp ordered
+!$omp end ordered nowait ! { dg-error "Unexpected junk" }
+
+!$omp parallel
+!$omp end parallel nowait ! { dg-error "Unexpected junk" }
+
+!$omp parallel workshare
+a(:) = 5
+!$omp end parallel workshare nowait ! { dg-error "Unexpected junk" }
+
+!$omp parallel do
+do i = 1, 5
+end do
+!$omp end parallel do nowait ! { dg-error "Unexpected junk" }
+
+!$omp parallel do simd
+do i = 1, 5
+end do
+!$omp end parallel do simd nowait ! { dg-error "Unexpected junk" }
+
+!$omp parallel masked
+!$omp end parallel masked nowait ! { dg-error "Unexpected junk" }
+
+!$omp parallel masked taskloop
+do i = 1, 5
+end do
+!$omp end parallel masked taskloop nowait ! { dg-error "Unexpected junk" }
+
+!$omp parallel masked taskloop simd
+do i = 1, 5
+end do
+!$omp end parallel masked taskloop simd nowait ! { dg-error "Unexpected junk" }
+
+!$omp parallel master
+!$omp end parallel master nowait ! { dg-error "Unexpected junk" }
+
+!$omp parallel master taskloop
+do i = 1, 5
+end do
+!$omp end parallel master taskloop nowait ! { dg-error "Unexpected junk" }
+
+!$omp parallel master taskloop simd
+do i = 1, 5
+end do
+!$omp end parallel master taskloop simd nowait ! { dg-error "Unexpected junk" }
+
+!$omp simd
+do i = 1, 5
+end do
+!$omp end simd nowait ! { dg-error "Unexpected junk" }
+
+!$omp task
+!$omp end task nowait ! { dg-error "Unexpected junk" }
+
+!$omp taskgroup
+!$omp end taskgroup nowait ! { dg-error "Unexpected junk" }
+
+!$omp taskloop
+do i = 1, 5
+end do
+!$omp end taskloop nowait ! { dg-error "Unexpected junk" }
+
+!$omp taskloop simd
+do i = 1, 5
+end do
+!$omp end taskloop simd nowait ! { dg-error "Unexpected junk" }
+
+!$omp teams
+!$omp end teams nowait ! { dg-error "Unexpected junk" }
+
+!$omp teams distribute
+do i = 1, 5
+end do
+!$omp end teams distribute nowait ! { dg-error "Unexpected junk" }
+
+!$omp teams distribute parallel do
+do i = 1, 5
+end do
+!$omp end teams distribute parallel do nowait ! { dg-error "Unexpected junk" }
+
+!$omp teams distribute parallel do simd
+do i = 1, 5
+end do
+!$omp end teams distribute parallel do simd nowait ! { dg-error "Unexpected junk" }
+
+!$omp teams distribute simd
+do i = 1, 5
+end do
+!$omp end teams distribute simd nowait ! { dg-error "Unexpected junk" }
+
+!$omp target data map(tofrom:i)
+!$omp end target data nowait ! { dg-error "Unexpected junk" }
+
+end ! { dg-error "Unexpected END statement" }
+! { dg-prune-output "Unexpected end of file" }
diff --git a/gcc/testsuite/gfortran.dg/gomp/nowait-5.f90 b/gcc/testsuite/gfortran.dg/gomp/nowait-5.f90
new file mode 100644
index 0000000..c688117
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/nowait-5.f90
@@ -0,0 +1,156 @@
+! Cross check that it is accepted without nowait
+subroutine bar()
+implicit none
+integer :: i, a(5)
+!$omp atomic write
+i = 5
+!$omp end atomic
+
+!$omp critical
+!$omp end critical
+
+!$omp distribute
+do i = 1, 5
+end do
+!$omp end distribute
+
+!$omp distribute parallel do
+do i = 1, 5
+end do
+!$omp end distribute parallel do
+
+!$omp distribute parallel do simd
+do i = 1, 5
+end do
+!$omp end distribute parallel do simd
+
+!$omp distribute simd
+do i = 1, 5
+end do
+!$omp end distribute simd
+
+!$omp masked
+!$omp end masked
+
+!$omp masked taskloop
+do i = 1, 5
+end do
+!$omp end masked taskloop
+
+!$omp masked taskloop simd
+do i = 1, 5
+end do
+!$omp end masked taskloop simd
+
+!$omp master
+!$omp end master
+
+!$omp master taskloop
+do i = 1, 5
+end do
+!$omp end master taskloop
+
+!$omp master taskloop simd
+do i = 1, 5
+end do
+!$omp end master taskloop simd
+
+!$omp ordered
+!$omp end ordered
+
+!$omp parallel
+!$omp end parallel
+
+!$omp parallel workshare
+a(:) = 5
+!$omp end parallel workshare
+
+!$omp parallel do
+do i = 1, 5
+end do
+!$omp end parallel do
+
+!$omp parallel do simd
+do i = 1, 5
+end do
+!$omp end parallel do simd
+
+!$omp parallel sections
+ !$omp section
+ block; end block
+!$omp end parallel sections
+
+!$omp parallel masked
+!$omp end parallel masked
+
+!$omp parallel masked taskloop
+do i = 1, 5
+end do
+!$omp end parallel masked taskloop
+
+!$omp parallel masked taskloop simd
+do i = 1, 5
+end do
+!$omp end parallel masked taskloop simd
+
+!$omp parallel master
+!$omp end parallel master
+
+!$omp parallel master taskloop
+do i = 1, 5
+end do
+!$omp end parallel master taskloop
+
+!$omp parallel master taskloop simd
+do i = 1, 5
+end do
+!$omp end parallel master taskloop simd
+
+!$omp simd
+do i = 1, 5
+end do
+!$omp end simd
+
+!$omp task
+!$omp end task
+
+!$omp taskgroup
+!$omp end taskgroup
+
+!$omp taskloop
+do i = 1, 5
+end do
+!$omp end taskloop
+
+!$omp taskloop simd
+do i = 1, 5
+end do
+!$omp end taskloop simd
+
+!$omp teams
+!$omp end teams
+
+!$omp teams distribute
+do i = 1, 5
+end do
+!$omp end teams distribute
+
+!$omp teams distribute parallel do
+do i = 1, 5
+end do
+!$omp end teams distribute parallel do
+
+!$omp teams distribute parallel do simd
+do i = 1, 5
+end do
+!$omp end teams distribute parallel do simd
+
+!$omp teams distribute simd
+do i = 1, 5
+end do
+!$omp end teams distribute simd
+
+!$omp target data map(tofrom:i)
+!$omp end target data
+
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/nowait-6.f90 b/gcc/testsuite/gfortran.dg/gomp/nowait-6.f90
new file mode 100644
index 0000000..5fe7d38
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/nowait-6.f90
@@ -0,0 +1,158 @@
+! invalid nowait
+
+subroutine foo
+implicit none
+integer :: i, a(5)
+!$omp atomic write nowait ! { dg-error "Failed to match clause" }
+i = 5
+!$omp end atomic ! { dg-error "Unexpected ..OMP END " }
+
+!$omp critical nowait ! { dg-error "Failed to match clause" }
+!$omp end critical ! { dg-error "Unexpected ..OMP END " }
+
+!$omp distribute nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end distribute ! { dg-error "Unexpected ..OMP END " }
+
+!$omp distribute parallel do nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end distribute parallel do ! { dg-error "Unexpected ..OMP END " }
+
+!$omp distribute parallel do simd nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end distribute parallel do simd ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel sections nowait ! { dg-error "Failed to match clause" }
+ !$omp section ! { dg-error "Unexpected ..OMP SECTION statement" }
+ block; end block
+!$omp end parallel sections ! { dg-error "Unexpected ..OMP END " }
+
+!$omp distribute simd nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end distribute simd ! { dg-error "Unexpected ..OMP END " }
+
+!$omp masked nowait ! { dg-error "Failed to match clause" }
+!$omp end masked ! { dg-error "Unexpected ..OMP END " }
+
+!$omp masked taskloop nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end masked taskloop ! { dg-error "Unexpected ..OMP END " }
+
+!$omp masked taskloop simd nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end masked taskloop simd ! { dg-error "Unexpected ..OMP END " }
+
+!$omp master nowait ! { dg-error "Unexpected junk" }
+!$omp end master ! { dg-error "Unexpected ..OMP END " }
+
+!$omp master taskloop nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end master taskloop ! { dg-error "Unexpected ..OMP END " }
+
+!$omp master taskloop simd nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end master taskloop simd ! { dg-error "Unexpected ..OMP END " }
+
+!$omp ordered nowait ! { dg-error "Failed to match clause" }
+!$omp end ordered ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel nowait ! { dg-error "Failed to match clause" }
+!$omp end parallel ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel workshare nowait ! { dg-error "Failed to match clause" }
+a(:) = 5
+!$omp end parallel workshare ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel do nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end parallel do ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel do simd nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end parallel do simd ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel masked nowait ! { dg-error "Failed to match clause" }
+!$omp end parallel masked ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel masked taskloop nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end parallel masked taskloop ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel masked taskloop simd nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end parallel masked taskloop simd ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel master nowait ! { dg-error "Failed to match clause" }
+!$omp end parallel master ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel master taskloop nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end parallel master taskloop ! { dg-error "Unexpected ..OMP END " }
+
+!$omp parallel master taskloop simd nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end parallel master taskloop simd ! { dg-error "Unexpected ..OMP END " }
+
+!$omp simd nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end simd ! { dg-error "Unexpected ..OMP END " }
+
+!$omp task nowait ! { dg-error "Failed to match clause" }
+!$omp end task ! { dg-error "Unexpected ..OMP END " }
+
+!$omp taskgroup nowait ! { dg-error "Failed to match clause" }
+!$omp end taskgroup ! { dg-error "Unexpected ..OMP END " }
+
+!$omp taskloop nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end taskloop ! { dg-error "Unexpected ..OMP END " }
+
+!$omp taskloop simd nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end taskloop simd ! { dg-error "Unexpected ..OMP END " }
+
+!$omp teams nowait ! { dg-error "Failed to match clause" }
+!$omp end teams ! { dg-error "Unexpected ..OMP END " }
+
+!$omp teams distribute nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end teams distribute ! { dg-error "Unexpected ..OMP END " }
+
+!$omp teams distribute parallel do nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end teams distribute parallel do ! { dg-error "Unexpected ..OMP END " }
+
+!$omp teams distribute parallel do simd nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end teams distribute parallel do simd ! { dg-error "Unexpected ..OMP END " }
+
+!$omp teams distribute simd nowait ! { dg-error "Failed to match clause" }
+do i = 1, 5
+end do
+!$omp end teams distribute simd ! { dg-error "Unexpected ..OMP END " }
+
+!$omp target data map(tofrom:i) nowait ! { dg-error "Failed to match clause" }
+!$omp end target data ! { dg-error "Unexpected ..OMP END " }
+
+end
+! { dg-prune-output "Unexpected end of file" }
diff --git a/gcc/testsuite/gfortran.dg/gomp/nowait-7.f90 b/gcc/testsuite/gfortran.dg/gomp/nowait-7.f90
new file mode 100644
index 0000000..41ead2f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/nowait-7.f90
@@ -0,0 +1,118 @@
+! { dg-additional-options "-fdump-tree-original" }
+
+subroutine foo
+implicit none
+integer :: i, a(5)
+
+!$omp do nowait
+do i = 1, 5
+end do
+!$omp end do
+
+!$omp do simd nowait
+do i = 1, 5
+end do
+!$omp end do simd
+
+!$omp scope nowait
+!$omp end scope
+
+!$omp sections nowait
+ !$omp section
+ block; end block
+!$omp end sections
+
+!$omp single nowait
+!$omp end single
+
+!$omp target nowait
+!$omp end target
+
+!$omp target parallel nowait
+!$omp end target parallel
+
+!$omp target parallel do nowait
+do i = 1, 5
+end do
+!$omp end target parallel do
+
+!$omp target parallel do simd nowait
+do i = 1, 5
+end do
+!$omp end target parallel do simd
+
+!$omp target parallel loop nowait
+do i = 1, 5
+end do
+!$omp end target parallel loop
+
+!$omp target teams distribute parallel do nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute parallel do
+
+!$omp target teams distribute parallel do simd nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute parallel do simd
+
+!$omp target simd nowait
+do i = 1, 5
+end do
+!$omp end target simd
+
+!$omp target teams nowait
+!$omp end target teams
+
+!$omp target teams distribute nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute
+
+!$omp target teams distribute simd nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute simd
+
+!$omp target teams loop nowait
+do i = 1, 5
+end do
+!$omp end target teams loop
+
+!$omp workshare nowait
+A(:) = 5
+!$omp end workshare
+end
+
+! Note: internally, for '... parallel do ...', 'nowait' is always added
+! such that for 'omp end target parallel do nowait', 'nowait' is on both
+! 'target' as specified in the OpenMP spec and and on 'do' due to internal usage.
+
+! Expected with 'nowait'
+
+! { dg-final { scan-tree-dump-times "#pragma omp for nowait" 6 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp for schedule\\(static\\) nowait" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp sections nowait" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp single nowait" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target nowait" 12 "original" } }
+
+! Never:
+
+! { dg-final { scan-tree-dump-not "#pragma omp distribute\[^\n\r]*nowait" "original" } }
+! { dg-final { scan-tree-dump-not "#pragma omp loop\[^\n\r]*nowait" "original" } }
+! { dg-final { scan-tree-dump-not "#pragma omp parallel\[^\n\r]*nowait" "original" } }
+! { dg-final { scan-tree-dump-not "#pragma omp section\[^s\]\[^\n\r]*nowait" "original" } }
+! { dg-final { scan-tree-dump-not "#pragma omp simd\[^\n\r]*nowait" "original" } }
+! { dg-final { scan-tree-dump-not "#pragma omp teams\[^\n\r]*nowait" "original" } }
+
+! Sometimes or never with nowait:
+
+! { dg-final { scan-tree-dump-times "#pragma omp distribute\[\n\r]" 4 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp loop\[\n\r]" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel\[\n\r]" 6 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp section\[\n\r]" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\)\[\n\r]" 5 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp teams\[\n\r]" 6 "original" } }
+
+! { dg-final { scan-tree-dump-times "#pragma omp target\[\n\r]" 0 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp for\[\n\r]" 0 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/nowait-8.f90 b/gcc/testsuite/gfortran.dg/gomp/nowait-8.f90
new file mode 100644
index 0000000..5e666d1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/nowait-8.f90
@@ -0,0 +1,92 @@
+subroutine foo
+implicit none
+integer :: i, a(5)
+
+!$omp do nowait nowait ! { dg-error "Duplicated 'nowait' clause" }
+do i = 1, 5
+end do
+
+!$omp do
+do i = 1, 5
+end do
+!$omp do nowait nowait ! { dg-error "Duplicated 'nowait' clause" }
+
+!$omp do nowait
+do i = 1, 5
+end do
+!$omp end do nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp do simd nowait
+do i = 1, 5
+end do
+!$omp end do simd nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp scope nowait
+!$omp end scope nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp sections nowait
+ !$omp section
+ block; end block
+!$omp end sections nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp single nowait
+!$omp end single nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target nowait
+!$omp end target nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target parallel nowait
+!$omp end target parallel nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target parallel do nowait
+do i = 1, 5
+end do
+!$omp end target parallel do nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target parallel do simd nowait
+do i = 1, 5
+end do
+!$omp end target parallel do simd nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target parallel loop nowait
+do i = 1, 5
+end do
+!$omp end target parallel loop nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target teams distribute parallel do nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute parallel do nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target teams distribute parallel do simd nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute parallel do simd nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target simd nowait
+do i = 1, 5
+end do
+!$omp end target simd nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target teams nowait
+!$omp end target teams nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target teams distribute nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target teams distribute simd nowait
+do i = 1, 5
+end do
+!$omp end target teams distribute simd nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp target teams loop nowait
+do i = 1, 5
+end do
+!$omp end target teams loop nowait ! { dg-error "Duplicated NOWAIT clause" }
+
+!$omp workshare nowait
+A(:) = 5
+!$omp end workshare nowait ! { dg-error "Duplicated NOWAIT clause" }
+end
diff --git a/gcc/testsuite/gfortran.dg/graphite/pr107865.f90 b/gcc/testsuite/gfortran.dg/graphite/pr107865.f90
new file mode 100644
index 0000000..6bddb17
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/graphite/pr107865.f90
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! { dg-options "-O1 -floop-parallelize-all -ftree-parallelize-loops=2" }
+
+ SUBROUTINE FNC (F)
+
+ IMPLICIT REAL (A-H)
+ DIMENSION F(N)
+
+ DO I = 1, 6
+ DO J = 1, 6
+ IF (J .NE. I) THEN
+ F(I) = F(I) + 1
+ END IF
+ END DO
+ END DO
+
+ RETURN
+ END
diff --git a/gcc/testsuite/gfortran.dg/guality/guality.exp b/gcc/testsuite/gfortran.dg/guality/guality.exp
index 0375edf..86a966a 100644
--- a/gcc/testsuite/gfortran.dg/guality/guality.exp
+++ b/gcc/testsuite/gfortran.dg/guality/guality.exp
@@ -8,6 +8,10 @@ if { [istarget *-*-darwin*] } {
return
}
+if { [istarget hppa*-*-hpux*] } {
+ return
+}
+
if { [istarget "powerpc-ibm-aix*"] } {
set torture_execute_xfail "powerpc-ibm-aix*"
return
diff --git a/gcc/testsuite/gfortran.dg/merge_1.f90 b/gcc/testsuite/gfortran.dg/merge_1.f90
new file mode 100644
index 0000000..437b13a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/merge_1.f90
@@ -0,0 +1,57 @@
+! { dg-do run }
+! PR fortran/107874 - merge not using all its arguments
+! Contributed by John Harper
+
+program testmerge9
+ implicit none
+ integer :: i
+ logical :: x(2) = (/.true., .false./)
+ logical :: called(2)
+ logical :: y
+
+ ! At run-time all arguments shall be evaluated
+ do i = 1,2
+ called = .false.
+ y = merge (tstuff(), fstuff(), x(i))
+ print *, y
+ if (any (.not. called)) stop 1
+ end do
+
+ ! Compile-time simplification shall not drop non-constant args
+ called = .false.
+ y = merge (tstuff(),fstuff(),.true.)
+ print *, y
+ if (any (.not. called)) stop 2
+ called = .false.
+ y = merge (tstuff(),fstuff(),.false.)
+ print *, y
+ if (any (.not. called)) stop 3
+ called = .false.
+ y = merge (tstuff(),.false.,.true.)
+ print *, y
+ if (any (called .neqv. [.true.,.false.])) stop 4
+ called = .false.
+ y = merge (tstuff(),.false.,.false.)
+ print *, y
+ if (any (called .neqv. [.true.,.false.])) stop 5
+ called = .false.
+ y = merge (.true.,fstuff(),.true.)
+ print *, y
+ if (any (called .neqv. [.false.,.true.])) stop 6
+ called = .false.
+ y = merge (.true.,fstuff(),.false.)
+ print *, y
+ if (any (called .neqv. [.false.,.true.])) stop 7
+contains
+ logical function tstuff()
+ print *,'tstuff'
+ tstuff = .true.
+ called(1) = .true.
+ end function tstuff
+
+ logical function fstuff()
+ print *,'fstuff'
+ fstuff = .false.
+ called(2) = .true.
+ end function fstuff
+end program testmerge9
diff --git a/gcc/testsuite/gfortran.dg/merge_init_expr_2.f90 b/gcc/testsuite/gfortran.dg/merge_init_expr_2.f90
index c761a47..f4a8380 100644
--- a/gcc/testsuite/gfortran.dg/merge_init_expr_2.f90
+++ b/gcc/testsuite/gfortran.dg/merge_init_expr_2.f90
@@ -48,7 +48,8 @@ end module m2
subroutine test
- character(len=3) :: one, two, three
+ character(len=3) :: one, three
+ character(len=3), parameter :: two = "def"
logical, parameter :: true = .true.
three = merge (one, two, true)
end subroutine test
diff --git a/gcc/testsuite/gfortran.dg/null_actual_3.f90 b/gcc/testsuite/gfortran.dg/null_actual_3.f90
new file mode 100644
index 0000000..ea49f96
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/null_actual_3.f90
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! { dg-options "-fallow-argument-mismatch -w" }
+! PR fortran/107576
+! Contributed by G.Steinmetz
+
+program p
+ implicit none
+ interface
+ subroutine r(y)
+ integer, pointer :: y(:)
+ end subroutine r
+ end interface
+ integer, pointer :: z(:) => null()
+ call r(z)
+ call s(z)
+ call r(null(z))
+ call s(null(z)) ! { dg-error "requires an explicit interface" }
+end
diff --git a/gcc/testsuite/gfortran.dg/optional_absent_6.f90 b/gcc/testsuite/gfortran.dg/optional_absent_6.f90
new file mode 100644
index 0000000..b8abb069
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/optional_absent_6.f90
@@ -0,0 +1,60 @@
+! { dg-do run }
+! PR fortran/107441
+!
+! Test VALUE + OPTIONAL for integer/real/...
+! in the presence of non-optional character dummies
+
+program bugdemo
+ implicit none
+ character :: s = 'a'
+ integer :: t
+
+ t = testoptional(s)
+ call test2 (s)
+ call test3 (s)
+ call test4 (w='123',x=42)
+
+contains
+
+ function testoptional (w, x) result(t)
+ character, intent(in) :: w
+ integer, intent(in), value, optional :: x
+ integer :: t
+ print *, 'present(x) is', present(x)
+ t = 0
+ if (present (x)) stop 1
+ end function testoptional
+
+ subroutine test2 (w, x)
+ character, intent(in) :: w
+ integer, intent(in), value, optional :: x
+ print*, 'present(x) is', present(x)
+ if (present (x)) stop 2
+ end subroutine test2
+
+ subroutine test3 (w, x)
+ character, intent(in), optional :: w
+ integer, intent(in), value, optional :: x
+ print *, 'present(w) is', present(w)
+ print *, 'present(x) is', present(x)
+ if (.not. present (w)) stop 3
+ if (present (x)) stop 4
+ end subroutine test3
+
+ subroutine test4 (r, w, x)
+ real, value, optional :: r
+ character(*), intent(in), optional :: w
+ integer, value, optional :: x
+ print *, 'present(r) is', present(r)
+ print *, 'present(w) is', present(w)
+ print *, 'present(x) is', present(x)
+ if (present (r)) stop 5
+ if (.not. present (w)) stop 6
+ if (.not. present (x)) stop 7
+ print *, 'x=', x
+ print *, 'len(w)=', len(w)
+ if (len(w) /= 3) stop 8
+ if (x /= 42) stop 9
+ end subroutine test4
+
+end program bugdemo
diff --git a/gcc/testsuite/gfortran.dg/optional_absent_7.f90 b/gcc/testsuite/gfortran.dg/optional_absent_7.f90
new file mode 100644
index 0000000..163d0b6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/optional_absent_7.f90
@@ -0,0 +1,31 @@
+! { dg-do run }
+! { dg-additional-options "-fdump-tree-original" }
+!
+! PR fortran/107441
+! Check that procedure types and procedure decls match when the procedure
+! has both character-typed and optional value args.
+!
+! Contributed by M.Morin
+
+program p
+ interface
+ subroutine i(c, o)
+ character(*) :: c
+ integer, optional, value :: o
+ end subroutine i
+ end interface
+ procedure(i), pointer :: pp
+ pp => s
+ call pp("abcd")
+contains
+ subroutine s(c, o)
+ character(*) :: c
+ integer, optional, value :: o
+ if (present(o)) stop 1
+ if (len(c) /= 4) stop 2
+ if (c /= "abcd") stop 3
+ end subroutine s
+end program p
+
+! { dg-final { scan-tree-dump "void s .* c, .* o, logical.* \.o, integer.* _c" "original" } }
+! { dg-final { scan-tree-dump ", integer.*, logical.*, integer.* pp" "original" } }
diff --git a/gcc/testsuite/gfortran.dg/optional_absent_8.f90 b/gcc/testsuite/gfortran.dg/optional_absent_8.f90
new file mode 100644
index 0000000..e3c0445
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/optional_absent_8.f90
@@ -0,0 +1,53 @@
+! { dg-do run }
+! PR fortran/107444
+!
+! Check that procedures with optional arguments that have the value attribute
+! work for intrinsic types including character, and that the presence check
+! works.
+!
+! Co-contributed by M.Morin
+
+program p
+ implicit none
+ interface
+ subroutine i(c, o)
+ character(*) :: c
+ character(3), optional, value :: o
+ end subroutine i
+ end interface
+ procedure(i), pointer :: pp
+ call s([.false.,.false.,.false.], 0)
+ call s([.true., .false.,.false.], 10, i=7)
+ call s([.false.,.true. ,.false.], 20, c='abc')
+ call s([.false.,.false.,.true. ], 30, r=3.0)
+ pp => f
+ call pp ("abcd", "xyz")
+contains
+ subroutine s (expect,code,i,c,r)
+ logical, intent(in) :: expect(:)
+ integer, intent(in) :: code
+ integer , value, optional :: i
+ character(3), value, optional :: c
+ real , value, optional :: r
+ if (expect(1) .neqv. present (i)) stop 1+code
+ if (expect(2) .neqv. present (c)) stop 2+code
+ if (expect(3) .neqv. present (r)) stop 3+code
+ if (present (i)) then
+ if (i /= 7) stop 4+code
+ end if
+ if (present (c)) then
+ if (c /= "abc") stop 5+code
+ end if
+ if (present (r)) then
+ if (r /= 3.0) stop 6+code
+ end if
+ end subroutine s
+ subroutine f (c, o)
+ character(*) :: c
+ character(3), optional, value :: o
+ if (c /= "abcd") stop 41
+ if (len (c) /= 4) stop 42
+ if (.not. present (o)) stop 43
+ if (o /= "xyz") stop 44
+ end subroutine f
+end
diff --git a/gcc/testsuite/gfortran.dg/parens_2.f90 b/gcc/testsuite/gfortran.dg/parens_2.f90
index bc2acd8..dc5965d 100644
--- a/gcc/testsuite/gfortran.dg/parens_2.f90
+++ b/gcc/testsuite/gfortran.dg/parens_2.f90
@@ -2,7 +2,7 @@
! { dg-do compile }
! Originally contributed by Joost VandeVondele
INTEGER, POINTER :: I
-CALL S1((I)) ! { dg-error "Actual argument for .i. must be a pointer" }
+CALL S1((I)) ! { dg-error "Actual argument for .i. at .1. must be a pointer or a valid target" }
CONTAINS
SUBROUTINE S1(I)
INTEGER, POINTER ::I
diff --git a/gcc/testsuite/gfortran.dg/pr102180.f90 b/gcc/testsuite/gfortran.dg/pr102180.f90
new file mode 100644
index 0000000..cbf3e72
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr102180.f90
@@ -0,0 +1,19 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=lib" }
+! PR fortran/102180 - Improve checking of assumed size array spec
+
+subroutine s(x,y)
+ real :: x(0:*) ! legal
+ real :: y[0:*] ! legal
+end
+
+subroutine t(x,y)
+ real :: x(:*) ! { dg-error "A lower bound must precede colon" }
+ real :: y[:*] ! { dg-error "A lower bound must precede colon" }
+end
+
+subroutine u(x,y,z)
+ real :: x(2,*)
+ real :: y(2,2:*)
+ real :: z(2,:*) ! { dg-error "A lower bound must precede colon" }
+end
diff --git a/gcc/testsuite/gfortran.dg/pr106911.f90 b/gcc/testsuite/gfortran.dg/pr106911.f90
new file mode 100644
index 0000000..f3fe7f6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr106911.f90
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! PR fortran/106911 - ICE in gfc_convert_mpz_to_signed
+! Contributed by G.Steinmetz
+
+program p
+ implicit none
+ integer, parameter :: a = 10
+ integer, parameter :: b = 20
+ integer, parameter :: c = ishftc(1_1, a, b) ! { dg-error "must be less than or equal" }
+ integer, parameter :: d = ishftc(1_1, a, 0) ! { dg-error "must be positive" }
+ interface
+ subroutine s
+ import :: a, b
+ integer, parameter :: e = ishftc(1_1, a, b) ! { dg-error "must be less than or equal" }
+ integer, parameter :: f = ishftc(1_1, a, 0) ! { dg-error "must be positive" }
+ end
+ end interface
+end
diff --git a/gcc/testsuite/gfortran.dg/pr107559.f90 b/gcc/testsuite/gfortran.dg/pr107559.f90
new file mode 100644
index 0000000..714e236
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr107559.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! { dg-options "-std=f95" }
+! PR fortran/107559 - ICE in resolve_equivalence
+! Contributed by G.Steinmetz
+
+module m
+ implicit none
+ integer, protected :: a ! { dg-error "Fortran 2003: PROTECTED attribute" }
+ integer :: b
+ equivalence (a, b) ! { dg-error "has no IMPLICIT type" }
+end
diff --git a/gcc/testsuite/gfortran.dg/pr107577.f90 b/gcc/testsuite/gfortran.dg/pr107577.f90
new file mode 100644
index 0000000..94e6620
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr107577.f90
@@ -0,0 +1,13 @@
+! { dg-do compile }
+! PR fortran/107577 - ICE in find_array_spec
+! Contributed by G.Steinmetz
+
+program p
+ implicit none
+ associate (y => f(4)) ! { dg-error "has no IMPLICIT type" }
+ if (lbound (y, 1) /= 1) stop 1 ! { dg-error "Invalid array reference" }
+ if (y(1) /= 1) stop 2 ! { dg-error "Invalid array reference" }
+ end associate
+end
+
+! { dg-error "has no type" " " { target *-*-* } 7 }
diff --git a/gcc/testsuite/gfortran.dg/pr107679.f90 b/gcc/testsuite/gfortran.dg/pr107679.f90
new file mode 100644
index 0000000..33a52fb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr107679.f90
@@ -0,0 +1,9 @@
+! { dg-do compile }
+
+subroutine s1(x)
+ integer, intent(out) :: x
+end
+subroutine s2(z)
+ integer, value :: z
+ call s1(z)
+end
diff --git a/gcc/testsuite/gfortran.dg/pr107680.f90 b/gcc/testsuite/gfortran.dg/pr107680.f90
new file mode 100644
index 0000000..4ed431e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr107680.f90
@@ -0,0 +1,34 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+! PR fortran/107680 - ICE in arith_power
+! Contributed by G.Steinmetz
+
+program p
+ real, parameter :: x(*) = [real :: ([1])] ** 2.0
+ complex, parameter :: y(*) = [real :: ([1])] ** (2.0,1.0)
+ complex, parameter :: z(*) = [complex :: ([1])] ** (2.0,1.0)
+ complex, parameter :: u(*) = [complex :: ([1.0])] ** (2.0,1.0)
+ complex, parameter :: v(*) = [real :: ([(1.0,2.0)])] ** (3.0,1.0)
+ complex, parameter :: w(*) = [integer :: ([(1.0,2.0)])] ** (3.0,1.0)
+ print *, [real :: ([3])] ** 2
+ print *, [real :: ([3])] ** 2.0
+ print *, [real :: ([1])] ** (1.0,2.0)
+ print *, [real :: ([1.0])] ** (1.0,2.0)
+ print *, [complex :: ([3])] ** 2
+ print *, [complex :: ([3])] ** 2.0
+ print *, [complex :: ([1])] ** (1.0,2.0)
+ print *, [complex :: ([1.0])] ** (1.0,2.0)
+ print *, [integer :: ([3.0])] ** 2
+ print *, [integer :: ([3.0])] ** 2.0
+ print *, [integer :: ([1.0])] ** (1.0,2.0)
+ print *, [integer :: ([(1.0,2.0)])] ** (3.0,1.0)
+ print *, v(1)
+ if (u(1) /= 1) stop 1
+ if (v(1) /= 1) stop 2
+ if (w(1) /= 1) stop 3
+ if (x(1) /= 1) stop 4
+ if (y(1) /= 1) stop 5
+ if (z(1) /= 1) stop 6
+end
+
+! { dg-final { scan-tree-dump-not "_gfortran_stop_numeric" "original" } }
diff --git a/gcc/testsuite/gfortran.dg/pr107681.f90 b/gcc/testsuite/gfortran.dg/pr107681.f90
new file mode 100644
index 0000000..0999ad9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr107681.f90
@@ -0,0 +1,13 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=lib" }
+! PR fortran/107681 - ICE in gfc_type_is_extensible
+! Contributed by G.Steinmetz
+
+program p
+ type t
+ integer, allocatable :: a
+ end type
+ class(t) :: x[*] ! { dg-error "must be dummy, allocatable or pointer" }
+ associate (y => x) ! { dg-error "Invalid array reference" }
+ end associate
+end
diff --git a/gcc/testsuite/gfortran.dg/pr107707.f90 b/gcc/testsuite/gfortran.dg/pr107707.f90
new file mode 100644
index 0000000..a8be2b5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr107707.f90
@@ -0,0 +1,13 @@
+! { dg-do compile }
+! PR fortran/107707 - ICE in gfc_compare_actual_formal
+! Contributed by G.Steinmetz
+
+program p
+ character(3), allocatable :: c
+ c = 'abc'
+ call s(c)
+contains
+ subroutine s(x)
+ character(real(3)), allocatable :: x ! { dg-error "must be of INTEGER type" }
+ end
+end
diff --git a/gcc/testsuite/gfortran.dg/pr107872.f90 b/gcc/testsuite/gfortran.dg/pr107872.f90
new file mode 100644
index 0000000..0983847
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr107872.f90
@@ -0,0 +1,40 @@
+! { dg-do run }
+!
+! Test the fix for PR107872, where an ICE occurred in
+! resolve.cc(derived_inaccessible) because derived types with
+! recursive allocatable components were not catered for.
+!
+module mod1
+ type t
+ integer :: data
+ type(t), allocatable :: next
+ contains
+ procedure, private :: write_t
+ generic :: write(formatted) => write_t
+ end type
+contains
+ recursive subroutine write_t(this, unit, iotype, v_list, iostat, iomsg)
+ class(t), intent(in) :: this
+ integer, intent(in) :: unit
+ character(*), intent(in) :: iotype
+ integer, intent(in) :: v_list(:)
+ integer, intent(out) :: iostat
+ character(*), intent(inout) :: iomsg
+ if (ALLOCATED(this%next)) &
+ write (unit, '(dt)') this%next
+ write (unit, '(i2)') this%data
+ end subroutine
+end module
+
+ use mod1
+ type(t) :: a
+ character (8) :: buffer
+ a%data = 1
+ allocate (a%next)
+ a%next%data = 2
+ allocate (a%next%next)
+ a%next%next%data = 3
+ write (buffer, '(dt)')a
+ deallocate (a%next)
+ if (trim (buffer) .ne. ' 3 2 1') stop 1
+end
diff --git a/gcc/testsuite/gfortran.dg/pr107899.f90 b/gcc/testsuite/gfortran.dg/pr107899.f90
new file mode 100644
index 0000000..e47b57b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr107899.f90
@@ -0,0 +1,13 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=single" }
+! PR fortran/107899 - ICE in resolve_deallocate_expr
+! Contributed by G.Steinmetz
+
+program p
+ type t
+ end type
+ class(t), target :: x[:] ! { dg-error "deferred shape" }
+ if (allocated (x)) then ! { dg-error "must be ALLOCATABLE" }
+ deallocate (x) ! { dg-error "must be ALLOCATABLE or a POINTER" }
+ end if
+end
diff --git a/gcc/testsuite/gfortran.dg/pr107995.f90 b/gcc/testsuite/gfortran.dg/pr107995.f90
new file mode 100644
index 0000000..22e8786
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr107995.f90
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! PR fortran/107995
+! Contributed by G.Steinmetz
+
+program p
+ implicit none
+ integer :: n ! { dg-error "Self-referential argument" }
+ n(n) = 1 ! { dg-warning "Statement function" }
+ print *, n(n) ! { dg-error "Statement function" }
+end
diff --git a/gcc/testsuite/gfortran.dg/pr108010.f90 b/gcc/testsuite/gfortran.dg/pr108010.f90
new file mode 100644
index 0000000..303b2b9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr108010.f90
@@ -0,0 +1,54 @@
+! { dg-do run }
+! PR fortran/108010 - ICE in reduce_unary, reduce_binary_aa
+! Contributed by G.Steinmetz
+
+program p
+ implicit none
+ print *, + [integer :: [real ::]]
+ print *, - [integer :: [real ::]]
+ print *, 1 + [integer :: [real ::]]
+ print *, 1 - [integer :: [real ::]]
+ print *, 2 * [integer :: [real ::]]
+ print *, - [real :: [real ::], 2]
+ print *, + [integer :: [real ::], 2]
+ print *, - [integer :: [real ::], 2]
+ print *, 1 + [integer :: [real ::], 2]
+ print *, 1 - [integer :: [real ::], 2]
+ print *, 2 * [integer :: [real ::], 2]
+ print *, [integer :: [real ::]] + [integer :: [real ::]]
+ print *, [integer :: [real ::]] - [integer :: [real ::]]
+ print *, [integer :: [real ::]] * [integer :: [real ::]]
+ print *, [integer :: [real ::], 2] + [real :: [real ::], 3]
+ print *, [integer :: [real ::], 2] - [real :: [real ::], 3]
+ print *, [integer :: [real ::], 2] * [real :: [real ::], 3]
+
+ ! Validate type of resulting arrays
+ if (.not. is_int ([integer :: [real ::]] )) stop 1
+ if (.not. is_int ([integer :: [real ::]] + [integer :: [real ::]])) stop 2
+ if (.not. is_real([real :: [integer ::]] )) stop 3
+ if (.not. is_real([real :: [integer ::]] + [real :: [integer ::]])) stop 4
+ if (.not. is_real([real :: [integer ::]] + [integer :: [real ::]])) stop 5
+ if (.not. is_real([integer :: [real ::]] + [real :: [integer ::]])) stop 6
+
+contains
+
+ logical function is_int (x)
+ class(*) :: x(:)
+ select type (x)
+ type is (integer)
+ is_int = .true.
+ class default
+ is_int = .false.
+ end select
+ end function is_int
+
+ logical function is_real (x)
+ class(*) :: x(:)
+ select type (x)
+ type is (real)
+ is_real = .true.
+ class default
+ is_real = .false.
+ end select
+ end function is_real
+end
diff --git a/gcc/testsuite/gfortran.dg/unpack_field_1.f90 b/gcc/testsuite/gfortran.dg/unpack_field_1.f90
new file mode 100644
index 0000000..ca3cfbd
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/unpack_field_1.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! PR fortran/107922 - ICE in gfc_simplify_unpack
+! Test error recovery when shapes of FIELD and MASK do not match
+! Contributed by G.Steinmetz
+
+program p
+ integer, parameter :: a(2) = 1
+ integer, parameter :: d(3) = 1
+ logical, parameter :: mask(3) = [.false.,.true.,.false.]
+ integer, parameter :: b(2) = unpack(a,mask,a) ! { dg-error "must have identical shape" }
+ integer :: c(3) = unpack(a,[.false.,.true.,.false.],a) ! { dg-error "must have identical shape" }
+ print *, unpack(a,mask,a) ! { dg-error "must have identical shape" }
+ print *, unpack(a,mask,d) ! OK
+ print *, unpack(a,mask,3) ! OK
+end
diff --git a/gcc/testsuite/gfortran.dg/widechar_11.f90 b/gcc/testsuite/gfortran.dg/widechar_11.f90
new file mode 100644
index 0000000..02530fb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/widechar_11.f90
@@ -0,0 +1,51 @@
+! { dg-do run }
+! { dg-additional-options "-fdump-tree-original" }
+!
+! PR fortran/107508
+!
+use iso_c_binding
+implicit none
+character(len=:,kind=4), allocatable, target :: a4str(:), a4str2
+type(c_ptr) :: cptr, cptr2
+
+allocate(character(len=7,kind=4) :: a4str(-2:3))
+allocate(character(len=9,kind=4) :: a4str2)
+
+cptr = c_loc(a4str)
+cptr2 = c_loc(a4str2)
+
+if (len(a4str) /= 7) error stop
+if (lbound(a4str,1) /= -2) error stop
+if (ubound(a4str,1) /= 3) error stop
+if (len(a4str2) /= 9) error stop
+
+a4str = [4_"sf456aq", 4_"3dtzu24", 4_"_4fh7sm", 4_"=ff85s7", 4_"j=8af4d", 4_".,A%Fsz"]
+a4str2 = 4_"4f5g5f8a9"
+
+!print *, lbound(a4str), ubound(a4str) ! expected (-2:3) - actually: (1:6)
+
+if (len(a4str) /= 7) error stop
+if (lbound(a4str,1) /= -2) error stop
+if (ubound(a4str,1) /= 3) error stop
+if (len(a4str2) /= 9) error stop
+if (.not. c_associated (cptr, c_loc(a4str))) error stop
+if (.not. c_associated (cptr2, c_loc(a4str2))) error stop
+end
+
+! { dg-final { scan-tree-dump-times "__builtin_malloc" 4 "original" } }
+! { dg-final { scan-tree-dump-times "__builtin_realloc" 2 "original" } }
+
+! { dg-final { scan-tree-dump-times "a4str.data = __builtin_malloc \\(168\\);" 2 "original" } }
+! { dg-final { scan-tree-dump-times "a4str.data = __builtin_realloc \\(a4str.data, 168\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times "a4str2 = \\(character\\(kind=4\\)\\\[1:.a4str2\\\] \\*\\) __builtin_malloc \\(36\\);" 2 "original" } }
+! { dg-final { scan-tree-dump-times "a4str2 = \\(character\\(kind=4\\)\\\[1:.a4str2\\\] \\*\\) __builtin_realloc \\(\\(void \\*\\) a4str2, 36\\);" 1 "original" } }
+
+! Array: Assert, realloc-check assign string length (alloc + (realloc'ed) assignment):
+! { dg-final { scan-tree-dump-times "if \\(\[^\\n\\r\]*\\.a4str != 7\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "if \\(D\\.\[0-9\]+ != 28\\) goto L\\." 1 "original" } }
+! { dg-final { scan-tree-dump-times "\\.a4str = 7;" 2 "original" } }
+
+! Scalar: Assert, realloc-check assign string length (alloc + (realloc'ed) assignment):
+! { dg-final { scan-tree-dump-times "if \\(\[^\\n\\r\]*\\.a4str2 != 9\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "if \\(\\.a4str2 == 9\\) goto L\\." 1 "original" } }
+! { dg-final { scan-tree-dump-times "\\.a4str2 = 9;" 2 "original" } }
diff --git a/gcc/testsuite/gnat.dg/abstract1.adb b/gcc/testsuite/gnat.dg/abstract1.adb
index 97508fa..36f75e9 100644
--- a/gcc/testsuite/gnat.dg/abstract1.adb
+++ b/gcc/testsuite/gnat.dg/abstract1.adb
@@ -1,18 +1,20 @@
-- { dg-do compile }
+-- { dg-options "-gnatws" }
+
with Ada.Tags.Generic_Dispatching_Constructor; use Ada.Tags;
package body abstract1 is
-
+
function New_T (Stream : not null access Root_Stream_Type'Class)
return T'Class is
function Construct is
new Generic_Dispatching_Constructor (T, Root_Stream_Type'Class, Input);
E : constant String := String'Input (Stream);
I : constant Tag := Internal_Tag (E);
-
+
begin
return Construct (I, Stream);
end New_T;
-
+
function Input (Stream : not null access Root_Stream_Type'Class)
return IT is
begin
@@ -20,12 +22,12 @@ package body abstract1 is
Integer'Read (Stream, O.I);
end return;
end Input;
-
+
function Input (Stream : not null access Root_Stream_Type'Class)
return FT is
begin
return O : FT do
Float'Read (Stream, O.F);
- end return;
- end Input;
+ end return;
+ end Input;
end abstract1;
diff --git a/gcc/testsuite/gnat.dg/abstract1.ads b/gcc/testsuite/gnat.dg/abstract1.ads
index bad9ee6..de14d77 100644
--- a/gcc/testsuite/gnat.dg/abstract1.ads
+++ b/gcc/testsuite/gnat.dg/abstract1.ads
@@ -3,15 +3,15 @@ package abstract1 is
type T is abstract tagged limited null record;
function Input (Stream : not null access Root_Stream_Type'Class) return T
is abstract;
-
+
function New_T (Stream : not null access Root_Stream_Type'Class)
return T'Class;
-
+
type IT is limited new T with record
I : Integer;
end record;
function Input (Stream : not null access Root_Stream_Type'Class) return IT;
-
+
type FT is limited new T with record
F : Float;
end record;
diff --git a/gcc/testsuite/gnat.dg/machine_attr2.adb b/gcc/testsuite/gnat.dg/machine_attr2.adb
new file mode 100644
index 0000000..e98a69a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/machine_attr2.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile { target arm*-*-* } }
+-- { dg-options "-mcpu=cortex-m33 -mcmse" }
+
+package body Machine_Attr2 is
+
+ procedure Call (Proc : Non_Secure) is
+ begin
+ Proc.all;
+ end;
+
+ procedure Foo; -- { dg-warning "only applies to base type" }
+ pragma Machine_Attribute (Foo, "cmse_nonsecure_call");
+ procedure Foo is null;
+
+end Machine_Attr2;
diff --git a/gcc/testsuite/gnat.dg/machine_attr2.ads b/gcc/testsuite/gnat.dg/machine_attr2.ads
new file mode 100644
index 0000000..4eda09e
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/machine_attr2.ads
@@ -0,0 +1,8 @@
+package Machine_Attr2 is
+
+ type Non_Secure is access procedure;
+ pragma Machine_Attribute (Non_Secure, "cmse_nonsecure_call");
+
+ procedure Call (Proc : Non_Secure);
+
+end Machine_Attr2;
diff --git a/gcc/testsuite/gnat.dg/opt100.adb b/gcc/testsuite/gnat.dg/opt100.adb
new file mode 100644
index 0000000..83270b6
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt100.adb
@@ -0,0 +1,13 @@
+-- { dg-do run }
+-- { dg-options "-O2 -gnatp" }
+
+with Opt100_Pkg; use Opt100_Pkg;
+
+procedure Opt100 is
+ R : constant Rec := (K => B, N => 1);
+
+begin
+ if Func (R) /= 1 then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/opt100_pkg.adb b/gcc/testsuite/gnat.dg/opt100_pkg.adb
new file mode 100644
index 0000000..42bf883
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt100_pkg.adb
@@ -0,0 +1,17 @@
+package body Opt100_Pkg is
+
+ function Func (R : Rec) return Integer is
+ begin
+ if R in Small_Rec then
+ case R.K is
+ when A => return 0;
+ when B => return 1;
+ when C => return 2;
+ when others => raise Program_Error;
+ end case;
+ else
+ return -1;
+ end if;
+ end;
+
+end Opt100_Pkg;
diff --git a/gcc/testsuite/gnat.dg/opt100_pkg.ads b/gcc/testsuite/gnat.dg/opt100_pkg.ads
new file mode 100644
index 0000000..a45f887
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt100_pkg.ads
@@ -0,0 +1,23 @@
+with Interfaces; use Interfaces;
+
+package Opt100_Pkg is
+
+ A : constant Unsigned_8 := 0;
+ B : constant Unsigned_8 := 1;
+ C : constant Unsigned_8 := 2;
+
+ subtype Small_Unsigned_8 is Unsigned_8 range A .. C;
+
+ type Rec is record
+ K : Unsigned_8;
+ N : Natural;
+ end record;
+
+ subtype Small_Rec is Rec
+ with Dynamic_Predicate =>
+ Small_Rec.K in Small_Unsigned_8 and
+ ((Small_Rec.N in Positive) = (Small_Rec.K in B | C));
+
+ function Func (R : Rec) return Integer;
+
+end Opt100_Pkg;
diff --git a/gcc/testsuite/gnat.dg/opt99.adb b/gcc/testsuite/gnat.dg/opt99.adb
new file mode 100644
index 0000000..8805d47
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt99.adb
@@ -0,0 +1,15 @@
+-- { dg-do run }
+-- { dg-options "-O" }
+
+with Opt99_Pkg1; use Opt99_Pkg1;
+
+procedure Opt99 is
+ C : constant My_Character := (D => True, C => ' ');
+ D : Derived;
+
+begin
+ Set (D, C, C);
+ if not D.C2.D then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/opt99_pkg1.adb b/gcc/testsuite/gnat.dg/opt99_pkg1.adb
new file mode 100644
index 0000000..476b09c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt99_pkg1.adb
@@ -0,0 +1,10 @@
+package body Opt99_Pkg1 is
+
+ procedure Set (D: in out Derived; C1, C2 : My_Character) is
+ begin
+ D.I := 0;
+ D.C1 := C1;
+ D.C2 := C2;
+ end;
+
+end Opt99_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/opt99_pkg1.ads b/gcc/testsuite/gnat.dg/opt99_pkg1.ads
new file mode 100644
index 0000000..3e26561
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt99_pkg1.ads
@@ -0,0 +1,19 @@
+with Opt99_Pkg2;
+
+package Opt99_Pkg1 is
+
+ type My_Character (D : Boolean := False) is record
+ case D is
+ when False => null;
+ when True => C : Character;
+ end case;
+ end record;
+
+ type Derived is new Opt99_Pkg2.Root with record
+ I : Integer;
+ C1, C2 : My_Character;
+ end record;
+
+ procedure Set (D: in out Derived; C1, C2 : My_Character);
+
+end Opt99_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/opt99_pkg2.ads b/gcc/testsuite/gnat.dg/opt99_pkg2.ads
new file mode 100644
index 0000000..09aaff1
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt99_pkg2.ads
@@ -0,0 +1,13 @@
+package Opt99_Pkg2 is
+
+ function Get_Max return Positive is (4);
+
+ C : constant Positive := Get_Max;
+
+ type Arr is array (1 .. C) of Integer;
+
+ type Root is tagged record
+ Data : Arr;
+ end record;
+
+end Opt99_Pkg2;
diff --git a/gcc/testsuite/gnat.dg/sso18.adb b/gcc/testsuite/gnat.dg/sso18.adb
new file mode 100644
index 0000000..7496e96
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/sso18.adb
@@ -0,0 +1,21 @@
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+with System;
+
+procedure SSO18 is
+
+ type Arr is array (1..32) of Short_Integer;
+ type Rev_Arr is array (1..32) of Short_Integer
+ with Scalar_Storage_Order => System.High_Order_First;
+ C : constant Arr := (others => 16);
+ RA : Rev_Arr;
+ A : Arr;
+
+begin
+ RA := Rev_Arr(C);
+ A := Arr (RA);
+ if A /= C or else RA(1) /= 16 then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/unchecked_convert9.adb b/gcc/testsuite/gnat.dg/unchecked_convert9.adb
index a01584f..5d12d62 100644
--- a/gcc/testsuite/gnat.dg/unchecked_convert9.adb
+++ b/gcc/testsuite/gnat.dg/unchecked_convert9.adb
@@ -11,4 +11,4 @@ package body Unchecked_Convert9 is
end Unchecked_Convert9;
--- { dg-final { scan-rtl-dump-times "set \\(mem/v" 1 "final" } }
+-- { dg-final { scan-rtl-dump-times "set \\(mem/v/c" 1 "final" } }
diff --git a/gcc/testsuite/jit.dg/harness.h b/gcc/testsuite/jit.dg/harness.h
index 7b70ce7..e423abe 100644
--- a/gcc/testsuite/jit.dg/harness.h
+++ b/gcc/testsuite/jit.dg/harness.h
@@ -68,6 +68,21 @@ static char test[1024];
} \
} while (0)
+#define CHECK_VECTOR_VALUE(LEN, ACTUAL, EXPECTED) \
+ do { \
+ for (int __check_vector_it = 0; __check_vector_it < LEN; ++__check_vector_it) { \
+ if ((ACTUAL)[__check_vector_it] != (EXPECTED)[__check_vector_it]) { \
+ fail ("%s: %s: actual: %s != expected: %s (position %d)", \
+ test, __func__, #ACTUAL, #EXPECTED, __check_vector_it); \
+ fprintf (stderr, "incorrect value\n"); \
+ abort (); \
+ } \
+ } \
+ pass ("%s: %s: actual: %s == expected: %s", \
+ test, __func__, #ACTUAL, #EXPECTED); \
+ } while (0)
+
+
#define CHECK_DOUBLE_VALUE(ACTUAL, EXPECTED) \
do { \
double expected = (EXPECTED); \
diff --git a/gcc/testsuite/jit.dg/test-expressions.c b/gcc/testsuite/jit.dg/test-expressions.c
index f9cc64f..13b3baf 100644
--- a/gcc/testsuite/jit.dg/test-expressions.c
+++ b/gcc/testsuite/jit.dg/test-expressions.c
@@ -383,15 +383,7 @@ make_test_of_comparison (gcc_jit_context *ctxt,
gcc_jit_param *param_b =
gcc_jit_context_new_param (ctxt, NULL, type, "b");
gcc_jit_param *params[] = {param_a, param_b};
- gcc_jit_type *bool_type =
- gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_BOOL);
- gcc_jit_function *test_fn =
- gcc_jit_context_new_function (ctxt, NULL,
- GCC_JIT_FUNCTION_EXPORTED,
- bool_type,
- funcname,
- 2, params,
- 0);
+
gcc_jit_rvalue *comparison =
gcc_jit_context_new_comparison (
ctxt,
@@ -400,6 +392,16 @@ make_test_of_comparison (gcc_jit_context *ctxt,
gcc_jit_param_as_rvalue (param_a),
gcc_jit_param_as_rvalue (param_b));
+ gcc_jit_type *comparison_type = gcc_jit_rvalue_get_type(comparison);
+
+ gcc_jit_function *test_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ comparison_type,
+ funcname,
+ 2, params,
+ 0);
+
gcc_jit_block *initial = gcc_jit_function_new_block (test_fn, "initial");
gcc_jit_block_end_with_return (initial, NULL, comparison);
@@ -407,48 +409,103 @@ make_test_of_comparison (gcc_jit_context *ctxt,
gcc_jit_rvalue_as_object (comparison));
}
-static void
-make_tests_of_comparisons (gcc_jit_context *ctxt)
+static void run_test_of_comparison(gcc_jit_context *ctxt,
+ gcc_jit_type *type,
+ enum gcc_jit_comparison op,
+ const char *funcname,
+ const char *vec_funcname,
+ const char *expected)
{
- gcc_jit_type *int_type =
- gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_type *vec_type =
+ gcc_jit_type_get_vector (type, 4);
CHECK_STRING_VALUE (
make_test_of_comparison (ctxt,
- int_type,
- GCC_JIT_COMPARISON_EQ,
- "test_COMPARISON_EQ_on_int"),
- "a == b");
- CHECK_STRING_VALUE (
- make_test_of_comparison (ctxt,
- int_type,
- GCC_JIT_COMPARISON_NE,
- "test_COMPARISON_NE_on_int"),
- "a != b");
- CHECK_STRING_VALUE (
- make_test_of_comparison (ctxt,
- int_type,
- GCC_JIT_COMPARISON_LT,
- "test_COMPARISON_LT_on_int"),
- "a < b");
+ type,
+ op,
+ funcname),
+ expected);
CHECK_STRING_VALUE (
make_test_of_comparison (ctxt,
- int_type,
- GCC_JIT_COMPARISON_LE,
- "test_COMPARISON_LE_on_int"),
- "a <= b");
- CHECK_STRING_VALUE (
- make_test_of_comparison (ctxt,
- int_type,
- GCC_JIT_COMPARISON_GT,
- "test_COMPARISON_GT_on_int"),
- "a > b");
- CHECK_STRING_VALUE (
- make_test_of_comparison (ctxt,
- int_type,
- GCC_JIT_COMPARISON_GE,
- "test_COMPARISON_GE_on_int"),
- "a >= b");
+ vec_type,
+ op,
+ vec_funcname),
+ expected);
+}
+
+static void
+make_tests_of_comparisons (gcc_jit_context *ctxt)
+{
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_type *float_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT);
+
+ run_test_of_comparison(
+ ctxt,
+ int_type,
+ GCC_JIT_COMPARISON_EQ,
+ "test_COMPARISON_EQ_on_int",
+ "test_COMPARISON_EQ_on_vec_int",
+ "a == b");
+ run_test_of_comparison(
+ ctxt,
+ int_type,
+ GCC_JIT_COMPARISON_NE,
+ "test_COMPARISON_NE_on_int",
+ "test_COMPARISON_NE_on_vec_int",
+ "a != b");
+ run_test_of_comparison(
+ ctxt,
+ int_type,
+ GCC_JIT_COMPARISON_LT,
+ "test_COMPARISON_LT_on_int",
+ "test_COMPARISON_LT_on_vec_int",
+ "a < b");
+ run_test_of_comparison(
+ ctxt,
+ int_type,
+ GCC_JIT_COMPARISON_LE,
+ "test_COMPARISON_LE_on_int",
+ "test_COMPARISON_LE_on_vec_int",
+ "a <= b");
+ run_test_of_comparison(
+ ctxt,
+ int_type,
+ GCC_JIT_COMPARISON_GT,
+ "test_COMPARISON_GT_on_int",
+ "test_COMPARISON_GT_on_vec_int",
+ "a > b");
+ run_test_of_comparison(
+ ctxt,
+ int_type,
+ GCC_JIT_COMPARISON_GE,
+ "test_COMPARISON_GE_on_int",
+ "test_COMPARISON_GE_on_vec_int",
+ "a >= b");
+
+ // Float tests
+ run_test_of_comparison(
+ ctxt,
+ float_type,
+ GCC_JIT_COMPARISON_NE,
+ "test_COMPARISON_NE_on_float",
+ "test_COMPARISON_NE_on_vec_float",
+ "a != b");
+ run_test_of_comparison(
+ ctxt,
+ float_type,
+ GCC_JIT_COMPARISON_LT,
+ "test_COMPARISON_LT_on_float",
+ "test_COMPARISON_LT_on_vec_float",
+ "a < b");
+ run_test_of_comparison(
+ ctxt,
+ float_type,
+ GCC_JIT_COMPARISON_GT,
+ "test_COMPARISON_GT_on_float",
+ "test_COMPARISON_GT_on_vec_float",
+ "a > b");
}
static void
@@ -502,6 +559,93 @@ verify_comparisons (gcc_jit_result *result)
CHECK_VALUE (test_COMPARISON_GE_on_int (0, 0), 1);
CHECK_VALUE (test_COMPARISON_GE_on_int (1, 2), 0);
CHECK_VALUE (test_COMPARISON_GE_on_int (2, 1), 1);
+
+ typedef int __vector __attribute__ ((__vector_size__ (sizeof(int) * 2)));
+ typedef __vector (*test_vec_fn) (__vector, __vector);
+
+ __vector zero_zero = {0, 0};
+ __vector zero_one = {0, 1};
+ __vector one_zero = {1, 0};
+
+ __vector true_true = {-1, -1};
+ __vector false_true = {0, -1};
+ __vector true_false = {-1, 0};
+ __vector false_false = {0, 0};
+
+ test_vec_fn test_COMPARISON_EQ_on_vec_int =
+ (test_vec_fn)gcc_jit_result_get_code (result,
+ "test_COMPARISON_EQ_on_vec_int");
+ CHECK_NON_NULL (test_COMPARISON_EQ_on_vec_int);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_EQ_on_vec_int (zero_zero, zero_zero), true_true);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_EQ_on_vec_int (zero_one, one_zero), false_false);
+
+ test_vec_fn test_COMPARISON_NE_on_vec_int =
+ (test_vec_fn)gcc_jit_result_get_code (result,
+ "test_COMPARISON_NE_on_vec_int");
+ CHECK_NON_NULL (test_COMPARISON_NE_on_vec_int);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_NE_on_vec_int (zero_zero, zero_zero), false_false);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_NE_on_vec_int (zero_one, one_zero), true_true);
+
+ test_vec_fn test_COMPARISON_LT_on_vec_int =
+ (test_vec_fn)gcc_jit_result_get_code (result,
+ "test_COMPARISON_LT_on_vec_int");
+ CHECK_NON_NULL (test_COMPARISON_LT_on_vec_int);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_LT_on_vec_int (zero_zero, zero_zero), false_false);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_LT_on_vec_int (zero_one, one_zero), true_false);
+
+ test_vec_fn test_COMPARISON_LE_on_vec_int =
+ (test_vec_fn)gcc_jit_result_get_code (result,
+ "test_COMPARISON_LE_on_vec_int");
+ CHECK_NON_NULL (test_COMPARISON_LE_on_vec_int);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_LE_on_vec_int (zero_zero, zero_zero), true_true);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_LE_on_vec_int (zero_one, one_zero), true_false);
+
+ test_vec_fn test_COMPARISON_GT_on_vec_int =
+ (test_vec_fn)gcc_jit_result_get_code (result,
+ "test_COMPARISON_GT_on_vec_int");
+ CHECK_NON_NULL (test_COMPARISON_GT_on_vec_int);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_GT_on_vec_int (zero_zero, zero_zero), false_false);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_GT_on_vec_int (zero_one, one_zero), false_true);
+
+ test_vec_fn test_COMPARISON_GE_on_vec_int =
+ (test_vec_fn)gcc_jit_result_get_code (result,
+ "test_COMPARISON_GE_on_vec_int");
+ CHECK_NON_NULL (test_COMPARISON_GE_on_vec_int);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_GE_on_vec_int (zero_zero, zero_zero), true_true);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_GE_on_vec_int (zero_one, one_zero), false_true);
+
+ typedef float __vector_f __attribute__ ((__vector_size__ (sizeof(float) * 2)));
+ typedef __vector (*test_vec_f_fn) (__vector_f, __vector_f);
+
+ __vector_f zero_zero_f = {0, 0};
+ __vector_f zero_one_f = {0, 1};
+ __vector_f one_zero_f = {1, 0};
+
+ __vector_f true_true_f = {-1, -1};
+ __vector_f false_true_f = {0, -1};
+ __vector_f true_false_f = {-1, 0};
+ __vector_f false_false_f = {0, 0};
+
+ test_vec_f_fn test_COMPARISON_NE_on_vec_float =
+ (test_vec_f_fn)gcc_jit_result_get_code (result,
+ "test_COMPARISON_NE_on_vec_float");
+ CHECK_NON_NULL (test_COMPARISON_NE_on_vec_float);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_NE_on_vec_float (zero_zero_f, zero_zero_f), false_false_f);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_NE_on_vec_float (zero_one_f, one_zero_f), true_true_f);
+
+ test_vec_f_fn test_COMPARISON_LT_on_vec_float =
+ (test_vec_f_fn)gcc_jit_result_get_code (result,
+ "test_COMPARISON_LT_on_vec_float");
+ CHECK_NON_NULL (test_COMPARISON_LT_on_vec_float);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_LT_on_vec_float (zero_zero_f, zero_zero_f), false_false_f);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_LT_on_vec_float (zero_one_f, one_zero_f), true_false_f);
+
+ test_vec_f_fn test_COMPARISON_GT_on_vec_float =
+ (test_vec_f_fn)gcc_jit_result_get_code (result,
+ "test_COMPARISON_GT_on_vec_float");
+ CHECK_NON_NULL (test_COMPARISON_GT_on_vec_float);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_GT_on_vec_float (zero_zero_f, zero_zero_f), false_false_f);
+ CHECK_VECTOR_VALUE (2, test_COMPARISON_GT_on_vec_float (zero_one_f, one_zero_f), false_true_f);
}
/**********************************************************************
diff --git a/gcc/testsuite/lib/g++.exp b/gcc/testsuite/lib/g++.exp
index 16e61fb..4e10b61 100644
--- a/gcc/testsuite/lib/g++.exp
+++ b/gcc/testsuite/lib/g++.exp
@@ -142,6 +142,10 @@ proc g++_link_flags { paths } {
append flags " -L${gccpath}/libstdc++-v3/src/.libs "
append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs"
}
+ if [file exists "${gccpath}/libstdc++-v3/src/experimental/.libs/libstdc++exp.a"] {
+ append flags " -L${gccpath}/libstdc++-v3/src/experimental/.libs "
+ append ld_library_path ":${gccpath}/libstdc++-v3/src/experimental/.libs"
+ }
if [file exists "${gccpath}/libiberty/libiberty.a"] {
append flags "-L${gccpath}/libiberty "
diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
index 23ec038..0129b11 100644
--- a/gcc/testsuite/lib/gcc-dg.exp
+++ b/gcc/testsuite/lib/gcc-dg.exp
@@ -1429,5 +1429,18 @@ proc scan-symbol-not { args } {
}
}
+# Transform a tool-name to its canonical-target-name by "transform"
+# (which may return the original name for native targets) but only if
+# testing out-of-tree. When in-tree, the tool is expected to be found
+# by its original name, typically with some build-directory prefix
+# prepended by the caller.
+proc gcc-transform-out-of-tree { args } {
+ global TESTING_IN_BUILD_TREE
+ if { [info exists TESTING_IN_BUILD_TREE] } {
+ return $args;
+ }
+ return [transform $args]
+}
+
set additional_prunes ""
set dg_runtest_extra_prunes ""
diff --git a/gcc/testsuite/lib/scanoffloadipa.exp b/gcc/testsuite/lib/scanoffloadipa.exp
new file mode 100644
index 0000000..615cbf4
--- /dev/null
+++ b/gcc/testsuite/lib/scanoffloadipa.exp
@@ -0,0 +1,148 @@
+# Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Various utilities for scanning offloading ipa dump output, used by
+# libgomp.exp.
+
+load_lib scandump.exp
+load_lib scanoffload.exp
+
+# Utility for scanning compiler result, invoked via dg-final.
+# Call pass if pattern is present, otherwise fail.
+#
+# Argument 0 is the regexp to match
+# Argument 1 is the name of the dumped ipa pass
+# Argument 2 handles expected failures and the like
+proc scan-offload-ipa-dump { args } {
+
+ if { [llength $args] < 2 } {
+ error "scan-offload-ipa-dump: too few arguments"
+ return
+ }
+ if { [llength $args] > 3 } {
+ error "scan-offload-ipa-dump: too many arguments"
+ return
+ }
+ if { [llength $args] >= 3 } {
+ scoff end-1 scan-dump "offload-ipa" [lindex $args 0] \
+ "\[0-9\]\[0-9\]\[0-9]i.[lindex $args 1]" "" \
+ [lindex $args 2]
+ } else {
+ scoff end scan-dump "offload-ipa" [lindex $args 0] \
+ "\[0-9\]\[0-9\]\[0-9]i.[lindex $args 1]" ""
+ }
+}
+
+# Call pass if pattern is present given number of times, otherwise fail.
+# Argument 0 is the regexp to match
+# Argument 1 is number of times the regexp must be found
+# Argument 2 is the name of the dumped ipa pass
+# Argument 3 handles expected failures and the like
+proc scan-offload-ipa-dump-times { args } {
+
+ if { [llength $args] < 3 } {
+ error "scan-offload-ipa-dump-times: too few arguments"
+ return
+ }
+ if { [llength $args] > 4 } {
+ error "scan-offload-ipa-dump-times: too many arguments"
+ return
+ }
+ if { [llength $args] >= 4 } {
+ scoff end-1 scan-dump-times "offload-ipa" [lindex $args 0] \
+ [lindex $args 1] "\[0-9\]\[0-9\]\[0-9]i.[lindex $args 2]" "" \
+ [lindex $args 3]
+ } else {
+ scoff end scan-dump-times "offload-ipa" [lindex $args 0] \
+ [lindex $args 1] "\[0-9\]\[0-9\]\[0-9]i.[lindex $args 2]" ""
+ }
+}
+
+# Call pass if pattern is not present, otherwise fail.
+#
+# Argument 0 is the regexp to match
+# Argument 1 is the name of the dumped ipa pass
+# Argument 2 handles expected failures and the like
+proc scan-offload-ipa-dump-not { args } {
+
+ if { [llength $args] < 2 } {
+ error "scan-offload-ipa-dump-not: too few arguments"
+ return
+ }
+ if { [llength $args] > 3 } {
+ error "scan-offload-ipa-dump-not: too many arguments"
+ return
+ }
+ if { [llength $args] >= 3 } {
+ scoff end-1 scan-dump-not "offload-ipa" [lindex $args 0] \
+ "\[0-9\]\[0-9\]\[0-9]i.[lindex $args 1]" "" \
+ [lindex $args 2]
+ } else {
+ scoff end scan-dump-not "offload-ipa" [lindex $args 0] \
+ "\[0-9\]\[0-9\]\[0-9]i.[lindex $args 1]" ""
+ }
+}
+
+# Utility for scanning demangled compiler result, invoked via dg-final.
+# Call pass if pattern is present, otherwise fail.
+#
+# Argument 0 is the regexp to match
+# Argument 1 is the name of the dumped ipa pass
+# Argument 2 handles expected failures and the like
+proc scan-offload-ipa-dump-dem { args } {
+
+ if { [llength $args] < 2 } {
+ error "scan-offload-ipa-dump-dem: too few arguments"
+ return
+ }
+ if { [llength $args] > 3 } {
+ error "scan-offload-ipa-dump-dem: too many arguments"
+ return
+ }
+ if { [llength $args] >= 3 } {
+ scoff end-1 scan-dump-dem "offload-ipa" [lindex $args 0] \
+ "\[0-9\]\[0-9\]\[0-9]i.[lindex $args 1]" "" \
+ [lindex $args 2]
+ } else {
+ scoff end scan-dump-dem "offload-ipa" [lindex $args 0] \
+ "\[0-9\]\[0-9\]\[0-9]i.[lindex $args 1]" ""
+ }
+}
+
+# Call pass if demangled pattern is not present, otherwise fail.
+#
+# Argument 0 is the regexp to match
+# Argument 1 is the name of the dumped ipa pass
+# Argument 2 handles expected failures and the like
+proc scan-offload-ipa-dump-dem-not { args } {
+
+ if { [llength $args] < 2 } {
+ error "scan-offload-ipa-dump-dem-not: too few arguments"
+ return
+ }
+ if { [llength $args] > 3 } {
+ error "scan-offload-ipa-dump-dem-not: too many arguments"
+ return
+ }
+ if { [llength $args] >= 3 } {
+ scoff end-1 scan-dump-dem-not "offload-ipa" [lindex $args 0] \
+ "\[0-9\]\[0-9\]\[0-9]i.[lindex $args 1]" "" \
+ [lindex $args 2]
+ } else {
+ scoff end scan-dump-dem-not "offload-ipa" [lindex $args 0] \
+ "\[0-9\]\[0-9\]\[0-9]i.[lindex $args 1]" ""
+ }
+}
diff --git a/gcc/testsuite/lib/target-supports-dg.exp b/gcc/testsuite/lib/target-supports-dg.exp
index aa2164b..6ce3b2b 100644
--- a/gcc/testsuite/lib/target-supports-dg.exp
+++ b/gcc/testsuite/lib/target-supports-dg.exp
@@ -683,3 +683,18 @@ proc dg-require-symver { args } {
set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
}
}
+
+# If this target does not provide prog named "$args", skip this test.
+
+proc dg-require-prog-name-available { args } {
+ # The args are within another list; pull them out.
+ set args [lindex $args 0]
+
+ set prog [lindex $args 1]
+
+ if { ![ check_is_prog_name_available $prog ] } {
+ upvar dg-do-what dg-do-what
+ set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
+ }
+}
+
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 750897d..2a058c6 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -1176,6 +1176,20 @@ proc check_effective_target_pthread {} {
} "-pthread"]
}
+# Return 1 if the target supports both Unix and internet sockets, 0 otherwise.
+proc check_effective_target_sockets {} {
+ return [check_no_compiler_messages socket executable {
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+int main (void) {
+ socket(AF_UNIX, SOCK_STREAM, 0);
+ socket(AF_INET, SOCK_DGRAM, 0);
+ return 0;
+}
+ } ""]
+}
+
# Return 1 if compilation with -mpe-aligned-commons is error-free
# for trivial code, 0 otherwise.
@@ -1329,10 +1343,10 @@ proc check_effective_target_pie { } {
# Return true if the target supports -mpaired-single (as used on MIPS).
-proc check_effective_target_mpaired_single { } {
+proc check_effective_target_mpaired_single { args } {
return [check_no_compiler_messages mpaired_single object {
void foo (void) { }
- } "-mpaired-single"]
+ } "$args"]
}
# Return true if the target has access to FPU instructions.
@@ -2144,7 +2158,7 @@ proc check_mips_msa_hw_available { } {
# executables, 0 otherwise.
proc check_effective_target_mpaired_single_runtime { } {
- if { [check_effective_target_mpaired_single]
+ if { [check_effective_target_mpaired_single "-mpaired-single"]
&& [check_mpaired_single_hw_available] } {
return 1
}
@@ -2154,7 +2168,7 @@ proc check_effective_target_mpaired_single_runtime { } {
# Return 1 if the target supports running Loongson executables, 0 otherwise.
proc check_effective_target_mips_loongson_mmi_runtime { } {
- if { [check_effective_target_mips_loongson_mmi]
+ if { [check_effective_target_mips_loongson_mmi "-mloongson-mmi"]
&& [check_mips_loongson_mmi_hw_available] } {
return 1
}
@@ -2164,7 +2178,7 @@ proc check_effective_target_mips_loongson_mmi_runtime { } {
# Return 1 if the target supports running MIPS MSA executables, 0 otherwise.
proc check_effective_target_mips_msa_runtime { } {
- if { [check_effective_target_mips_msa]
+ if { [check_effective_target_mips_msa "-mmsa"]
&& [check_mips_msa_hw_available] } {
return 1
}
@@ -6095,7 +6109,7 @@ proc check_effective_target_arm_acq_rel { } {
# Add the options needed for MIPS Paired-Single.
proc add_options_for_mpaired_single { flags } {
- if { ! [check_effective_target_mpaired_single] } {
+ if { ! [check_effective_target_mpaired_single "-mpaired-single"] } {
return "$flags"
}
return "$flags -mpaired-single"
@@ -6104,7 +6118,7 @@ proc add_options_for_mpaired_single { flags } {
# Add the options needed for MIPS SIMD Architecture.
proc add_options_for_mips_msa { flags } {
- if { ! [check_effective_target_mips_msa] } {
+ if { ! [check_effective_target_mips_msa "-mmsa"] } {
return "$flags"
}
return "$flags -mmsa"
@@ -6113,7 +6127,7 @@ proc add_options_for_mips_msa { flags } {
# Add the options needed for MIPS Loongson MMI Architecture.
proc add_options_for_mips_loongson_mmi { flags } {
- if { ! [check_effective_target_mips_loongson_mmi] } {
+ if { ! [check_effective_target_mips_loongson_mmi "-mloongson-mmi"] } {
return "$flags"
}
return "$flags -mloongson-mmi"
@@ -6123,7 +6137,7 @@ proc add_options_for_mips_loongson_mmi { flags } {
# Return 1 if this a Loongson-2E or -2F target using an ABI that supports
# the Loongson vector modes.
-proc check_effective_target_mips_loongson_mmi { } {
+proc check_effective_target_mips_loongson_mmi { args } {
return [check_no_compiler_messages loongson assembly {
#if !defined(__mips_loongson_mmi)
#error !__mips_loongson_mmi
@@ -6131,7 +6145,7 @@ proc check_effective_target_mips_loongson_mmi { } {
#if !defined(__mips_loongson_vector_rev)
#error !__mips_loongson_vector_rev
#endif
- }]
+ } "$args"]
}
# Return 1 if this is a MIPS target that supports the legacy NAN.
@@ -6145,7 +6159,7 @@ proc check_effective_target_mips_nanlegacy { } {
# Return 1 if an MSA program can be compiled to object
-proc check_effective_target_mips_msa { } {
+proc check_effective_target_mips_msa { args } {
if ![check_effective_target_nomips16] {
return 0
}
@@ -6171,7 +6185,7 @@ proc check_effective_target_mips_msa { } {
return v[0];
}
#endif
- } "-mmsa" ]
+ } "$args"]
}
# Return 1 if this is an ARM target that adheres to the ABI for the ARM
@@ -9049,11 +9063,16 @@ proc et-is-effective-target { target } {
global EFFECTIVE_TARGETS
global et_index
- if { [llength $EFFECTIVE_TARGETS] > $et_index
- && [lindex $EFFECTIVE_TARGETS $et_index] == $target } {
+ if { [info exists EFFECTIVE_TARGETS] } {
+ if { [llength $EFFECTIVE_TARGETS] > $et_index
+ && [lindex $EFFECTIVE_TARGETS $et_index] == $target } {
return 1
+ } else {
+ return 0
+ }
+ } else {
+ return [check_effective_target_${target}]
}
- return 0
}
# Return 1 if target default to short enums
@@ -9561,6 +9580,27 @@ proc check_effective_target_avxneconvert { } {
} "-O0 -mavxneconvert" ]
}
+# Return 1 if cmpccxadd instructions can be compiled.
+proc check_effective_target_cmpccxadd { } {
+ return [check_no_compiler_messages cmpccxadd object {
+ int _cmpccxadd_epi32 (int *__A, int __B, int __C, const int __D)
+ {
+ return (int)__builtin_ia32_cmpccxadd (__A, __B, __C, 1);
+ }
+ } "-mcmpccxadd" ]
+}
+
+# Return 1 if raoint instructions can be compiled.
+proc check_effective_target_raoint { } {
+ return [check_no_compiler_messages raoint object {
+ void
+ _aadd_si32 (int *__A, int __B)
+ {
+ return __builtin_ia32_aadd32((int *)__A, __B);
+ }
+ } "-mraoint" ]
+}
+
# Return 1 if sse instructions can be compiled.
proc check_effective_target_sse { } {
return [check_no_compiler_messages sse object {
@@ -10112,6 +10152,17 @@ proc check_effective_target_amx_bf16 { } {
} "-mamx-bf16" ]
}
+# Return 1 if amx-fp16 instructions can be compiled.
+proc check_effective_target_amx_fp16 { } {
+ return [check_no_compiler_messages amx_fp16 object {
+ void
+ foo ()
+ {
+ __asm__ volatile ("tdpfp16ps\t%%tmm1, %%tmm2, %%tmm3" ::);
+ }
+ } "-mamx-fp16" ]
+}
+
# Return 1 if vpclmulqdq instructions can be compiled.
proc check_effective_target_vpclmulqdq { } {
return [check_no_compiler_messages vpclmulqdq object {
@@ -10615,13 +10666,13 @@ proc check_vect_support_and_set_flags { } {
}
} elseif { [istarget mips*-*-*]
&& [check_effective_target_nomips16] } {
- if { [check_effective_target_mpaired_single] } {
+ if { [check_effective_target_mpaired_single "-mpaired-single"] } {
lappend EFFECTIVE_TARGETS mpaired_single
}
- if { [check_effective_target_mips_loongson_mmi] } {
+ if { [check_effective_target_mips_loongson_mmi "-mloongson-mmi"] } {
lappend EFFECTIVE_TARGETS mips_loongson_mmi
}
- if { [check_effective_target_mips_msa] } {
+ if { [check_effective_target_mips_msa "-mmsa"] } {
lappend EFFECTIVE_TARGETS mips_msa
}
return [llength $EFFECTIVE_TARGETS]
@@ -11506,7 +11557,8 @@ proc check_effective_target_supports_stack_clash_protection { } {
if { [istarget x86_64-*-*] || [istarget i?86-*-*]
|| [istarget powerpc*-*-*] || [istarget rs6000*-*-*]
- || [istarget aarch64*-**] || [istarget s390*-*-*] } {
+ || [istarget aarch64*-**] || [istarget s390*-*-*]
+ || [istarget loongarch64*-**] } {
return 1
}
return 0
@@ -11557,6 +11609,10 @@ proc check_effective_target_caller_implicit_probes { } {
return 1;
}
+ if { [istarget loongarch64*-*-*] } {
+ return 1;
+ }
+
return 0
}
@@ -12125,3 +12181,18 @@ main:
.byte 0
} ""]
}
+
+# Return 1 if this target has prog named "$prog", 0 otherwise.
+
+proc check_is_prog_name_available { prog } {
+ global tool
+
+ set options [list "additional_flags=-print-prog-name=$prog"]
+ set output [lindex [${tool}_target_compile "" "" "none" $options] 0]
+
+ if { $output == $prog } {
+ return 0
+ }
+
+ return 1
+}
diff --git a/gcc/tree-call-cdce.cc b/gcc/tree-call-cdce.cc
index b4b14a0..1a74eef 100644
--- a/gcc/tree-call-cdce.cc
+++ b/gcc/tree-call-cdce.cc
@@ -693,20 +693,31 @@ get_no_error_domain (enum built_in_function fnc)
{
/* Trig functions: return [-1, +1] */
CASE_FLT_FN (BUILT_IN_ACOS):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_ACOS):
CASE_FLT_FN (BUILT_IN_ASIN):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_ASIN):
return get_domain (-1, true, true,
1, true, true);
/* Hyperbolic functions. */
CASE_FLT_FN (BUILT_IN_ACOSH):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_ACOSH):
/* acosh: [1, +inf) */
return get_domain (1, true, true,
1, false, false);
CASE_FLT_FN (BUILT_IN_ATANH):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_ATANH):
/* atanh: (-1, +1) */
return get_domain (-1, true, false,
1, true, false);
+ case BUILT_IN_COSHF16:
+ case BUILT_IN_SINHF16:
+ /* coshf16: (-11, +11) */
+ return get_domain (-11, true, false,
+ 11, true, false);
case BUILT_IN_COSHF:
case BUILT_IN_SINHF:
+ case BUILT_IN_COSHF32:
+ case BUILT_IN_SINHF32:
/* coshf: (-89, +89) */
return get_domain (-89, true, false,
89, true, false);
@@ -714,21 +725,39 @@ get_no_error_domain (enum built_in_function fnc)
case BUILT_IN_SINH:
case BUILT_IN_COSHL:
case BUILT_IN_SINHL:
+ case BUILT_IN_COSHF64:
+ case BUILT_IN_SINHF64:
/* cosh: (-710, +710) */
return get_domain (-710, true, false,
710, true, false);
+ case BUILT_IN_COSHF128:
+ case BUILT_IN_SINHF128:
+ /* coshf128: (-11357, +11357) */
+ return get_domain (-11357, true, false,
+ 11357, true, false);
/* Log functions: (0, +inf) */
CASE_FLT_FN (BUILT_IN_LOG):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_LOG):
CASE_FLT_FN (BUILT_IN_LOG2):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_LOG2):
CASE_FLT_FN (BUILT_IN_LOG10):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_LOG10):
return get_domain (0, true, false,
0, false, false);
CASE_FLT_FN (BUILT_IN_LOG1P):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_LOG1P):
return get_domain (-1, true, false,
0, false, false);
/* Exp functions. */
+ case BUILT_IN_EXPF16:
+ case BUILT_IN_EXPM1F16:
+ /* expf: (-inf, 11) */
+ return get_domain (-1, false, false,
+ 11, true, false);
case BUILT_IN_EXPF:
case BUILT_IN_EXPM1F:
+ case BUILT_IN_EXPF32:
+ case BUILT_IN_EXPM1F32:
/* expf: (-inf, 88) */
return get_domain (-1, false, false,
88, true, false);
@@ -736,18 +765,35 @@ get_no_error_domain (enum built_in_function fnc)
case BUILT_IN_EXPM1:
case BUILT_IN_EXPL:
case BUILT_IN_EXPM1L:
+ case BUILT_IN_EXPF64:
+ case BUILT_IN_EXPM1F64:
/* exp: (-inf, 709) */
return get_domain (-1, false, false,
709, true, false);
+ case BUILT_IN_EXPF128:
+ case BUILT_IN_EXPM1F128:
+ /* expf128: (-inf, 11356) */
+ return get_domain (-1, false, false,
+ 11356, true, false);
+ case BUILT_IN_EXP2F16:
+ /* exp2f16: (-inf, 16) */
+ return get_domain (-1, false, false,
+ 16, true, false);
case BUILT_IN_EXP2F:
+ case BUILT_IN_EXP2F32:
/* exp2f: (-inf, 128) */
return get_domain (-1, false, false,
128, true, false);
case BUILT_IN_EXP2:
case BUILT_IN_EXP2L:
+ case BUILT_IN_EXP2F64:
/* exp2: (-inf, 1024) */
return get_domain (-1, false, false,
1024, true, false);
+ case BUILT_IN_EXP2F128:
+ /* exp2f128: (-inf, 16384) */
+ return get_domain (-1, false, false,
+ 16384, true, false);
case BUILT_IN_EXP10F:
case BUILT_IN_POW10F:
/* exp10f: (-inf, 38) */
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index d982988..0c409b4 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -4795,17 +4795,6 @@ verify_gimple_assign_single (gassign *stmt)
}
return res;
- case ASSERT_EXPR:
- /* FIXME. */
- rhs1 = fold (ASSERT_EXPR_COND (rhs1));
- if (rhs1 == boolean_false_node)
- {
- error ("%qs with an always-false condition", code_name);
- debug_generic_stmt (rhs1);
- return true;
- }
- break;
-
case WITH_SIZE_EXPR:
error ("%qs RHS in assignment statement",
get_tree_code_name (rhs_code));
@@ -7870,6 +7859,8 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
if (bb->loop_father->header == bb)
{
class loop *this_loop = bb->loop_father;
+ /* Avoid the need to remap SSA names used in nb_iterations. */
+ free_numbers_of_iterations_estimates (this_loop);
class loop *outer = loop_outer (this_loop);
if (outer == loop
/* If the SESE region contains some bbs ending with
diff --git a/gcc/tree-chrec.cc b/gcc/tree-chrec.cc
index 7321fb9..dcf26cb 100644
--- a/gcc/tree-chrec.cc
+++ b/gcc/tree-chrec.cc
@@ -622,7 +622,8 @@ chrec_apply (unsigned var,
/* "{a, +, b} (x)" -> "a + b*x". */
else if (operand_equal_p (CHREC_LEFT (chrec), chrecr)
&& TREE_CODE (x) == PLUS_EXPR
- && integer_all_onesp (TREE_OPERAND (x, 1)))
+ && integer_all_onesp (TREE_OPERAND (x, 1))
+ && !POINTER_TYPE_P (type))
{
/* We know the number of iterations can't be negative.
So {a, +, a} (x-1) -> "a*x". */
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index af75522..e146b13 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -2284,15 +2284,32 @@ struct floatn_type_info {
/* Matrix describing the structures contained in a given tree code. */
extern bool tree_contains_struct[MAX_TREE_CODES][64];
+#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
+#define END_OF_BASE_TREE_CODES tcc_exceptional,
+
+
/* Class of tree given its code. */
-extern const enum tree_code_class tree_code_type[];
+constexpr enum tree_code_class tree_code_type[] = {
+#include "all-tree.def"
+};
+
+#undef DEFTREECODE
+#undef END_OF_BASE_TREE_CODES
/* Each tree code class has an associated string representation.
These must correspond to the tree_code_class entries. */
extern const char *const tree_code_class_strings[];
/* Number of argument-words in each kind of tree-node. */
-extern const unsigned char tree_code_length[];
+
+#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
+#define END_OF_BASE_TREE_CODES 0,
+constexpr unsigned char tree_code_length[] = {
+#include "all-tree.def"
+};
+
+#undef DEFTREECODE
+#undef END_OF_BASE_TREE_CODES
/* Vector of all alias pairs for global symbols. */
extern GTY(()) vec<alias_pair, va_gc> *alias_pairs;
diff --git a/gcc/tree-diagnostic.cc b/gcc/tree-diagnostic.cc
index 0d79fe3..5cf3a1c 100644
--- a/gcc/tree-diagnostic.cc
+++ b/gcc/tree-diagnostic.cc
@@ -190,14 +190,17 @@ maybe_unwind_expanded_macro_loc (diagnostic_context *context,
location_t l =
linemap_resolve_location (line_table, resolved_def_loc,
LRK_SPELLING_LOCATION, &m);
- if (l < RESERVED_LOCATION_COUNT || LINEMAP_SYSP (m))
+ location_t l0 = l;
+ if (IS_ADHOC_LOC (l0))
+ l0 = get_location_from_adhoc_loc (line_table, l0);
+ if (l0 < RESERVED_LOCATION_COUNT || LINEMAP_SYSP (m))
continue;
/* We need to print the context of the macro definition only
when the locus of the first displayed diagnostic (displayed
before this trace) was inside the definition of the
macro. */
- int resolved_def_loc_line = SOURCE_LINE (m, l);
+ const int resolved_def_loc_line = SOURCE_LINE (m, l0);
if (ix == 0 && saved_location_line != resolved_def_loc_line)
{
diagnostic_append_note (context, resolved_def_loc,
diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
index a83b013..0807201 100644
--- a/gcc/tree-if-conv.cc
+++ b/gcc/tree-if-conv.cc
@@ -763,10 +763,9 @@ idx_within_array_bound (tree ref, tree *idx, void *dta)
if (TREE_CODE (ref) != ARRAY_REF)
return false;
- /* For arrays at the end of the structure, we are not guaranteed that they
- do not really extend over their declared size. However, for arrays of
- size greater than one, this is unlikely to be intended. */
- if (array_at_struct_end_p (ref))
+ /* For arrays that might have flexible sizes, it is not guaranteed that they
+ do not extend over their declared size. */
+ if (array_ref_flexible_size_p (ref))
return false;
ev = analyze_scalar_evolution (loop, *idx);
@@ -1434,10 +1433,20 @@ if_convertible_loop_p_1 (class loop *loop, vec<data_reference_p> *refs)
basic_block bb = ifc_bbs[i];
gimple_stmt_iterator gsi;
+ bool may_have_nonlocal_labels
+ = bb_with_exit_edge_p (loop, bb) || bb == loop->latch;
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
switch (gimple_code (gsi_stmt (gsi)))
{
case GIMPLE_LABEL:
+ if (!may_have_nonlocal_labels)
+ {
+ tree label
+ = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi)));
+ if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
+ return false;
+ }
+ /* Fallthru. */
case GIMPLE_ASSIGN:
case GIMPLE_CALL:
case GIMPLE_DEBUG:
@@ -2628,8 +2637,8 @@ remove_conditions_and_labels (loop_p loop)
basic_block bb = ifc_bbs[i];
if (bb_with_exit_edge_p (loop, bb)
- || bb == loop->latch)
- continue;
+ || bb == loop->latch)
+ continue;
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
switch (gimple_code (gsi_stmt (gsi)))
@@ -3762,7 +3771,8 @@ pass_if_conversion::execute (function *fun)
if (!gimple_bb (g))
continue;
unsigned ifcvt_loop = tree_to_uhwi (gimple_call_arg (g, 0));
- if (!get_loop (fun, ifcvt_loop))
+ unsigned orig_loop = tree_to_uhwi (gimple_call_arg (g, 1));
+ if (!get_loop (fun, ifcvt_loop) || !get_loop (fun, orig_loop))
{
if (dump_file)
fprintf (dump_file, "If-converted loop vanished\n");
diff --git a/gcc/tree-into-ssa.cc b/gcc/tree-into-ssa.cc
index d13fb72..9a2417d 100644
--- a/gcc/tree-into-ssa.cc
+++ b/gcc/tree-into-ssa.cc
@@ -1911,13 +1911,17 @@ maybe_register_def (def_operand_p def_p, gimple *stmt,
{
if (gimple_clobber_p (stmt) && is_gimple_reg (sym))
{
- gcc_checking_assert (VAR_P (sym));
+ tree defvar;
+ if (VAR_P (sym))
+ defvar = sym;
+ else
+ defvar = create_tmp_reg (TREE_TYPE (sym));
/* Replace clobber stmts with a default def. This new use of a
default definition may make it look like SSA_NAMEs have
conflicting lifetimes, so we need special code to let them
coalesce properly. */
to_delete = true;
- def = get_or_create_ssa_default_def (cfun, sym);
+ def = get_or_create_ssa_default_def (cfun, defvar);
}
else
{
@@ -2106,7 +2110,6 @@ rewrite_update_phi_arguments (basic_block bb)
symbol we may find NULL arguments. That's why we
take the symbol from the LHS of the PHI node. */
reaching_def = get_reaching_def (lhs_sym);
-
}
else
{
@@ -2118,8 +2121,9 @@ rewrite_update_phi_arguments (basic_block bb)
reaching_def = get_reaching_def (arg);
}
- /* Update the argument if there is a reaching def. */
- if (reaching_def)
+ /* Update the argument if there is a reaching def different
+ from arg. */
+ if (reaching_def && reaching_def != arg)
{
location_t locus;
int arg_i = PHI_ARG_INDEX_FROM_USE (arg_p);
@@ -2129,6 +2133,10 @@ rewrite_update_phi_arguments (basic_block bb)
/* Virtual operands do not need a location. */
if (virtual_operand_p (reaching_def))
locus = UNKNOWN_LOCATION;
+ /* If SSA update didn't insert this PHI the argument
+ might have a location already, keep that. */
+ else if (gimple_phi_arg_has_location (phi, arg_i))
+ locus = gimple_phi_arg_location (phi, arg_i);
else
{
gimple *stmt = SSA_NAME_DEF_STMT (reaching_def);
@@ -2146,7 +2154,6 @@ rewrite_update_phi_arguments (basic_block bb)
gimple_phi_arg_set_location (phi, arg_i, locus);
}
-
if (e->flags & EDGE_ABNORMAL)
SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (arg_p)) = 1;
}
diff --git a/gcc/tree-loop-distribution.cc b/gcc/tree-loop-distribution.cc
index ed3dd73..15ae241 100644
--- a/gcc/tree-loop-distribution.cc
+++ b/gcc/tree-loop-distribution.cc
@@ -1790,10 +1790,15 @@ loop_distribution::classify_builtin_ldst (loop_p loop, struct graph *rdg,
if (res != 2)
return;
- /* They much have the same access size. */
+ /* They must have the same access size. */
if (!operand_equal_p (size, src_size, 0))
return;
+ /* They must have the same storage order. */
+ if (reverse_storage_order_for_component_p (DR_REF (dst_dr))
+ != reverse_storage_order_for_component_p (DR_REF (src_dr)))
+ return;
+
/* Load and store in loop nest must access memory in the same way, i.e,
their must have the same steps in each loop of the nest. */
if (dst_steps.length () != src_steps.length ())
diff --git a/gcc/tree-object-size.cc b/gcc/tree-object-size.cc
index 1f04cb8..d9f2539 100644
--- a/gcc/tree-object-size.cc
+++ b/gcc/tree-object-size.cc
@@ -89,6 +89,10 @@ static bitmap computed[OST_END];
/* Maximum value of offset we consider to be addition. */
static unsigned HOST_WIDE_INT offset_limit;
+/* Tell the generic SSA updater what kind of update is needed after the pass
+ executes. */
+static unsigned todo;
+
/* Return true if VAL represents an initial size for OBJECT_SIZE_TYPE. */
static inline bool
@@ -633,7 +637,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
v = NULL_TREE;
break;
}
- is_flexible_array_mem_ref = array_at_struct_end_p (v);
+ is_flexible_array_mem_ref = array_ref_flexible_size_p (v);
while (v != pt_var && TREE_CODE (v) == COMPONENT_REF)
if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
!= UNION_TYPE
@@ -787,6 +791,71 @@ alloc_object_size (const gcall *call, int object_size_type)
return bytes ? bytes : size_unknown (object_size_type);
}
+/* Compute __builtin_object_size for CALL, which is a call to either
+ BUILT_IN_STRDUP or BUILT_IN_STRNDUP; IS_STRNDUP indicates which it is.
+ OBJECT_SIZE_TYPE is the second argument from __builtin_object_size.
+ If unknown, return size_unknown (object_size_type). */
+
+static tree
+strdup_object_size (const gcall *call, int object_size_type, bool is_strndup)
+{
+ tree src = gimple_call_arg (call, 0);
+ tree sz = size_unknown (object_size_type);
+ tree n = NULL_TREE;
+
+ if (is_strndup)
+ n = fold_build2 (PLUS_EXPR, sizetype, size_one_node,
+ gimple_call_arg (call, 1));
+ /* For strdup, simply emit strlen (SRC) + 1 and let the optimizer fold it the
+ way it likes. */
+ else
+ {
+ tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
+ if (strlen_fn)
+ {
+ sz = fold_build2 (PLUS_EXPR, sizetype, size_one_node,
+ build_call_expr (strlen_fn, 1, src));
+ todo = TODO_update_ssa_only_virtuals;
+ }
+ }
+
+ /* In all other cases, return the size of SRC since the object size cannot
+ exceed that. We cannot do this for OST_MINIMUM unless SRC points into a
+ string constant since otherwise the object size could go all the way down
+ to zero. */
+ if (!size_valid_p (sz, object_size_type)
+ || size_unknown_p (sz, object_size_type))
+ {
+ tree wholesrc = NULL_TREE;
+ if (TREE_CODE (src) == ADDR_EXPR)
+ wholesrc = get_base_address (TREE_OPERAND (src, 0));
+
+ /* If the source points within a string constant, we try to get its
+ length. */
+ if (wholesrc && TREE_CODE (wholesrc) == STRING_CST)
+ {
+ tree len = c_strlen (src, 0);
+ if (len)
+ sz = fold_build2 (PLUS_EXPR, sizetype, size_one_node, len);
+ }
+
+ /* For maximum estimate, our next best guess is the object size of the
+ source. */
+ if (size_unknown_p (sz, object_size_type)
+ && !(object_size_type & OST_MINIMUM))
+ compute_builtin_object_size (src, object_size_type, &sz);
+ }
+
+ /* String duplication allocates at least one byte, so we should never fail
+ for OST_MINIMUM. */
+ if ((!size_valid_p (sz, object_size_type)
+ || size_unknown_p (sz, object_size_type))
+ && (object_size_type & OST_MINIMUM))
+ sz = size_one_node;
+
+ /* Factor in the N. */
+ return n ? fold_build2 (MIN_EXPR, sizetype, n, sz) : sz;
+}
/* If object size is propagated from one of function's arguments directly
to its return value, return that argument for GIMPLE_CALL statement CALL.
@@ -1233,12 +1302,19 @@ call_object_size (struct object_size_info *osi, tree ptr, gcall *call)
{
int object_size_type = osi->object_size_type;
unsigned int varno = SSA_NAME_VERSION (ptr);
+ tree bytes = NULL_TREE;
gcc_assert (is_gimple_call (call));
gcc_assert (!object_sizes_unknown_p (object_size_type, varno));
gcc_assert (osi->pass == 0);
- tree bytes = alloc_object_size (call, object_size_type);
+
+ bool is_strdup = gimple_call_builtin_p (call, BUILT_IN_STRDUP);
+ bool is_strndup = gimple_call_builtin_p (call, BUILT_IN_STRNDUP);
+ if (is_strdup || is_strndup)
+ bytes = strdup_object_size (call, object_size_type, is_strndup);
+ else
+ bytes = alloc_object_size (call, object_size_type);
if (!size_valid_p (bytes, object_size_type))
bytes = size_unknown (object_size_type);
@@ -1998,6 +2074,8 @@ dynamic_object_sizes_execute_one (gimple_stmt_iterator *i, gimple *call)
static unsigned int
object_sizes_execute (function *fun, bool early)
{
+ todo = 0;
+
basic_block bb;
FOR_EACH_BB_FN (bb, fun)
{
@@ -2094,7 +2172,7 @@ object_sizes_execute (function *fun, bool early)
}
fini_object_sizes ();
- return 0;
+ return todo;
}
/* Simple pass to optimize all __builtin_object_size () builtins. */
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index e7a8c94..cb2a88c 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -3416,14 +3416,6 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
pp_greater (pp);
break;
- case ASSERT_EXPR:
- pp_string (pp, "ASSERT_EXPR <");
- dump_generic_node (pp, ASSERT_EXPR_VAR (node), spc, flags, false);
- pp_string (pp, ", ");
- dump_generic_node (pp, ASSERT_EXPR_COND (node), spc, flags, false);
- pp_greater (pp);
- break;
-
case SCEV_KNOWN:
pp_string (pp, "scev_known");
break;
diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc
index 7e2a3e9..f75398a 100644
--- a/gcc/tree-scalar-evolution.cc
+++ b/gcc/tree-scalar-evolution.cc
@@ -1122,13 +1122,11 @@ scev_dfs::follow_ssa_edge_expr (gimple *at_stmt, tree expr,
- a PLUS_EXPR,
- a POINTER_PLUS_EXPR,
- a MINUS_EXPR,
- - an ASSERT_EXPR,
- other cases are not yet handled. */
/* For SSA_NAME look at the definition statement, handling
PHI nodes and otherwise expand appropriately for the expression
handling below. */
-tail_recurse:
if (TREE_CODE (expr) == SSA_NAME)
{
gimple *def = SSA_NAME_DEF_STMT (expr);
@@ -1229,10 +1227,16 @@ tail_recurse:
{
CASE_CONVERT:
{
- /* This assignment is under the form "a_1 = (cast) rhs. */
+ /* This assignment is under the form "a_1 = (cast) rhs. We cannot
+ validate any precision altering conversion during the SCC
+ analysis, so don't even try. */
+ if (!tree_nop_conversion_p (type, TREE_TYPE (rhs0)))
+ return t_false;
t_bool res = follow_ssa_edge_expr (at_stmt, rhs0,
evolution_of_loop, limit);
- *evolution_of_loop = chrec_convert (type, *evolution_of_loop, at_stmt);
+ if (res == t_true)
+ *evolution_of_loop = chrec_convert (type, *evolution_of_loop,
+ at_stmt);
return res;
}
@@ -1272,12 +1276,6 @@ tail_recurse:
return follow_ssa_edge_binary (at_stmt, type, rhs0, code, rhs1,
evolution_of_loop, limit);
- case ASSERT_EXPR:
- /* This assignment is of the form: "a_1 = ASSERT_EXPR <a_2, ...>"
- It must be handled as a copy assignment of the form a_1 = a_2. */
- expr = ASSERT_EXPR_VAR (rhs0);
- goto tail_recurse;
-
default:
return t_false;
}
@@ -1640,13 +1638,6 @@ interpret_rhs_expr (class loop *loop, gimple *at_stmt,
if (code == SSA_NAME)
return chrec_convert (type, analyze_scalar_evolution (loop, rhs1),
at_stmt);
-
- if (code == ASSERT_EXPR)
- {
- rhs1 = ASSERT_EXPR_VAR (rhs1);
- return chrec_convert (type, analyze_scalar_evolution (loop, rhs1),
- at_stmt);
- }
}
switch (code)
diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc
index b4c65da..d3a91b1 100644
--- a/gcc/tree-ssa-alias.cc
+++ b/gcc/tree-ssa-alias.cc
@@ -1073,7 +1073,7 @@ component_ref_to_zero_sized_trailing_array_p (tree ref)
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 1))) == ARRAY_TYPE
&& (!TYPE_SIZE (TREE_TYPE (TREE_OPERAND (ref, 1)))
|| integer_zerop (TYPE_SIZE (TREE_TYPE (TREE_OPERAND (ref, 1)))))
- && array_at_struct_end_p (ref));
+ && array_ref_flexible_size_p (ref));
}
/* Worker for aliasing_component_refs_p. Most parameters match parameters of
@@ -3433,10 +3433,10 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref)
}
/* Finally check if the lhs has the same address and size as the
base candidate of the access. Watch out if we have dropped
- an array-ref that was at struct end, this means ref->ref may
- be outside of the TYPE_SIZE of its base. */
+ an array-ref that might have flexible size, this means ref->ref
+ may be outside of the TYPE_SIZE of its base. */
if ((! innermost_dropped_array_ref
- || ! array_at_struct_end_p (innermost_dropped_array_ref))
+ || ! array_ref_flexible_size_p (innermost_dropped_array_ref))
&& (lhs == base
|| (((TYPE_SIZE (TREE_TYPE (lhs))
== TYPE_SIZE (TREE_TYPE (base)))
diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc
index 9778e77..68e69bf 100644
--- a/gcc/tree-ssa-ccp.cc
+++ b/gcc/tree-ssa-ccp.cc
@@ -532,7 +532,12 @@ set_lattice_value (tree var, ccp_prop_value_t *new_val)
use the meet operator to retain a conservative value.
Missed optimizations like PR65851 makes this necessary.
It also ensures we converge to a stable lattice solution. */
- if (old_val->lattice_val != UNINITIALIZED)
+ if (old_val->lattice_val != UNINITIALIZED
+ /* But avoid using meet for constant -> copy transitions. */
+ && !(old_val->lattice_val == CONSTANT
+ && CONSTANT_CLASS_P (old_val->value)
+ && new_val->lattice_val == CONSTANT
+ && TREE_CODE (new_val->value) == SSA_NAME))
ccp_lattice_meet (new_val, old_val);
gcc_checking_assert (valid_lattice_transition (*old_val, *new_val));
@@ -1266,24 +1271,15 @@ valueize_op_1 (tree op)
static tree
ccp_fold (gimple *stmt)
{
- location_t loc = gimple_location (stmt);
switch (gimple_code (stmt))
{
- case GIMPLE_COND:
- {
- /* Handle comparison operators that can appear in GIMPLE form. */
- tree op0 = valueize_op (gimple_cond_lhs (stmt));
- tree op1 = valueize_op (gimple_cond_rhs (stmt));
- enum tree_code code = gimple_cond_code (stmt);
- return fold_binary_loc (loc, code, boolean_type_node, op0, op1);
- }
-
case GIMPLE_SWITCH:
{
/* Return the constant switch index. */
return valueize_op (gimple_switch_index (as_a <gswitch *> (stmt)));
}
+ case GIMPLE_COND:
case GIMPLE_ASSIGN:
case GIMPLE_CALL:
return gimple_fold_stmt_to_constant_1 (stmt,
@@ -1934,6 +1930,18 @@ bit_value_binop (enum tree_code code, signop sgn, int width,
{
widest_int r1max = r1val | r1mask;
widest_int r2max = r2val | r2mask;
+ if (r2mask == 0 && !wi::neg_p (r1max))
+ {
+ widest_int shift = wi::exact_log2 (r2val);
+ if (shift != -1)
+ {
+ // Handle division by a power of 2 as an rshift.
+ bit_value_binop (RSHIFT_EXPR, sgn, width, val, mask,
+ r1type_sgn, r1type_precision, r1val, r1mask,
+ r2type_sgn, r2type_precision, shift, r2mask);
+ return;
+ }
+ }
if (sgn == UNSIGNED
|| (!wi::neg_p (r1max) && !wi::neg_p (r2max)))
{
@@ -3471,17 +3479,35 @@ optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip,
{
gimple *use_nop_stmt;
if (!single_imm_use (use_lhs, &use_p, &use_nop_stmt)
- || !is_gimple_assign (use_nop_stmt))
+ || (!is_gimple_assign (use_nop_stmt)
+ && gimple_code (use_nop_stmt) != GIMPLE_COND))
return false;
- tree use_nop_lhs = gimple_assign_lhs (use_nop_stmt);
- rhs_code = gimple_assign_rhs_code (use_nop_stmt);
- if (rhs_code != BIT_AND_EXPR)
+ /* Handle both
+ _4 = _5 < 0;
+ and
+ if (_5 < 0)
+ */
+ tree use_nop_lhs = nullptr;
+ rhs_code = ERROR_MARK;
+ if (is_gimple_assign (use_nop_stmt))
{
- if (TREE_CODE (use_nop_lhs) == SSA_NAME
+ use_nop_lhs = gimple_assign_lhs (use_nop_stmt);
+ rhs_code = gimple_assign_rhs_code (use_nop_stmt);
+ }
+ if (!use_nop_lhs || rhs_code != BIT_AND_EXPR)
+ {
+ /* Also handle
+ if (_5 < 0)
+ */
+ if (use_nop_lhs
+ && TREE_CODE (use_nop_lhs) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (use_nop_lhs))
return false;
- if (rhs_code == BIT_NOT_EXPR)
+ if (use_nop_lhs && rhs_code == BIT_NOT_EXPR)
{
+ /* Handle
+ _7 = ~_2;
+ */
g = convert_atomic_bit_not (fn, use_nop_stmt, lhs,
mask);
if (!g)
@@ -3512,14 +3538,31 @@ optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip,
}
else
{
- if (TREE_CODE (TREE_TYPE (use_nop_lhs)) != BOOLEAN_TYPE)
- return false;
+ tree cmp_rhs1, cmp_rhs2;
+ if (use_nop_lhs)
+ {
+ /* Handle
+ _4 = _5 < 0;
+ */
+ if (TREE_CODE (TREE_TYPE (use_nop_lhs))
+ != BOOLEAN_TYPE)
+ return false;
+ cmp_rhs1 = gimple_assign_rhs1 (use_nop_stmt);
+ cmp_rhs2 = gimple_assign_rhs2 (use_nop_stmt);
+ }
+ else
+ {
+ /* Handle
+ if (_5 < 0)
+ */
+ rhs_code = gimple_cond_code (use_nop_stmt);
+ cmp_rhs1 = gimple_cond_lhs (use_nop_stmt);
+ cmp_rhs2 = gimple_cond_rhs (use_nop_stmt);
+ }
if (rhs_code != GE_EXPR && rhs_code != LT_EXPR)
return false;
- tree cmp_rhs1 = gimple_assign_rhs1 (use_nop_stmt);
if (use_lhs != cmp_rhs1)
return false;
- tree cmp_rhs2 = gimple_assign_rhs2 (use_nop_stmt);
if (!integer_zerop (cmp_rhs2))
return false;
@@ -3547,6 +3590,14 @@ optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip,
_1 = __atomic_fetch_and_4 (ptr_6, 0x7fffffff, _3);
_6 = _1 & 0x80000000;
_4 = _6 != 0 or _6 == 0;
+ and convert
+ _1 = __atomic_fetch_and_4 (ptr_6, 0x7fffffff, _3);
+ _5 = (signed int) _1;
+ if (_5 < 0 or _5 >= 0)
+ to
+ _1 = __atomic_fetch_and_4 (ptr_6, 0x7fffffff, _3);
+ _6 = _1 & 0x80000000;
+ if (_6 != 0 or _6 == 0)
*/
and_mask = build_int_cst (TREE_TYPE (use_rhs),
highest);
@@ -3567,6 +3618,14 @@ optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip,
_1 = __atomic_fetch_or_4 (ptr_6, 0x80000000, _3);
_6 = _1 & 0x80000000;
_4 = _6 != 0 or _6 == 0;
+ and convert
+ _1 = __atomic_fetch_or_4 (ptr_6, 0x80000000, _3);
+ _5 = (signed int) _1;
+ if (_5 < 0 or _5 >= 0)
+ to
+ _1 = __atomic_fetch_or_4 (ptr_6, 0x80000000, _3);
+ _6 = _1 & 0x80000000;
+ if (_6 != 0 or _6 == 0)
*/
}
var = make_ssa_name (TREE_TYPE (use_rhs));
@@ -3577,11 +3636,14 @@ optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip,
gsi = gsi_for_stmt (use_nop_stmt);
gsi_insert_before (&gsi, g, GSI_NEW_STMT);
use_stmt = g;
- g = gimple_build_assign (use_nop_lhs,
- (rhs_code == GE_EXPR
- ? EQ_EXPR : NE_EXPR),
- var,
- build_zero_cst (TREE_TYPE (use_rhs)));
+ rhs_code = rhs_code == GE_EXPR ? EQ_EXPR : NE_EXPR;
+ tree const_zero = build_zero_cst (TREE_TYPE (use_rhs));
+ if (use_nop_lhs)
+ g = gimple_build_assign (use_nop_lhs, rhs_code,
+ var, const_zero);
+ else
+ g = gimple_build_cond (rhs_code, var, const_zero,
+ nullptr, nullptr);
gsi_insert_after (&gsi, g, GSI_NEW_STMT);
gsi = gsi_for_stmt (use_nop_stmt);
gsi_remove (&gsi, true);
diff --git a/gcc/tree-ssa-copy.cc b/gcc/tree-ssa-copy.cc
index 782ceb5..811161c 100644
--- a/gcc/tree-ssa-copy.cc
+++ b/gcc/tree-ssa-copy.cc
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "tree-scalar-evolution.h"
#include "tree-ssa-loop-niter.h"
+#include "gimple-fold.h"
/* This file implements the copy propagation pass and provides a
@@ -99,12 +100,16 @@ stmt_may_generate_copy (gimple *stmt)
if (gimple_vuse (stmt))
return false;
+ /* If the assignment is from a constant it generates a useful copy. */
+ if (gimple_assign_single_p (stmt)
+ && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
+ return true;
+
/* Otherwise, the only statements that generate useful copies are
- assignments whose RHS is just an SSA name that doesn't flow
- through abnormal edges. */
- return ((gimple_assign_rhs_code (stmt) == SSA_NAME
- && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)))
- || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)));
+ assignments whose single SSA use doesn't flow through abnormal
+ edges. */
+ tree rhs = single_ssa_tree_operand (stmt, SSA_OP_USE);
+ return (rhs && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs));
}
@@ -197,26 +202,24 @@ dump_copy_of (FILE *file, tree var)
static enum ssa_prop_result
copy_prop_visit_assignment (gimple *stmt, tree *result_p)
{
- tree lhs, rhs;
-
- lhs = gimple_assign_lhs (stmt);
- rhs = valueize_val (gimple_assign_rhs1 (stmt));
-
- if (TREE_CODE (lhs) == SSA_NAME)
+ tree lhs = gimple_assign_lhs (stmt);
+ tree rhs = gimple_fold_stmt_to_constant_1 (stmt, valueize_val);
+ if (rhs
+ && (TREE_CODE (rhs) == SSA_NAME
+ || is_gimple_min_invariant (rhs)))
{
- /* Straight copy between two SSA names. First, make sure that
+ /* Straight copy between two SSA names or a constant. Make sure that
we can propagate the RHS into uses of LHS. */
if (!may_propagate_copy (lhs, rhs))
- return SSA_PROP_VARYING;
-
- *result_p = lhs;
- if (set_copy_of_val (*result_p, rhs))
- return SSA_PROP_INTERESTING;
- else
- return SSA_PROP_NOT_INTERESTING;
+ rhs = lhs;
}
+ else
+ rhs = lhs;
- return SSA_PROP_VARYING;
+ *result_p = lhs;
+ if (set_copy_of_val (*result_p, rhs))
+ return SSA_PROP_INTERESTING;
+ return rhs != lhs ? SSA_PROP_NOT_INTERESTING : SSA_PROP_VARYING;
}
@@ -282,10 +285,8 @@ copy_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *result_p)
fprintf (dump_file, "\n");
}
- if (gimple_assign_single_p (stmt)
- && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
- && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
- || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
+ if (is_gimple_assign (stmt)
+ && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
{
/* If the statement is a copy assignment, evaluate its RHS to
see if the lattice value of its output has changed. */
diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc
index 54e5d8c..187d58b 100644
--- a/gcc/tree-ssa-dce.cc
+++ b/gcc/tree-ssa-dce.cc
@@ -2005,14 +2005,25 @@ class pass_dce : public gimple_opt_pass
{
public:
pass_dce (gcc::context *ctxt)
- : gimple_opt_pass (pass_data_dce, ctxt)
+ : gimple_opt_pass (pass_data_dce, ctxt), update_address_taken_p (false)
{}
/* opt_pass methods: */
opt_pass * clone () final override { return new pass_dce (m_ctxt); }
+ void set_pass_param (unsigned n, bool param) final override
+ {
+ gcc_assert (n == 0);
+ update_address_taken_p = param;
+ }
bool gate (function *) final override { return flag_tree_dce != 0; }
- unsigned int execute (function *) final override { return tree_ssa_dce (); }
+ unsigned int execute (function *) final override
+ {
+ return (tree_ssa_dce ()
+ | (update_address_taken_p ? TODO_update_address_taken : 0));
+ }
+private:
+ bool update_address_taken_p;
}; // class pass_dce
} // anon namespace
diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc
index c7f095d..c9e52d1 100644
--- a/gcc/tree-ssa-dom.cc
+++ b/gcc/tree-ssa-dom.cc
@@ -673,10 +673,10 @@ record_edge_info (basic_block bb)
{
/* At this point we know the exit condition is loop
invariant. The only way to get out of the loop is
- if never traverses the backedge to begin with. This
- implies that any PHI nodes create equivalances we can
- attach to the loop exit edge. */
- int alternative
+ if it never traverses the backedge to begin with. This
+ implies that any PHI nodes create equivalances that we
+ can attach to the loop exit edge. */
+ bool alternative
= (EDGE_PRED (bb, 0)->flags & EDGE_DFS_BACK) ? 1 : 0;
gphi_iterator gsi;
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index 4b693ef..160e49e 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -3162,7 +3162,11 @@ optimize_vector_load (gimple_stmt_iterator *gsi)
&& (def == lhs
|| (known_eq (bit_field_size (use_rhs), def_eltsize)
&& constant_multiple_p (bit_field_offset (use_rhs),
- def_eltsize))))
+ def_eltsize)
+ /* We can simulate the VEC_UNPACK_{HI,LO}_EXPR
+ via a NOP_EXPR only for integral types.
+ ??? Support VEC_UNPACK_FLOAT_{HI,LO}_EXPR. */
+ && INTEGRAL_TYPE_P (TREE_TYPE (use_rhs)))))
{
bf_stmts.safe_push (use_stmt);
continue;
@@ -3363,6 +3367,7 @@ pass_forwprop::execute (function *fun)
auto_vec<gimple *, 4> to_fixup;
auto_vec<gimple *, 32> to_remove;
to_purge = BITMAP_ALLOC (NULL);
+ bitmap need_ab_cleanup = BITMAP_ALLOC (NULL);
for (int i = 0; i < postorder_num; ++i)
{
gimple_stmt_iterator gsi;
@@ -3384,7 +3389,12 @@ pass_forwprop::execute (function *fun)
FOR_EACH_PHI_ARG (use_p, phi, it, SSA_OP_USE)
{
tree use = USE_FROM_PTR (use_p);
- if (! first)
+ if (use == res)
+ /* The PHI result can also appear on a backedge, if so
+ we can ignore this case for the purpose of determining
+ the singular value. */
+ ;
+ else if (! first)
first = use;
else if (! operand_equal_p (first, use, 0))
{
@@ -3673,6 +3683,9 @@ pass_forwprop::execute (function *fun)
/* Mark stmt as potentially needing revisiting. */
gimple_set_plf (stmt, GF_PLF_1, false);
+ bool can_make_abnormal_goto = (is_gimple_call (stmt)
+ && stmt_can_make_abnormal_goto (stmt));
+
/* Substitute from our lattice. We need to do so only once. */
bool substituted_p = false;
use_operand_p usep;
@@ -3691,6 +3704,10 @@ pass_forwprop::execute (function *fun)
&& is_gimple_assign (stmt)
&& gimple_assign_rhs_code (stmt) == ADDR_EXPR)
recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
+ if (substituted_p
+ && can_make_abnormal_goto
+ && !stmt_can_make_abnormal_goto (stmt))
+ bitmap_set_bit (need_ab_cleanup, bb->index);
bool changed;
do
@@ -3892,7 +3909,9 @@ pass_forwprop::execute (function *fun)
}
cfg_changed |= gimple_purge_all_dead_eh_edges (to_purge);
+ cfg_changed |= gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup);
BITMAP_FREE (to_purge);
+ BITMAP_FREE (need_ab_cleanup);
if (cfg_changed)
todoflags |= TODO_cleanup_cfg;
diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc
index 2119d40..20a9ca7 100644
--- a/gcc/tree-ssa-loop-im.cc
+++ b/gcc/tree-ssa-loop-im.cc
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "alias.h"
#include "builtins.h"
#include "tree-dfa.h"
+#include "tree-ssa.h"
#include "dbgcnt.h"
/* TODO: Support for predicated code motion. I.e.
@@ -331,8 +332,8 @@ enum move_pos
because it may trap), return MOVE_PRESERVE_EXECUTION.
Otherwise return MOVE_IMPOSSIBLE. */
-enum move_pos
-movement_possibility (gimple *stmt)
+static enum move_pos
+movement_possibility_1 (gimple *stmt)
{
tree lhs;
enum move_pos ret = MOVE_POSSIBLE;
@@ -422,6 +423,23 @@ movement_possibility (gimple *stmt)
return ret;
}
+static enum move_pos
+movement_possibility (gimple *stmt)
+{
+ enum move_pos pos = movement_possibility_1 (stmt);
+ if (pos == MOVE_POSSIBLE)
+ {
+ use_operand_p use_p;
+ ssa_op_iter ssa_iter;
+ FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, ssa_iter, SSA_OP_USE)
+ if (TREE_CODE (USE_FROM_PTR (use_p)) == SSA_NAME
+ && ssa_name_maybe_undef_p (USE_FROM_PTR (use_p)))
+ return MOVE_PRESERVE_EXECUTION;
+ }
+ return pos;
+}
+
+
/* Compare the profile count inequality of bb and loop's preheader, it is
three-state as stated in profile-count.h, FALSE is returned if inequality
cannot be decided. */
@@ -3532,6 +3550,8 @@ loop_invariant_motion_in_fun (function *fun, bool store_motion)
tree_ssa_lim_initialize (store_motion);
+ mark_ssa_maybe_undefs ();
+
/* Gathers information about memory accesses in the loops. */
analyze_memory_references (store_motion);
diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
index a6f926a..ebd4aec 100644
--- a/gcc/tree-ssa-loop-ivopts.cc
+++ b/gcc/tree-ssa-loop-ivopts.cc
@@ -131,6 +131,7 @@ along with GCC; see the file COPYING3. If not see
#include "builtins.h"
#include "tree-vectorizer.h"
#include "dbgcnt.h"
+#include "cfganal.h"
/* For lang_hooks.types.type_for_mode. */
#include "langhooks.h"
@@ -3071,117 +3072,6 @@ get_loop_invariant_expr (struct ivopts_data *data, tree inv_expr)
return *slot;
}
-/* Return TRUE iff VAR is marked as maybe-undefined. See
- mark_ssa_maybe_undefs. */
-
-static inline bool
-ssa_name_maybe_undef_p (tree var)
-{
- gcc_checking_assert (TREE_CODE (var) == SSA_NAME);
- return TREE_VISITED (var);
-}
-
-/* Set (or clear, depending on VALUE) VAR's maybe-undefined mark. */
-
-static inline void
-ssa_name_set_maybe_undef (tree var, bool value = true)
-{
- gcc_checking_assert (TREE_CODE (var) == SSA_NAME);
- TREE_VISITED (var) = value;
-}
-
-/* Return TRUE iff there are any non-PHI uses of VAR that dominate the
- end of BB. If we return TRUE and BB is a loop header, then VAR we
- be assumed to be defined within the loop, even if it is marked as
- maybe-undefined. */
-
-static inline bool
-ssa_name_any_use_dominates_bb_p (tree var, basic_block bb)
-{
- imm_use_iterator iter;
- use_operand_p use_p;
- FOR_EACH_IMM_USE_FAST (use_p, iter, var)
- {
- if (is_a <gphi *> (USE_STMT (use_p))
- || is_gimple_debug (USE_STMT (use_p)))
- continue;
- basic_block dombb = gimple_bb (USE_STMT (use_p));
- if (dominated_by_p (CDI_DOMINATORS, bb, dombb))
- return true;
- }
-
- return false;
-}
-
-/* Mark as maybe_undef any SSA_NAMEs that are unsuitable as ivopts
- candidates for potentially involving undefined behavior. */
-
-static void
-mark_ssa_maybe_undefs (void)
-{
- auto_vec<tree> queue;
-
- /* Scan all SSA_NAMEs, marking the definitely-undefined ones as
- maybe-undefined and queuing them for propagation, while clearing
- the mark on others. */
- unsigned int i;
- tree var;
- FOR_EACH_SSA_NAME (i, var, cfun)
- {
- if (SSA_NAME_IS_VIRTUAL_OPERAND (var)
- || !ssa_undefined_value_p (var, false))
- ssa_name_set_maybe_undef (var, false);
- else
- {
- ssa_name_set_maybe_undef (var);
- queue.safe_push (var);
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "marking _%i as maybe-undef\n",
- SSA_NAME_VERSION (var));
- }
- }
-
- /* Now propagate maybe-undefined from a DEF to any other PHI that
- uses it, as long as there isn't any intervening use of DEF. */
- while (!queue.is_empty ())
- {
- var = queue.pop ();
- imm_use_iterator iter;
- use_operand_p use_p;
- FOR_EACH_IMM_USE_FAST (use_p, iter, var)
- {
- /* Any uses of VAR that aren't PHI args imply VAR must be
- defined, otherwise undefined behavior would have been
- definitely invoked. Only PHI args may hold
- maybe-undefined values without invoking undefined
- behavior for that reason alone. */
- if (!is_a <gphi *> (USE_STMT (use_p)))
- continue;
- gphi *phi = as_a <gphi *> (USE_STMT (use_p));
-
- tree def = gimple_phi_result (phi);
- if (ssa_name_maybe_undef_p (def))
- continue;
-
- /* Look for any uses of the maybe-unused SSA_NAME that
- dominates the block that reaches the incoming block
- corresponding to the PHI arg in which it is mentioned.
- That means we can assume the SSA_NAME is defined in that
- path, so we only mark a PHI result as maybe-undef if we
- find an unused reaching SSA_NAME. */
- int idx = phi_arg_index_from_use (use_p);
- basic_block bb = gimple_phi_arg_edge (phi, idx)->src;
- if (ssa_name_any_use_dominates_bb_p (var, bb))
- continue;
-
- ssa_name_set_maybe_undef (def);
- queue.safe_push (def);
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "marking _%i as maybe-undef because of _%i\n",
- SSA_NAME_VERSION (def), SSA_NAME_VERSION (var));
- }
- }
-}
/* Return *TP if it is an SSA_NAME marked with TREE_VISITED, i.e., as
unsuitable as ivopts candidates for potentially involving undefined
@@ -7346,6 +7236,12 @@ create_new_iv (struct ivopts_data *data, struct iv_cand *cand)
case IP_END:
incr_pos = gsi_last_bb (ip_end_pos (data->current_loop));
after = true;
+ if (!gsi_end_p (incr_pos) && stmt_ends_bb_p (gsi_stmt (incr_pos)))
+ {
+ edge e = find_edge (gsi_bb (incr_pos), data->current_loop->header);
+ incr_pos = gsi_after_labels (split_edge (e));
+ after = false;
+ }
break;
case IP_AFTER_USE:
diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
index 4ffcef4..fece876 100644
--- a/gcc/tree-ssa-loop-niter.cc
+++ b/gcc/tree-ssa-loop-niter.cc
@@ -63,11 +63,6 @@ struct bounds
mpz_t below, up;
};
-static bool number_of_iterations_popcount (loop_p loop, edge exit,
- enum tree_code code,
- class tree_niter_desc *niter);
-
-
/* Splits expression EXPR to a variable part VAR and constant OFFSET. */
static void
@@ -2031,6 +2026,227 @@ number_of_iterations_cond (class loop *loop,
return ret;
}
+/* Return an expression that computes the popcount of src. */
+
+static tree
+build_popcount_expr (tree src)
+{
+ tree fn;
+ int prec = TYPE_PRECISION (TREE_TYPE (src));
+ int i_prec = TYPE_PRECISION (integer_type_node);
+ int li_prec = TYPE_PRECISION (long_integer_type_node);
+ int lli_prec = TYPE_PRECISION (long_long_integer_type_node);
+ if (prec <= i_prec)
+ fn = builtin_decl_implicit (BUILT_IN_POPCOUNT);
+ else if (prec == li_prec)
+ fn = builtin_decl_implicit (BUILT_IN_POPCOUNTL);
+ else if (prec == lli_prec || prec == 2 * lli_prec)
+ fn = builtin_decl_implicit (BUILT_IN_POPCOUNTLL);
+ else
+ return NULL_TREE;
+
+ tree utype = unsigned_type_for (TREE_TYPE (src));
+ src = fold_convert (utype, src);
+ if (prec < i_prec)
+ src = fold_convert (unsigned_type_node, src);
+ tree call;
+ if (prec == 2 * lli_prec)
+ {
+ tree src1 = fold_convert (long_long_unsigned_type_node,
+ fold_build2 (RSHIFT_EXPR, TREE_TYPE (src),
+ unshare_expr (src),
+ build_int_cst (integer_type_node,
+ lli_prec)));
+ tree src2 = fold_convert (long_long_unsigned_type_node, src);
+ tree call1 = build_call_expr (fn, 1, src1);
+ tree call2 = build_call_expr (fn, 1, src2);
+ call = fold_build2 (PLUS_EXPR, integer_type_node, call1, call2);
+ }
+ else
+ call = build_call_expr (fn, 1, src);
+
+ return call;
+}
+
+/* Utility function to check if OP is defined by a stmt
+ that is a val - 1. */
+
+static bool
+ssa_defined_by_minus_one_stmt_p (tree op, tree val)
+{
+ gimple *stmt;
+ return (TREE_CODE (op) == SSA_NAME
+ && (stmt = SSA_NAME_DEF_STMT (op))
+ && is_gimple_assign (stmt)
+ && (gimple_assign_rhs_code (stmt) == PLUS_EXPR)
+ && val == gimple_assign_rhs1 (stmt)
+ && integer_minus_onep (gimple_assign_rhs2 (stmt)));
+}
+
+/* See comment below for number_of_iterations_bitcount.
+ For popcount, we have:
+
+ modify:
+ _1 = iv_1 + -1
+ iv_2 = iv_1 & _1
+
+ test:
+ if (iv != 0)
+
+ modification count:
+ popcount (src)
+
+ */
+
+static bool
+number_of_iterations_popcount (loop_p loop, edge exit,
+ enum tree_code code,
+ class tree_niter_desc *niter)
+{
+ bool modify_before_test = true;
+ HOST_WIDE_INT max;
+
+ /* Check that condition for staying inside the loop is like
+ if (iv != 0). */
+ gimple *cond_stmt = last_stmt (exit->src);
+ if (!cond_stmt
+ || gimple_code (cond_stmt) != GIMPLE_COND
+ || code != NE_EXPR
+ || !integer_zerop (gimple_cond_rhs (cond_stmt))
+ || TREE_CODE (gimple_cond_lhs (cond_stmt)) != SSA_NAME)
+ return false;
+
+ tree iv_2 = gimple_cond_lhs (cond_stmt);
+ gimple *iv_2_stmt = SSA_NAME_DEF_STMT (iv_2);
+
+ /* If the test comes before the iv modification, then these will actually be
+ iv_1 and a phi node. */
+ if (gimple_code (iv_2_stmt) == GIMPLE_PHI
+ && gimple_bb (iv_2_stmt) == loop->header
+ && gimple_phi_num_args (iv_2_stmt) == 2
+ && (TREE_CODE (gimple_phi_arg_def (iv_2_stmt,
+ loop_latch_edge (loop)->dest_idx))
+ == SSA_NAME))
+ {
+ /* iv_2 is actually one of the inputs to the phi. */
+ iv_2 = gimple_phi_arg_def (iv_2_stmt, loop_latch_edge (loop)->dest_idx);
+ iv_2_stmt = SSA_NAME_DEF_STMT (iv_2);
+ modify_before_test = false;
+ }
+
+ /* Make sure iv_2_stmt is an and stmt (iv_2 = _1 & iv_1). */
+ if (!is_gimple_assign (iv_2_stmt)
+ || gimple_assign_rhs_code (iv_2_stmt) != BIT_AND_EXPR)
+ return false;
+
+ tree iv_1 = gimple_assign_rhs1 (iv_2_stmt);
+ tree _1 = gimple_assign_rhs2 (iv_2_stmt);
+
+ /* Check that _1 is defined by (_1 = iv_1 + -1).
+ Also make sure that _1 is the same in and_stmt and _1 defining stmt.
+ Also canonicalize if _1 and _b11 are revrsed. */
+ if (ssa_defined_by_minus_one_stmt_p (iv_1, _1))
+ std::swap (iv_1, _1);
+ else if (ssa_defined_by_minus_one_stmt_p (_1, iv_1))
+ ;
+ else
+ return false;
+
+ /* Check the recurrence. */
+ gimple *phi = SSA_NAME_DEF_STMT (iv_1);
+ if (gimple_code (phi) != GIMPLE_PHI
+ || (gimple_bb (phi) != loop_latch_edge (loop)->dest)
+ || (iv_2 != gimple_phi_arg_def (phi, loop_latch_edge (loop)->dest_idx)))
+ return false;
+
+ /* We found a match. */
+ tree src = gimple_phi_arg_def (phi, loop_preheader_edge (loop)->dest_idx);
+ int src_precision = TYPE_PRECISION (TREE_TYPE (src));
+
+ /* Get the corresponding popcount builtin. */
+ tree expr = build_popcount_expr (src);
+
+ if (!expr)
+ return false;
+
+ max = src_precision;
+
+ tree may_be_zero = boolean_false_node;
+
+ if (modify_before_test)
+ {
+ expr = fold_build2 (MINUS_EXPR, integer_type_node, expr,
+ integer_one_node);
+ max = max - 1;
+ may_be_zero = fold_build2 (EQ_EXPR, boolean_type_node, src,
+ build_zero_cst (TREE_TYPE (src)));
+ }
+
+ expr = fold_convert (unsigned_type_node, expr);
+
+ niter->assumptions = boolean_true_node;
+ niter->may_be_zero = simplify_using_initial_conditions (loop, may_be_zero);
+ niter->niter = simplify_using_initial_conditions(loop, expr);
+
+ if (TREE_CODE (niter->niter) == INTEGER_CST)
+ niter->max = tree_to_uhwi (niter->niter);
+ else
+ niter->max = max;
+
+ niter->bound = NULL_TREE;
+ niter->cmp = ERROR_MARK;
+ return true;
+}
+
+/* See if LOOP contains a bit counting idiom. The idiom consists of two parts:
+ 1. A modification to the induction variabler;.
+ 2. A test to determine whether or not to exit the loop.
+
+ These can come in either order - i.e.:
+
+ <bb 3>
+ iv_1 = PHI <src(2), iv_2(4)>
+ if (test (iv_1))
+ goto <bb 4>
+ else
+ goto <bb 5>
+
+ <bb 4>
+ iv_2 = modify (iv_1)
+ goto <bb 3>
+
+ OR
+
+ <bb 3>
+ iv_1 = PHI <src(2), iv_2(4)>
+ iv_2 = modify (iv_1)
+
+ <bb 4>
+ if (test (iv_2))
+ goto <bb 3>
+ else
+ goto <bb 5>
+
+ The second form can be generated by copying the loop header out of the loop.
+
+ In the first case, the number of latch executions will be equal to the
+ number of induction variable modifications required before the test fails.
+
+ In the second case (modify_before_test), if we assume that the number of
+ modifications required before the test fails is nonzero, then the number of
+ latch executions will be one less than this number.
+
+ If we recognise the pattern, then we update niter accordingly, and return
+ true. */
+
+static bool
+number_of_iterations_bitcount (loop_p loop, edge exit,
+ enum tree_code code,
+ class tree_niter_desc *niter)
+{
+ return number_of_iterations_popcount (loop, exit, code, niter);
+}
+
/* Substitute NEW_TREE for OLD in EXPR and fold the result.
If VALUEIZE is non-NULL then OLD and NEW_TREE are ignored and instead
all SSA names are replaced with the result of calling the VALUEIZE
@@ -2537,6 +2753,9 @@ number_of_iterations_exit_assumptions (class loop *loop, edge exit,
if (!stmt)
return false;
+ if (at_stmt)
+ *at_stmt = stmt;
+
/* We want the condition for staying inside loop. */
code = gimple_cond_code (stmt);
if (exit->flags & EDGE_TRUE_VALUE)
@@ -2566,7 +2785,7 @@ number_of_iterations_exit_assumptions (class loop *loop, edge exit,
tree iv0_niters = NULL_TREE;
if (!simple_iv_with_niters (loop, loop_containing_stmt (stmt),
op0, &iv0, safe ? &iv0_niters : NULL, false))
- return number_of_iterations_popcount (loop, exit, code, niter);
+ return number_of_iterations_bitcount (loop, exit, code, niter);
tree iv1_niters = NULL_TREE;
if (!simple_iv_with_niters (loop, loop_containing_stmt (stmt),
op1, &iv1, safe ? &iv1_niters : NULL, false))
@@ -2642,209 +2861,9 @@ number_of_iterations_exit_assumptions (class loop *loop, edge exit,
if (TREE_CODE (niter->niter) == INTEGER_CST)
niter->max = wi::to_widest (niter->niter);
- if (at_stmt)
- *at_stmt = stmt;
-
return (!integer_zerop (niter->assumptions));
}
-
-/* Utility function to check if OP is defined by a stmt
- that is a val - 1. */
-
-static bool
-ssa_defined_by_minus_one_stmt_p (tree op, tree val)
-{
- gimple *stmt;
- return (TREE_CODE (op) == SSA_NAME
- && (stmt = SSA_NAME_DEF_STMT (op))
- && is_gimple_assign (stmt)
- && (gimple_assign_rhs_code (stmt) == PLUS_EXPR)
- && val == gimple_assign_rhs1 (stmt)
- && integer_minus_onep (gimple_assign_rhs2 (stmt)));
-}
-
-
-/* See if LOOP is a popcout implementation, determine NITER for the loop
-
- We match:
- <bb 2>
- goto <bb 4>
-
- <bb 3>
- _1 = b_11 + -1
- b_6 = _1 & b_11
-
- <bb 4>
- b_11 = PHI <b_5(D)(2), b_6(3)>
-
- exit block
- if (b_11 != 0)
- goto <bb 3>
- else
- goto <bb 5>
-
- OR we match copy-header version:
- if (b_5 != 0)
- goto <bb 3>
- else
- goto <bb 4>
-
- <bb 3>
- b_11 = PHI <b_5(2), b_6(3)>
- _1 = b_11 + -1
- b_6 = _1 & b_11
-
- exit block
- if (b_6 != 0)
- goto <bb 3>
- else
- goto <bb 4>
-
- If popcount pattern, update NITER accordingly.
- i.e., set NITER to __builtin_popcount (b)
- return true if we did, false otherwise.
-
- */
-
-static bool
-number_of_iterations_popcount (loop_p loop, edge exit,
- enum tree_code code,
- class tree_niter_desc *niter)
-{
- bool adjust = true;
- tree iter;
- HOST_WIDE_INT max;
- adjust = true;
- tree fn = NULL_TREE;
-
- /* Check loop terminating branch is like
- if (b != 0). */
- gimple *stmt = last_stmt (exit->src);
- if (!stmt
- || gimple_code (stmt) != GIMPLE_COND
- || code != NE_EXPR
- || !integer_zerop (gimple_cond_rhs (stmt))
- || TREE_CODE (gimple_cond_lhs (stmt)) != SSA_NAME)
- return false;
-
- gimple *and_stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (stmt));
-
- /* Depending on copy-header is performed, feeding PHI stmts might be in
- the loop header or loop latch, handle this. */
- if (gimple_code (and_stmt) == GIMPLE_PHI
- && gimple_bb (and_stmt) == loop->header
- && gimple_phi_num_args (and_stmt) == 2
- && (TREE_CODE (gimple_phi_arg_def (and_stmt,
- loop_latch_edge (loop)->dest_idx))
- == SSA_NAME))
- {
- /* SSA used in exit condition is defined by PHI stmt
- b_11 = PHI <b_5(D)(2), b_6(3)>
- from the PHI stmt, get the and_stmt
- b_6 = _1 & b_11. */
- tree t = gimple_phi_arg_def (and_stmt, loop_latch_edge (loop)->dest_idx);
- and_stmt = SSA_NAME_DEF_STMT (t);
- adjust = false;
- }
-
- /* Make sure it is indeed an and stmt (b_6 = _1 & b_11). */
- if (!is_gimple_assign (and_stmt)
- || gimple_assign_rhs_code (and_stmt) != BIT_AND_EXPR)
- return false;
-
- tree b_11 = gimple_assign_rhs1 (and_stmt);
- tree _1 = gimple_assign_rhs2 (and_stmt);
-
- /* Check that _1 is defined by _b11 + -1 (_1 = b_11 + -1).
- Also make sure that b_11 is the same in and_stmt and _1 defining stmt.
- Also canonicalize if _1 and _b11 are revrsed. */
- if (ssa_defined_by_minus_one_stmt_p (b_11, _1))
- std::swap (b_11, _1);
- else if (ssa_defined_by_minus_one_stmt_p (_1, b_11))
- ;
- else
- return false;
- /* Check the recurrence:
- ... = PHI <b_5(2), b_6(3)>. */
- gimple *phi = SSA_NAME_DEF_STMT (b_11);
- if (gimple_code (phi) != GIMPLE_PHI
- || (gimple_bb (phi) != loop_latch_edge (loop)->dest)
- || (gimple_assign_lhs (and_stmt)
- != gimple_phi_arg_def (phi, loop_latch_edge (loop)->dest_idx)))
- return false;
-
- /* We found a match. Get the corresponding popcount builtin. */
- tree src = gimple_phi_arg_def (phi, loop_preheader_edge (loop)->dest_idx);
- if (TYPE_PRECISION (TREE_TYPE (src)) <= TYPE_PRECISION (integer_type_node))
- fn = builtin_decl_implicit (BUILT_IN_POPCOUNT);
- else if (TYPE_PRECISION (TREE_TYPE (src))
- == TYPE_PRECISION (long_integer_type_node))
- fn = builtin_decl_implicit (BUILT_IN_POPCOUNTL);
- else if (TYPE_PRECISION (TREE_TYPE (src))
- == TYPE_PRECISION (long_long_integer_type_node)
- || (TYPE_PRECISION (TREE_TYPE (src))
- == 2 * TYPE_PRECISION (long_long_integer_type_node)))
- fn = builtin_decl_implicit (BUILT_IN_POPCOUNTLL);
-
- if (!fn)
- return false;
-
- /* Update NITER params accordingly */
- tree utype = unsigned_type_for (TREE_TYPE (src));
- src = fold_convert (utype, src);
- if (TYPE_PRECISION (TREE_TYPE (src)) < TYPE_PRECISION (integer_type_node))
- src = fold_convert (unsigned_type_node, src);
- tree call;
- if (TYPE_PRECISION (TREE_TYPE (src))
- == 2 * TYPE_PRECISION (long_long_integer_type_node))
- {
- int prec = TYPE_PRECISION (long_long_integer_type_node);
- tree src1 = fold_convert (long_long_unsigned_type_node,
- fold_build2 (RSHIFT_EXPR, TREE_TYPE (src),
- unshare_expr (src),
- build_int_cst (integer_type_node,
- prec)));
- tree src2 = fold_convert (long_long_unsigned_type_node, src);
- call = build_call_expr (fn, 1, src1);
- call = fold_build2 (PLUS_EXPR, TREE_TYPE (call), call,
- build_call_expr (fn, 1, src2));
- call = fold_convert (utype, call);
- }
- else
- call = fold_convert (utype, build_call_expr (fn, 1, src));
- if (adjust)
- iter = fold_build2 (MINUS_EXPR, utype, call, build_int_cst (utype, 1));
- else
- iter = call;
-
- if (TREE_CODE (call) == INTEGER_CST)
- max = tree_to_uhwi (call);
- else
- max = TYPE_PRECISION (TREE_TYPE (src));
- if (adjust)
- max = max - 1;
-
- niter->niter = iter;
- niter->assumptions = boolean_true_node;
-
- if (adjust)
- {
- tree may_be_zero = fold_build2 (EQ_EXPR, boolean_type_node, src,
- build_zero_cst (TREE_TYPE (src)));
- niter->may_be_zero
- = simplify_using_initial_conditions (loop, may_be_zero);
- }
- else
- niter->may_be_zero = boolean_false_node;
-
- niter->max = max;
- niter->bound = NULL_TREE;
- niter->cmp = ERROR_MARK;
- return true;
-}
-
-
/* Like number_of_iterations_exit_assumptions, but return TRUE only if
the niter information holds unconditionally. */
@@ -3716,18 +3735,17 @@ idx_infer_loop_bounds (tree base, tree *idx, void *dta)
struct ilb_data *data = (struct ilb_data *) dta;
tree ev, init, step;
tree low, high, type, next;
- bool sign, upper = true, at_end = false;
+ bool sign, upper = true, has_flexible_size = false;
class loop *loop = data->loop;
if (TREE_CODE (base) != ARRAY_REF)
return true;
- /* For arrays at the end of the structure, we are not guaranteed that they
- do not really extend over their declared size. However, for arrays of
- size greater than one, this is unlikely to be intended. */
- if (array_at_struct_end_p (base))
+ /* For arrays that might have flexible sizes, it is not guaranteed that they
+ do not really extend over their declared size. */
+ if (array_ref_flexible_size_p (base))
{
- at_end = true;
+ has_flexible_size = true;
upper = false;
}
@@ -3760,9 +3778,9 @@ idx_infer_loop_bounds (tree base, tree *idx, void *dta)
sign = tree_int_cst_sign_bit (step);
type = TREE_TYPE (step);
- /* The array of length 1 at the end of a structure most likely extends
+ /* The array that might have flexible size most likely extends
beyond its bounds. */
- if (at_end
+ if (has_flexible_size
&& operand_equal_p (low, high, 0))
return true;
diff --git a/gcc/tree-ssa-loop-unswitch.cc b/gcc/tree-ssa-loop-unswitch.cc
index 7d6781d..df7a201 100644
--- a/gcc/tree-ssa-loop-unswitch.cc
+++ b/gcc/tree-ssa-loop-unswitch.cc
@@ -118,6 +118,7 @@ struct unswitch_predicate
if (!false_range.varying_p ()
&& !false_range.undefined_p ())
false_range.invert ();
+ count = e->count ();
num = predicates->length ();
predicates->safe_push (this);
}
@@ -126,7 +127,8 @@ struct unswitch_predicate
unswitch_predicate (gcond *stmt)
: switch_p (false)
{
- if (EDGE_SUCC (gimple_bb (stmt), 0)->flags & EDGE_TRUE_VALUE)
+ basic_block bb = gimple_bb (stmt);
+ if (EDGE_SUCC (bb, 0)->flags & EDGE_TRUE_VALUE)
edge_index = 0;
else
edge_index = 1;
@@ -134,6 +136,7 @@ struct unswitch_predicate
tree rhs = gimple_cond_rhs (stmt);
enum tree_code code = gimple_cond_code (stmt);
condition = build2 (code, boolean_type_node, lhs, rhs);
+ count = EDGE_SUCC (bb, 0)->count ().max (EDGE_SUCC (bb, 1)->count ());
if (irange::supports_p (TREE_TYPE (lhs)))
{
auto range_op = range_op_handler (code, TREE_TYPE (lhs));
@@ -180,6 +183,9 @@ struct unswitch_predicate
/* Index of the edge the predicate belongs to in the successor vector. */
int edge_index;
+ /* The profile count of this predicate. */
+ profile_count count;
+
/* Whether the predicate was created from a switch statement. */
bool switch_p;
@@ -206,10 +212,15 @@ static class loop *tree_unswitch_loop (class loop *, edge, tree);
static bool tree_unswitch_single_loop (class loop *, dump_user_location_t,
predicate_vector &predicate_path,
unsigned loop_size, unsigned &budget,
- int ignored_edge_flag, bitmap);
+ int ignored_edge_flag, bitmap,
+ unswitch_predicate * = NULL,
+ basic_block = NULL);
static void
find_unswitching_predicates_for_bb (basic_block bb, class loop *loop,
- vec<unswitch_predicate *> &candidates);
+ class loop *&outer_loop,
+ vec<unswitch_predicate *> &candidates,
+ unswitch_predicate *&hottest,
+ basic_block &hottest_bb);
static bool tree_unswitch_outer_loop (class loop *);
static edge find_loop_guard (class loop *, vec<gimple *>&);
static bool empty_bb_without_guard_p (class loop *, basic_block,
@@ -239,33 +250,34 @@ set_predicates_for_bb (basic_block bb, vec<unswitch_predicate *> predicates)
}
/* Initialize LOOP information reused during the unswitching pass.
- Return total number of instructions in the loop. */
+ Return total number of instructions in the loop. Adjusts LOOP to
+ the outermost loop all candidates are invariant in. */
static unsigned
-init_loop_unswitch_info (class loop *loop)
+init_loop_unswitch_info (class loop *&loop, unswitch_predicate *&hottest,
+ basic_block &hottest_bb)
{
unsigned total_insns = 0;
- /* Calculate instruction count. */
basic_block *bbs = get_loop_body (loop);
- for (unsigned i = 0; i < loop->num_nodes; i++)
- {
- unsigned insns = 0;
- for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi);
- gsi_next (&gsi))
- insns += estimate_num_insns (gsi_stmt (gsi), &eni_size_weights);
-
- bbs[i]->aux = (void *)(uintptr_t)insns;
- total_insns += insns;
- }
- /* Find all unswitching candidates. */
+ /* Unswitch only nests with no sibling loops. */
+ class loop *outer_loop = loop;
+ unsigned max_depth = param_max_unswitch_depth;
+ while (loop_outer (outer_loop)->num != 0
+ && !loop_outer (outer_loop)->inner->next
+ && --max_depth != 0)
+ outer_loop = loop_outer (outer_loop);
+ hottest = NULL;
+ hottest_bb = NULL;
+ /* Find all unswitching candidates in the innermost loop. */
for (unsigned i = 0; i != loop->num_nodes; i++)
{
/* Find a bb to unswitch on. */
vec<unswitch_predicate *> candidates;
candidates.create (1);
- find_unswitching_predicates_for_bb (bbs[i], loop, candidates);
+ find_unswitching_predicates_for_bb (bbs[i], loop, outer_loop, candidates,
+ hottest, hottest_bb);
if (!candidates.is_empty ())
set_predicates_for_bb (bbs[i], candidates);
else
@@ -277,8 +289,34 @@ init_loop_unswitch_info (class loop *loop)
}
}
+ if (outer_loop != loop)
+ {
+ free (bbs);
+ bbs = get_loop_body (outer_loop);
+ }
+
+ /* Calculate instruction count. */
+ for (unsigned i = 0; i < outer_loop->num_nodes; i++)
+ {
+ unsigned insns = 0;
+ for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi);
+ gsi_next (&gsi))
+ insns += estimate_num_insns (gsi_stmt (gsi), &eni_size_weights);
+ /* No predicates to unswitch on in the outer loops. */
+ if (!flow_bb_inside_loop_p (loop, bbs[i]))
+ {
+ gimple *last = last_stmt (bbs[i]);
+ if (last != NULL)
+ gimple_set_uid (last, 0);
+ }
+
+ bbs[i]->aux = (void *)(uintptr_t)insns;
+ total_insns += insns;
+ }
+
free (bbs);
+ loop = outer_loop;
return total_insns;
}
@@ -293,68 +331,74 @@ tree_ssa_unswitch_loops (function *fun)
ranger = enable_ranger (fun);
- /* Go through all loops starting from innermost. */
+ /* Go through all loops starting from innermost, hoisting guards. */
for (auto loop : loops_list (fun, LI_FROM_INNERMOST))
{
- if (!loop->inner)
- {
- /* Perform initial tests if unswitch is eligible. */
- dump_user_location_t loc = find_loop_location (loop);
+ if (loop->inner)
+ changed_hoist |= tree_unswitch_outer_loop (loop);
+ }
- /* Do not unswitch in cold regions. */
- if (optimize_loop_for_size_p (loop))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, loc,
- "Not unswitching cold loops\n");
- continue;
- }
+ /* Go through innermost loops, unswitching on invariant predicates
+ within those. */
+ for (auto loop : loops_list (fun, LI_ONLY_INNERMOST))
+ {
+ /* Perform initial tests if unswitch is eligible. */
+ dump_user_location_t loc = find_loop_location (loop);
- /* If the loop is not expected to iterate, there is no need
- for unswitching. */
- HOST_WIDE_INT iterations = estimated_loop_iterations_int (loop);
- if (iterations < 0)
- iterations = likely_max_loop_iterations_int (loop);
- if (iterations >= 0 && iterations <= 1)
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, loc,
- "Not unswitching, loop is not expected"
- " to iterate\n");
- continue;
- }
+ /* Do not unswitch in cold regions. */
+ if (optimize_loop_for_size_p (loop))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, loc,
+ "Not unswitching cold loops\n");
+ continue;
+ }
- bb_predicates = new vec<vec<unswitch_predicate *>> ();
- bb_predicates->safe_push (vec<unswitch_predicate *> ());
- unswitch_predicate::predicates = new vec<unswitch_predicate *> ();
-
- /* Unswitch innermost loop. */
- unsigned int loop_size = init_loop_unswitch_info (loop);
- unsigned int budget = loop_size + param_max_unswitch_insns;
-
- predicate_vector predicate_path;
- predicate_path.create (8);
- auto_bitmap handled;
- changed_unswitch
- |= tree_unswitch_single_loop (loop, loc, predicate_path,
- loop_size, budget,
- ignored_edge_flag, handled);
- predicate_path.release ();
-
- for (auto predlist : bb_predicates)
- predlist.release ();
- bb_predicates->release ();
- delete bb_predicates;
- bb_predicates = NULL;
-
- for (auto pred : unswitch_predicate::predicates)
- delete pred;
- unswitch_predicate::predicates->release ();
- delete unswitch_predicate::predicates;
- unswitch_predicate::predicates = NULL;
+ /* If the loop is not expected to iterate, there is no need
+ for unswitching. */
+ HOST_WIDE_INT iterations = estimated_loop_iterations_int (loop);
+ if (iterations < 0)
+ iterations = likely_max_loop_iterations_int (loop);
+ if (iterations >= 0 && iterations <= 1)
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, loc,
+ "Not unswitching, loop is not expected"
+ " to iterate\n");
+ continue;
}
- else
- changed_hoist |= tree_unswitch_outer_loop (loop);
+
+ bb_predicates = new vec<vec<unswitch_predicate *>> ();
+ bb_predicates->safe_push (vec<unswitch_predicate *> ());
+ unswitch_predicate::predicates = new vec<unswitch_predicate *> ();
+
+ /* Unswitch loop. */
+ unswitch_predicate *hottest;
+ basic_block hottest_bb;
+ unsigned int loop_size = init_loop_unswitch_info (loop, hottest,
+ hottest_bb);
+ unsigned int budget = loop_size + param_max_unswitch_insns;
+
+ predicate_vector predicate_path;
+ predicate_path.create (8);
+ auto_bitmap handled;
+ changed_unswitch |= tree_unswitch_single_loop (loop, loc, predicate_path,
+ loop_size, budget,
+ ignored_edge_flag, handled,
+ hottest, hottest_bb);
+ predicate_path.release ();
+
+ for (auto predlist : bb_predicates)
+ predlist.release ();
+ bb_predicates->release ();
+ delete bb_predicates;
+ bb_predicates = NULL;
+
+ for (auto pred : unswitch_predicate::predicates)
+ delete pred;
+ unswitch_predicate::predicates->release ();
+ delete unswitch_predicate::predicates;
+ unswitch_predicate::predicates = NULL;
}
disable_ranger (fun);
@@ -445,11 +489,16 @@ is_maybe_undefined (const tree name, gimple *stmt, class loop *loop)
/* Checks whether we can unswitch LOOP on condition at end of BB -- one of its
basic blocks (for what it means see comments below).
- All candidates all filled to the provided vector CANDIDATES. */
+ All candidates all filled to the provided vector CANDIDATES.
+ OUTER_LOOP is updated to the innermost loop all found candidates are
+ invariant in. */
static void
find_unswitching_predicates_for_bb (basic_block bb, class loop *loop,
- vec<unswitch_predicate *> &candidates)
+ class loop *&outer_loop,
+ vec<unswitch_predicate *> &candidates,
+ unswitch_predicate *&hottest,
+ basic_block &hottest_bb)
{
gimple *last, *def;
tree use;
@@ -486,9 +535,29 @@ find_unswitching_predicates_for_bb (basic_block bb, class loop *loop,
if (is_maybe_undefined (use, stmt, loop))
return;
}
+ /* Narrow OUTER_LOOP. */
+ if (outer_loop != loop)
+ FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
+ {
+ def = SSA_NAME_DEF_STMT (use);
+ def_bb = gimple_bb (def);
+ while (outer_loop != loop
+ && ((def_bb && flow_bb_inside_loop_p (outer_loop, def_bb))
+ || is_maybe_undefined (use, stmt, outer_loop)))
+ outer_loop = superloop_at_depth (loop,
+ loop_depth (outer_loop) + 1);
+ }
unswitch_predicate *predicate = new unswitch_predicate (stmt);
candidates.safe_push (predicate);
+ /* If we unswitch on this predicate we isolate both paths, so
+ pick the highest count for updating of the hottest predicate
+ to unswitch on first. */
+ if (!hottest || predicate->count > hottest->count)
+ {
+ hottest = predicate;
+ hottest_bb = bb;
+ }
}
else if (gswitch *stmt = safe_dyn_cast <gswitch *> (last))
{
@@ -507,6 +576,12 @@ find_unswitching_predicates_for_bb (basic_block bb, class loop *loop,
behavior that the original program might never exercise. */
if (is_maybe_undefined (idx, stmt, loop))
return;
+ /* Narrow OUTER_LOOP. */
+ while (outer_loop != loop
+ && ((def_bb && flow_bb_inside_loop_p (outer_loop, def_bb))
+ || is_maybe_undefined (idx, stmt, outer_loop)))
+ outer_loop = superloop_at_depth (loop,
+ loop_depth (outer_loop) + 1);
/* Build compound expression for all outgoing edges of the switch. */
auto_vec<tree, 16> preds;
@@ -561,6 +636,11 @@ find_unswitching_predicates_for_bb (basic_block bb, class loop *loop,
edge_index, e,
edge_range[edge_index]);
candidates.safe_push (predicate);
+ if (!hottest || predicate->count > hottest->count)
+ {
+ hottest = predicate;
+ hottest_bb = bb;
+ }
}
}
}
@@ -839,7 +919,7 @@ evaluate_bbs (class loop *loop, predicate_vector *predicate_path,
{
basic_block dest = e->dest;
- if (dest->loop_father == loop
+ if (flow_bb_inside_loop_p (loop, dest)
&& !(dest->flags & reachable_flag)
&& !(e->flags & flags)
&& !ignored_edges.contains (e))
@@ -888,13 +968,15 @@ evaluate_loop_insns_for_predicate (class loop *loop,
/* Unswitch single LOOP. PREDICATE_PATH contains so far used predicates
for unswitching. BUDGET is number of instruction for which we can increase
- the loop and is updated when unswitching occurs. */
+ the loop and is updated when unswitching occurs. If HOTTEST is not
+ NULL then pick this candidate as the one to unswitch on. */
static bool
tree_unswitch_single_loop (class loop *loop, dump_user_location_t loc,
predicate_vector &predicate_path,
unsigned loop_size, unsigned &budget,
- int ignored_edge_flag, bitmap handled)
+ int ignored_edge_flag, bitmap handled,
+ unswitch_predicate *hottest, basic_block hottest_bb)
{
class loop *nloop;
bool changed = false;
@@ -939,8 +1021,15 @@ tree_unswitch_single_loop (class loop *loop, dump_user_location_t loc,
}
return false;
};
- /* Check predicates of reachable blocks. */
- evaluate_bbs (loop, NULL, ignored_edge_flag, check_predicates);
+
+ if (hottest)
+ {
+ predicate = hottest;
+ predicate_bb = hottest_bb;
+ }
+ else
+ /* Check predicates of reachable blocks. */
+ evaluate_bbs (loop, NULL, ignored_edge_flag, check_predicates);
if (predicate != NULL)
{
@@ -950,7 +1039,8 @@ tree_unswitch_single_loop (class loop *loop, dump_user_location_t loc,
if (dump_enabled_p ())
{
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
- "unswitching loop %d on %qs with condition: %T\n",
+ "unswitching %sloop %d on %qs with condition: %T\n",
+ loop->inner ? "outer " : "",
loop->num, predicate->switch_p ? "switch" : "if",
predicate->condition);
dump_printf_loc (MSG_NOTE, loc,
@@ -1022,7 +1112,6 @@ tree_unswitch_loop (class loop *loop, edge edge_true, tree cond)
/* Some sanity checking. */
gcc_assert (flow_bb_inside_loop_p (loop, edge_true->src));
gcc_assert (EDGE_COUNT (edge_true->src->succs) >= 2);
- gcc_assert (loop->inner == NULL);
profile_probability prob_true = edge_true->probability;
return loop_version (loop, unshare_expr (cond),
@@ -1544,6 +1633,7 @@ clean_up_after_unswitching (int ignored_edge_flag)
basic_block bb;
edge e;
edge_iterator ei;
+ bool removed_edge = false;
FOR_EACH_BB_FN (bb, cfun)
{
@@ -1568,7 +1658,10 @@ clean_up_after_unswitching (int ignored_edge_flag)
to preserve its edge. But we can remove the
non-default CASE sharing the edge. */
if (e != default_e)
- remove_edge (e);
+ {
+ remove_edge (e);
+ removed_edge = true;
+ }
}
else
{
@@ -1585,6 +1678,10 @@ clean_up_after_unswitching (int ignored_edge_flag)
FOR_EACH_EDGE (e, ei, bb->succs)
e->flags &= ~ignored_edge_flag;
}
+
+ /* If we removed an edge we possibly have to recompute dominators. */
+ if (removed_edge)
+ free_dominance_info (CDI_DOMINATORS);
}
/* Loop unswitching pass. */
diff --git a/gcc/tree-ssa-loop.h b/gcc/tree-ssa-loop.h
index 6c70f79..c24215b 100644
--- a/gcc/tree-ssa-loop.h
+++ b/gcc/tree-ssa-loop.h
@@ -52,7 +52,8 @@ public:
may_be_zero == false), more precisely the number
of executions of the latch of the loop. */
widest_int max; /* The upper bound on the number of iterations of
- the loop. */
+ the loop. If niter is constant, then these values
+ must agree. */
/* The simplified shape of the exit condition. This information is used by
loop unrolling. If CMP is ERROR_MARK, then the loop cannot be unrolled.
diff --git a/gcc/tree-ssa-operands.cc b/gcc/tree-ssa-operands.cc
index 4915622..4c90197 100644
--- a/gcc/tree-ssa-operands.cc
+++ b/gcc/tree-ssa-operands.cc
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "stmt.h"
#include "print-tree.h"
#include "dumpfile.h"
+#include "value-query.h"
/* This file contains the code required to manage the operands cache of the
@@ -896,7 +897,6 @@ operands_scanner::get_expr_operands (tree *expr_p, int flags)
case BIT_INSERT_EXPR:
case COMPOUND_EXPR:
case OBJ_TYPE_REF:
- case ASSERT_EXPR:
do_binary:
{
get_expr_operands (&TREE_OPERAND (expr, 0), flags);
@@ -1146,6 +1146,8 @@ update_stmt_operands (struct function *fn, gimple *stmt)
gcc_assert (gimple_modified_p (stmt));
operands_scanner (fn, stmt).build_ssa_operands ();
gimple_set_modified (stmt, false);
+ // Inform the active range query an update has happened.
+ get_range_query (fn)->update_stmt (stmt);
timevar_pop (TV_TREE_OPS);
}
diff --git a/gcc/tree-ssa-propagate.cc b/gcc/tree-ssa-propagate.cc
index 9dc4bfd..976b035 100644
--- a/gcc/tree-ssa-propagate.cc
+++ b/gcc/tree-ssa-propagate.cc
@@ -671,12 +671,14 @@ public:
stmts_to_remove.create (0);
stmts_to_fixup.create (0);
need_eh_cleanup = BITMAP_ALLOC (NULL);
+ need_ab_cleanup = BITMAP_ALLOC (NULL);
}
~substitute_and_fold_dom_walker ()
{
stmts_to_remove.release ();
stmts_to_fixup.release ();
BITMAP_FREE (need_eh_cleanup);
+ BITMAP_FREE (need_ab_cleanup);
}
edge before_dom_children (basic_block) final override;
@@ -689,6 +691,7 @@ public:
vec<gimple *> stmts_to_remove;
vec<gimple *> stmts_to_fixup;
bitmap need_eh_cleanup;
+ bitmap need_ab_cleanup;
class substitute_and_fold_engine *substitute_and_fold_engine;
@@ -818,10 +821,7 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb)
&& sprime != lhs
&& may_propagate_copy (lhs, sprime)
&& !stmt_could_throw_p (cfun, stmt)
- && !gimple_has_side_effects (stmt)
- /* We have to leave ASSERT_EXPRs around for jump-threading. */
- && (!is_gimple_assign (stmt)
- || gimple_assign_rhs_code (stmt) != ASSERT_EXPR))
+ && !gimple_has_side_effects (stmt))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -838,8 +838,13 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb)
folded. */
did_replace = false;
gimple *old_stmt = stmt;
- bool was_noreturn = (is_gimple_call (stmt)
- && gimple_call_noreturn_p (stmt));
+ bool was_noreturn = false;
+ bool can_make_abnormal_goto = false;
+ if (is_gimple_call (stmt))
+ {
+ was_noreturn = gimple_call_noreturn_p (stmt);
+ can_make_abnormal_goto = stmt_can_make_abnormal_goto (stmt);
+ }
/* Replace real uses in the statement. */
did_replace |= substitute_and_fold_engine->replace_uses_in (stmt);
@@ -905,6 +910,12 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb)
if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
bitmap_set_bit (need_eh_cleanup, bb->index);
+ /* If we turned a call with possible abnormal control transfer
+ into one that doesn't, remove abnormal edges. */
+ if (can_make_abnormal_goto
+ && !stmt_can_make_abnormal_goto (stmt))
+ bitmap_set_bit (need_ab_cleanup, bb->index);
+
/* If we turned a not noreturn call into a noreturn one
schedule it for fixup. */
if (!was_noreturn
@@ -1012,6 +1023,8 @@ substitute_and_fold_engine::substitute_and_fold (basic_block block)
if (!bitmap_empty_p (walker.need_eh_cleanup))
gimple_purge_all_dead_eh_edges (walker.need_eh_cleanup);
+ if (!bitmap_empty_p (walker.need_ab_cleanup))
+ gimple_purge_all_dead_abnormal_call_edges (walker.need_ab_cleanup);
/* Fixup stmts that became noreturn calls. This may require splitting
blocks and thus isn't possible during the dominator walk. Do this
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 3748440..b9f289b 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -5793,7 +5793,8 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p)
/* See if all non-TOP arguments have the same value. TOP is
equivalent to everything, so we can ignore it. */
- FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
+ basic_block bb = gimple_bb (phi);
+ FOR_EACH_EDGE (e, ei, bb->preds)
if (e->flags & EDGE_EXECUTABLE)
{
tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
@@ -5838,6 +5839,59 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p)
&& known_eq (soff, doff))
continue;
}
+ /* There's also the possibility to use equivalences. */
+ if (!FLOAT_TYPE_P (TREE_TYPE (def))
+ /* But only do this if we didn't force any of sameval or
+ val to VARYING because of backedge processing rules. */
+ && (TREE_CODE (sameval) != SSA_NAME
+ || SSA_VAL (sameval) == sameval)
+ && (TREE_CODE (def) != SSA_NAME || SSA_VAL (def) == def))
+ {
+ vn_nary_op_t vnresult;
+ tree ops[2];
+ ops[0] = def;
+ ops[1] = sameval;
+ tree val = vn_nary_op_lookup_pieces (2, EQ_EXPR,
+ boolean_type_node,
+ ops, &vnresult);
+ if (! val && vnresult && vnresult->predicated_values)
+ {
+ val = vn_nary_op_get_predicated_value (vnresult, e->src);
+ if (val && integer_truep (val))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Predication says ");
+ print_generic_expr (dump_file, def, TDF_NONE);
+ fprintf (dump_file, " and ");
+ print_generic_expr (dump_file, sameval, TDF_NONE);
+ fprintf (dump_file, " are equal on edge %d -> %d\n",
+ e->src->index, e->dest->index);
+ }
+ continue;
+ }
+ /* If on all previous edges the value was equal to def
+ we can change sameval to def. */
+ if (EDGE_COUNT (bb->preds) == 2
+ && (val = vn_nary_op_get_predicated_value
+ (vnresult, EDGE_PRED (bb, 0)->src))
+ && integer_truep (val))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Predication says ");
+ print_generic_expr (dump_file, def, TDF_NONE);
+ fprintf (dump_file, " and ");
+ print_generic_expr (dump_file, sameval, TDF_NONE);
+ fprintf (dump_file, " are equal on edge %d -> %d\n",
+ EDGE_PRED (bb, 0)->src->index,
+ EDGE_PRED (bb, 0)->dest->index);
+ }
+ sameval = def;
+ continue;
+ }
+ }
+ }
sameval = NULL_TREE;
break;
}
diff --git a/gcc/tree-ssa-sink.cc b/gcc/tree-ssa-sink.cc
index 9213052..eb7c2e6 100644
--- a/gcc/tree-ssa-sink.cc
+++ b/gcc/tree-ssa-sink.cc
@@ -263,12 +263,13 @@ statement_sink_location (gimple *stmt, basic_block frombb,
*zero_uses_p = false;
- /* We only can sink assignments and non-looping const/pure calls. */
+ /* We only can sink assignments and const/pure calls that are guaranteed
+ to return exactly once. */
int cf;
if (!is_gimple_assign (stmt)
&& (!is_gimple_call (stmt)
|| !((cf = gimple_call_flags (stmt)) & (ECF_CONST|ECF_PURE))
- || (cf & ECF_LOOPING_CONST_OR_PURE)))
+ || (cf & (ECF_LOOPING_CONST_OR_PURE|ECF_RETURNS_TWICE))))
return false;
/* We only can sink stmts with a single definition. */
diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc
index 5afbae1..abec225 100644
--- a/gcc/tree-ssa-strlen.cc
+++ b/gcc/tree-ssa-strlen.cc
@@ -1987,7 +1987,7 @@ maybe_set_strlen_range (tree lhs, tree src, tree bound)
suggests if it's treated as a poor-man's flexible array member. */
src = TREE_OPERAND (src, 0);
if (TREE_CODE (src) != MEM_REF
- && !array_at_struct_end_p (src))
+ && !array_ref_flexible_size_p (src))
{
tree type = TREE_TYPE (src);
tree size = TYPE_SIZE_UNIT (type);
@@ -4735,7 +4735,7 @@ strlen_pass::count_nonzero_bytes (tree exp, gimple *stmt,
/* Compute the number of leading nonzero bytes in the representation
and update the minimum and maximum. */
- unsigned n = prep ? strnlen (prep, nbytes) : nbytes;
+ unsigned HOST_WIDE_INT n = prep ? strnlen (prep, nbytes) : nbytes;
if (n < lenrange[0])
lenrange[0] = n;
diff --git a/gcc/tree-ssa-threadbackward.cc b/gcc/tree-ssa-threadbackward.cc
index 2a8cfa3..2290b95 100644
--- a/gcc/tree-ssa-threadbackward.cc
+++ b/gcc/tree-ssa-threadbackward.cc
@@ -249,25 +249,16 @@ back_threader::maybe_register_path (back_threader_profitability &profit)
if (taken_edge && taken_edge != UNREACHABLE_EDGE)
{
- if (m_visited_bbs.contains (taken_edge->dest))
+ bool irreducible = false;
+ if (profit.profitable_path_p (m_path, taken_edge, &irreducible)
+ && debug_counter ()
+ && m_registry.register_path (m_path, taken_edge))
{
- // Avoid circular paths by indicating there is nothing to
- // see in this direction.
- taken_edge = UNREACHABLE_EDGE;
+ if (irreducible)
+ vect_free_loop_info_assumptions (m_path[0]->loop_father);
}
else
- {
- bool irreducible = false;
- if (profit.profitable_path_p (m_path, taken_edge, &irreducible)
- && debug_counter ()
- && m_registry.register_path (m_path, taken_edge))
- {
- if (irreducible)
- vect_free_loop_info_assumptions (m_path[0]->loop_father);
- }
- else
- taken_edge = NULL;
- }
+ taken_edge = NULL;
}
if (dump_file && (dump_flags & TDF_DETAILS))
diff --git a/gcc/tree-ssa-threadedge.cc b/gcc/tree-ssa-threadedge.cc
index 905a98c..cc7020d 100644
--- a/gcc/tree-ssa-threadedge.cc
+++ b/gcc/tree-ssa-threadedge.cc
@@ -497,9 +497,9 @@ jump_threader::simplify_control_stmt_condition_1
}
/* If the condition has the form (A & B) CMP 0 or (A | B) CMP 0 then
- recurse into the LHS to see if there is a dominating ASSERT_EXPR
- of A or of B that makes this condition always true or always false
- along the edge E. */
+ recurse into the LHS to see if there is a simplification that
+ makes this condition always true or always false along the edge
+ E. */
if ((cond_code == EQ_EXPR || cond_code == NE_EXPR)
&& TREE_CODE (op0) == SSA_NAME
&& integer_zerop (op1))
diff --git a/gcc/tree-ssa-uninit.cc b/gcc/tree-ssa-uninit.cc
index bf2e505..7fbc384 100644
--- a/gcc/tree-ssa-uninit.cc
+++ b/gcc/tree-ssa-uninit.cc
@@ -1249,8 +1249,8 @@ find_uninit_use (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
if (dump_file && (dump_flags & TDF_DETAILS))
{
- fprintf (dump_file, "Found unguarded use in bb %u: ",
- use_bb->index);
+ fprintf (dump_file, "Found unguarded use on edge %u -> %u: ",
+ e->src->index, e->dest->index);
print_gimple_stmt (dump_file, use_stmt, 0);
}
/* Found a phi use that is not guarded, mark the phi_result as
diff --git a/gcc/tree-ssa.cc b/gcc/tree-ssa.cc
index 1a93ffd..5dedc09 100644
--- a/gcc/tree-ssa.cc
+++ b/gcc/tree-ssa.cc
@@ -1400,6 +1400,99 @@ gimple_uses_undefined_value_p (gimple *stmt)
}
+/* Return TRUE iff there are any non-PHI uses of VAR that dominate the
+ end of BB. If we return TRUE and BB is a loop header, then VAR we
+ be assumed to be defined within the loop, even if it is marked as
+ maybe-undefined. */
+
+bool
+ssa_name_any_use_dominates_bb_p (tree var, basic_block bb)
+{
+ imm_use_iterator iter;
+ use_operand_p use_p;
+ FOR_EACH_IMM_USE_FAST (use_p, iter, var)
+ {
+ if (is_a <gphi *> (USE_STMT (use_p))
+ || is_gimple_debug (USE_STMT (use_p)))
+ continue;
+ basic_block dombb = gimple_bb (USE_STMT (use_p));
+ if (dominated_by_p (CDI_DOMINATORS, bb, dombb))
+ return true;
+ }
+
+ return false;
+}
+
+/* Mark as maybe_undef any SSA_NAMEs that are unsuitable as ivopts
+ candidates for potentially involving undefined behavior. */
+
+void
+mark_ssa_maybe_undefs (void)
+{
+ auto_vec<tree> queue;
+
+ /* Scan all SSA_NAMEs, marking the definitely-undefined ones as
+ maybe-undefined and queuing them for propagation, while clearing
+ the mark on others. */
+ unsigned int i;
+ tree var;
+ FOR_EACH_SSA_NAME (i, var, cfun)
+ {
+ if (SSA_NAME_IS_VIRTUAL_OPERAND (var)
+ || !ssa_undefined_value_p (var, false))
+ ssa_name_set_maybe_undef (var, false);
+ else
+ {
+ ssa_name_set_maybe_undef (var);
+ queue.safe_push (var);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "marking _%i as maybe-undef\n",
+ SSA_NAME_VERSION (var));
+ }
+ }
+
+ /* Now propagate maybe-undefined from a DEF to any other PHI that
+ uses it, as long as there isn't any intervening use of DEF. */
+ while (!queue.is_empty ())
+ {
+ var = queue.pop ();
+ imm_use_iterator iter;
+ use_operand_p use_p;
+ FOR_EACH_IMM_USE_FAST (use_p, iter, var)
+ {
+ /* Any uses of VAR that aren't PHI args imply VAR must be
+ defined, otherwise undefined behavior would have been
+ definitely invoked. Only PHI args may hold
+ maybe-undefined values without invoking undefined
+ behavior for that reason alone. */
+ if (!is_a <gphi *> (USE_STMT (use_p)))
+ continue;
+ gphi *phi = as_a <gphi *> (USE_STMT (use_p));
+
+ tree def = gimple_phi_result (phi);
+ if (ssa_name_maybe_undef_p (def))
+ continue;
+
+ /* Look for any uses of the maybe-unused SSA_NAME that
+ dominates the block that reaches the incoming block
+ corresponding to the PHI arg in which it is mentioned.
+ That means we can assume the SSA_NAME is defined in that
+ path, so we only mark a PHI result as maybe-undef if we
+ find an unused reaching SSA_NAME. */
+ int idx = phi_arg_index_from_use (use_p);
+ basic_block bb = gimple_phi_arg_edge (phi, idx)->src;
+ if (ssa_name_any_use_dominates_bb_p (var, bb))
+ continue;
+
+ ssa_name_set_maybe_undef (def);
+ queue.safe_push (def);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "marking _%i as maybe-undef because of _%i\n",
+ SSA_NAME_VERSION (def), SSA_NAME_VERSION (var));
+ }
+ }
+}
+
/* If necessary, rewrite the base of the reference tree *TP from
a MEM_REF to a plain or converted symbol. */
diff --git a/gcc/tree-ssa.h b/gcc/tree-ssa.h
index 0085354..19c1eed 100644
--- a/gcc/tree-ssa.h
+++ b/gcc/tree-ssa.h
@@ -55,6 +55,31 @@ extern tree find_released_ssa_name (tree *, int *, void *);
extern bool ssa_defined_default_def_p (tree t);
extern bool ssa_undefined_value_p (tree, bool = true);
extern bool gimple_uses_undefined_value_p (gimple *);
+
+
+bool ssa_name_any_use_dominates_bb_p (tree var, basic_block bb);
+extern void mark_ssa_maybe_undefs (void);
+
+/* Return TRUE iff VAR is marked as maybe-undefined. See
+ mark_ssa_maybe_undefs. */
+
+static inline bool
+ssa_name_maybe_undef_p (tree var)
+{
+ gcc_checking_assert (TREE_CODE (var) == SSA_NAME);
+ return TREE_VISITED (var);
+}
+
+/* Set (or clear, depending on VALUE) VAR's maybe-undefined mark. */
+
+static inline void
+ssa_name_set_maybe_undef (tree var, bool value = true)
+{
+ gcc_checking_assert (TREE_CODE (var) == SSA_NAME);
+ TREE_VISITED (var) = value;
+}
+
+
extern void execute_update_addresses_taken (void);
/* Given an edge_var_map V, return the PHI arg definition. */
diff --git a/gcc/tree-switch-conversion.cc b/gcc/tree-switch-conversion.cc
index 5291fb8..1d75d7c 100644
--- a/gcc/tree-switch-conversion.cc
+++ b/gcc/tree-switch-conversion.cc
@@ -1518,7 +1518,6 @@ bit_test_cluster::emit (tree index_expr, tree index_type,
tree minval = get_low ();
tree maxval = get_high ();
- unsigned HOST_WIDE_INT bt_range = get_range (minval, maxval);
/* Go through all case labels, and collect the case labels, profile
counts, and other information we need to build the branch tests. */
@@ -1538,10 +1537,12 @@ bit_test_cluster::emit (tree index_expr, tree index_type,
test[k].target_bb = n->m_case_bb;
test[k].label = n->m_case_label_expr;
test[k].bits = 0;
+ test[k].prob = profile_probability::never ();
count++;
}
test[k].bits += n->get_range (n->get_low (), n->get_high ());
+ test[k].prob += n->m_prob;
lo = tree_to_uhwi (int_const_binop (MINUS_EXPR, n->get_low (), minval));
if (n->get_high () == NULL_TREE)
@@ -1629,6 +1630,11 @@ bit_test_cluster::emit (tree index_expr, tree index_type,
/*simple=*/true, NULL_TREE,
/*before=*/true, GSI_SAME_STMT);
+ profile_probability subtree_prob = m_subtree_prob;
+ profile_probability default_prob = m_default_prob;
+ if (!default_prob.initialized_p ())
+ default_prob = m_subtree_prob.invert ();
+
if (m_handles_entire_switch && entry_test_needed)
{
tree range = int_const_binop (MINUS_EXPR, maxval, minval);
@@ -1638,10 +1644,11 @@ bit_test_cluster::emit (tree index_expr, tree index_type,
fold_convert (unsigned_index_type, range),
/*simple=*/true, NULL_TREE,
/*before=*/true, GSI_SAME_STMT);
- tmp = fold_build2_loc (loc, GT_EXPR, boolean_type_node, idx, range);
+ tmp = fold_build2 (GT_EXPR, boolean_type_node, idx, range);
+ default_prob = default_prob / 2;
basic_block new_bb
= hoist_edge_and_branch_if_true (&gsi, tmp, default_bb,
- profile_probability::unlikely (), loc);
+ default_prob, loc);
gsi = gsi_last_bb (new_bb);
}
@@ -1662,15 +1669,12 @@ bit_test_cluster::emit (tree index_expr, tree index_type,
else
csui = tmp;
- profile_probability prob = profile_probability::always ();
-
/* for each unique set of cases:
if (const & csui) goto target */
for (k = 0; k < count; k++)
{
- prob = profile_probability::always ().apply_scale (test[k].bits,
- bt_range);
- bt_range -= test[k].bits;
+ profile_probability prob = test[k].prob / (subtree_prob + default_prob);
+ subtree_prob -= test[k].prob;
tmp = wide_int_to_tree (word_type_node, test[k].mask);
tmp = fold_build2_loc (loc, BIT_AND_EXPR, word_type_node, csui, tmp);
tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node,
@@ -1912,9 +1916,13 @@ switch_decision_tree::try_switch_expansion (vec<cluster *> &clusters)
/* Emit cluster-specific switch handling. */
for (unsigned i = 0; i < clusters.length (); i++)
if (clusters[i]->get_type () != SIMPLE_CASE)
- clusters[i]->emit (index_expr, index_type,
- gimple_switch_default_label (m_switch),
- m_default_bb, gimple_location (m_switch));
+ {
+ edge e = single_pred_edge (clusters[i]->m_case_bb);
+ e->dest->count = e->src->count.apply_probability (e->probability);
+ clusters[i]->emit (index_expr, index_type,
+ gimple_switch_default_label (m_switch),
+ m_default_bb, gimple_location (m_switch));
+ }
}
fix_phi_operands_for_edges ();
@@ -2162,6 +2170,7 @@ switch_decision_tree::emit_cmp_and_jump_insns (basic_block bb, tree op0,
edge false_edge = split_block (bb, cond);
false_edge->flags = EDGE_FALSE_VALUE;
false_edge->probability = prob.invert ();
+ false_edge->dest->count = bb->count.apply_probability (prob.invert ());
edge true_edge = make_edge (bb, label_bb, EDGE_TRUE_VALUE);
true_edge->probability = prob;
@@ -2192,6 +2201,7 @@ switch_decision_tree::do_jump_if_equal (basic_block bb, tree op0, tree op1,
edge false_edge = split_block (bb, cond);
false_edge->flags = EDGE_FALSE_VALUE;
false_edge->probability = prob.invert ();
+ false_edge->dest->count = bb->count.apply_probability (prob.invert ());
edge true_edge = make_edge (bb, label_bb, EDGE_TRUE_VALUE);
true_edge->probability = prob;
@@ -2227,7 +2237,7 @@ switch_decision_tree::emit_case_nodes (basic_block bb, tree index,
node->m_c->m_case_bb, p, loc);
/* Since this case is taken at this point, reduce its weight from
subtree_weight. */
- node->m_c->m_subtree_prob -= p;
+ node->m_c->m_subtree_prob -= node->m_c->m_prob;
if (node->m_left != NULL && node->m_right != NULL)
{
@@ -2246,6 +2256,7 @@ switch_decision_tree::emit_case_nodes (basic_block bb, tree index,
/ (node->m_c->m_subtree_prob + default_prob));
bb = do_jump_if_equal (bb, index, node->m_right->m_c->get_low (),
node->m_right->m_c->m_case_bb, p, loc);
+ node->m_c->m_subtree_prob -= node->m_right->m_c->m_prob;
p = (node->m_left->m_c->m_prob
/ (node->m_c->m_subtree_prob + default_prob));
@@ -2261,6 +2272,7 @@ switch_decision_tree::emit_case_nodes (basic_block bb, tree index,
p = ((node->m_right->m_c->m_subtree_prob + default_prob / 2)
/ (node->m_c->m_subtree_prob + default_prob));
+ test_bb->count = bb->count.apply_probability (p);
bb = emit_cmp_and_jump_insns (bb, index, node->m_c->get_high (),
GT_EXPR, test_bb, p, loc);
default_prob /= 2;
@@ -2347,21 +2359,28 @@ switch_decision_tree::emit_case_nodes (basic_block bb, tree index,
is the one to branch to. */
if (node->has_child () || node->m_c->get_type () != SIMPLE_CASE)
{
+ bool is_bt = node->m_c->get_type () == BIT_TEST;
+ int parts = is_bt ? 3 : 2;
+
/* Branch to a label where we will handle it later. */
basic_block test_bb = split_edge (single_succ_edge (bb));
redirect_edge_succ (single_pred_edge (test_bb),
single_succ_edge (bb)->dest);
+ profile_probability right_prob = profile_probability::never ();
+ if (node->m_right)
+ right_prob = node->m_right->m_c->m_subtree_prob;
+ p = ((right_prob + default_prob / parts)
+ / (node->m_c->m_subtree_prob + default_prob));
+ test_bb->count = bb->count.apply_probability (p);
- profile_probability right_prob = profile_probability::never ();
- if (node->m_right)
- right_prob = node->m_right->m_c->m_subtree_prob;
- p = ((right_prob + default_prob / 2)
- / (node->m_c->m_subtree_prob + default_prob));
+ bb = emit_cmp_and_jump_insns (bb, index, node->m_c->get_high (),
+ GT_EXPR, test_bb, p, loc);
- bb = emit_cmp_and_jump_insns (bb, index, node->m_c->get_high (),
- GT_EXPR, test_bb, p, loc);
- default_prob /= 2;
+ default_prob /= parts;
+ node->m_c->m_subtree_prob -= right_prob;
+ if (is_bt)
+ node->m_c->m_default_prob = default_prob;
/* Value belongs to this node or to the left-hand subtree. */
p = node->m_c->m_prob / (node->m_c->m_subtree_prob + default_prob);
diff --git a/gcc/tree-switch-conversion.h b/gcc/tree-switch-conversion.h
index 6861572..431cf1a 100644
--- a/gcc/tree-switch-conversion.h
+++ b/gcc/tree-switch-conversion.h
@@ -102,6 +102,10 @@ public:
/* Probability of reaching subtree rooted at this node. */
profile_probability m_subtree_prob;
+ /* Probability of default case when reaching the node.
+ It is used by bit-test right now. */
+ profile_probability m_default_prob;
+
protected:
/* Default constructor. */
cluster () {}
@@ -110,7 +114,8 @@ protected:
cluster::cluster (tree case_label_expr, basic_block case_bb,
profile_probability prob, profile_probability subtree_prob):
m_case_label_expr (case_label_expr), m_case_bb (case_bb), m_prob (prob),
- m_subtree_prob (subtree_prob)
+ m_subtree_prob (subtree_prob),
+ m_default_prob (profile_probability::uninitialized ())
{
}
@@ -545,6 +550,7 @@ public:
basic_block target_bb;
tree label;
int bits;
+ profile_probability prob;
/* Comparison function for qsort to order bit tests by decreasing
probability of execution. */
diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
index 6c89279..18b0f96 100644
--- a/gcc/tree-vect-data-refs.cc
+++ b/gcc/tree-vect-data-refs.cc
@@ -4845,11 +4845,13 @@ vect_create_addr_base_for_vector_ref (vec_info *vinfo, stmt_vec_info stmt_info,
if (loop_vinfo)
addr_base = fold_build_pointer_plus (data_ref_base, base_offset);
else
- {
- addr_base = build1 (ADDR_EXPR,
- build_pointer_type (TREE_TYPE (DR_REF (dr))),
- unshare_expr (DR_REF (dr)));
- }
+ addr_base = build1 (ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (DR_REF (dr))),
+ /* Strip zero offset components since we don't need
+ them and they can confuse late diagnostics if
+ we CSE them wrongly. See PR106904 for example. */
+ unshare_expr (strip_zero_offset_components
+ (DR_REF (dr))));
vect_ptr_type = build_pointer_type (TREE_TYPE (DR_REF (dr)));
dest = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var, base_name);
diff --git a/gcc/tree-vect-generic.cc b/gcc/tree-vect-generic.cc
index 3501295..6ad6372 100644
--- a/gcc/tree-vect-generic.cc
+++ b/gcc/tree-vect-generic.cc
@@ -1237,6 +1237,17 @@ expand_vector_operation (gimple_stmt_iterator *gsi, tree type, tree compute_type
tree rhs2 = gimple_assign_rhs2 (assign);
tree ret;
+ /* Check if the target was going to handle it through the special
+ division callback hook. */
+ tree cst = uniform_integer_cst_p (rhs2);
+ if (cst &&
+ targetm.vectorize.can_special_div_by_const (code, type,
+ wi::to_wide (cst),
+ NULL,
+ NULL_RTX, NULL_RTX))
+ return NULL_TREE;
+
+
if (!optimize
|| !VECTOR_INTEGER_TYPE_P (type)
|| TREE_CODE (rhs2) != VECTOR_CST
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index 4e2612e..d9fdb24 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -3749,7 +3749,7 @@ vect_recog_divmod_pattern (vec_info *vinfo,
gimple *pattern_stmt, *def_stmt;
enum tree_code rhs_code;
optab optab;
- tree q;
+ tree q, cst;
int dummy_int, prec;
if (!is_gimple_assign (last_stmt))
@@ -3913,6 +3913,14 @@ vect_recog_divmod_pattern (vec_info *vinfo,
return pattern_stmt;
}
+ else if ((cst = uniform_integer_cst_p (oprnd1))
+ && targetm.vectorize.can_special_div_by_const (rhs_code, vectype,
+ wi::to_wide (cst),
+ NULL, NULL_RTX,
+ NULL_RTX))
+ {
+ return NULL;
+ }
if (prec > HOST_BITS_PER_WIDE_INT
|| integer_zerop (oprnd1))
@@ -4956,6 +4964,8 @@ vect_recog_mask_conversion_pattern (vec_info *vinfo,
else
{
lhs = gimple_call_lhs (last_stmt);
+ if (!lhs)
+ return NULL;
vectype1 = get_vectype_for_scalar_type (vinfo, TREE_TYPE (lhs));
}
diff --git a/gcc/tree-vect-slp-patterns.cc b/gcc/tree-vect-slp-patterns.cc
index dc694b8..9373500 100644
--- a/gcc/tree-vect-slp-patterns.cc
+++ b/gcc/tree-vect-slp-patterns.cc
@@ -1035,8 +1035,11 @@ complex_mul_pattern::matches (complex_operation_t op,
auto_vec<slp_tree> left_op, right_op;
slp_tree add0 = NULL;
- /* Check if we may be a multiply add. */
+ /* Check if we may be a multiply add. It's only valid to form FMAs
+ with -ffp-contract=fast. */
if (!mul0
+ && (flag_fp_contract_mode == FP_CONTRACT_FAST
+ || !FLOAT_TYPE_P (SLP_TREE_VECTYPE (*node)))
&& vect_match_expression_p (l0node[0], PLUS_EXPR))
{
auto vals = SLP_TREE_CHILDREN (l0node[0]);
@@ -1501,9 +1504,13 @@ addsub_pattern::recognize (slp_tree_to_load_perm_map_t *,
}
/* 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))
+ (l0add_p), see whether we have FMA variants. We can only form FMAs
+ if allowed via -ffp-contract=fast. */
+ if (flag_fp_contract_mode != FP_CONTRACT_FAST
+ && FLOAT_TYPE_P (SLP_TREE_VECTYPE (l0node)))
+ ;
+ else 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))
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 4e0d75e..5485da5 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -6260,6 +6260,15 @@ vectorizable_operation (vec_info *vinfo,
}
target_support_p = (optab_handler (optab, vec_mode)
!= CODE_FOR_nothing);
+ tree cst;
+ if (!target_support_p
+ && op1
+ && (cst = uniform_integer_cst_p (op1)))
+ target_support_p
+ = targetm.vectorize.can_special_div_by_const (code, vectype,
+ wi::to_wide (cst),
+ NULL, NULL_RTX,
+ NULL_RTX);
}
bool using_emulated_vectors_p = vect_emulated_vector_p (vectype);
@@ -12185,6 +12194,15 @@ supportable_widening_operation (vec_info *vinfo,
if (VECTOR_BOOLEAN_TYPE_P (prev_type))
intermediate_type
= vect_halve_mask_nunits (prev_type, intermediate_mode);
+ else if (VECTOR_MODE_P (intermediate_mode))
+ {
+ tree intermediate_element_type
+ = lang_hooks.types.type_for_mode (GET_MODE_INNER (intermediate_mode),
+ TYPE_UNSIGNED (prev_type));
+ intermediate_type
+ = build_vector_type_for_mode (intermediate_element_type,
+ intermediate_mode);
+ }
else
intermediate_type
= lang_hooks.types.type_for_mode (intermediate_mode,
diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index f0e4d37..3846dc1 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -180,7 +180,7 @@ remove_unreachable::remove_and_update_globals (bool final_p)
bitmap_copy (dce, all_exports);
// Don't attempt to DCE parameters.
EXECUTE_IF_SET_IN_BITMAP (all_exports, 0, i, bi)
- if (SSA_NAME_IS_DEFAULT_DEF (ssa_name (i)))
+ if (!ssa_name (i) || SSA_NAME_IS_DEFAULT_DEF (ssa_name (i)))
bitmap_clear_bit (dce, i);
simple_dce_from_worklist (dce);
@@ -229,109 +229,6 @@ remove_unreachable::remove_and_update_globals (bool final_p)
return change;
}
-/* Set of SSA names found live during the RPO traversal of the function
- for still active basic-blocks. */
-class live_names
-{
-public:
- live_names ();
- ~live_names ();
- void set (tree, basic_block);
- void clear (tree, basic_block);
- void merge (basic_block dest, basic_block src);
- bool live_on_block_p (tree, basic_block);
- bool live_on_edge_p (tree, edge);
- bool block_has_live_names_p (basic_block);
- void clear_block (basic_block);
-
-private:
- sbitmap *live;
- unsigned num_blocks;
- void init_bitmap_if_needed (basic_block);
-};
-
-void
-live_names::init_bitmap_if_needed (basic_block bb)
-{
- unsigned i = bb->index;
- if (!live[i])
- {
- live[i] = sbitmap_alloc (num_ssa_names);
- bitmap_clear (live[i]);
- }
-}
-
-bool
-live_names::block_has_live_names_p (basic_block bb)
-{
- unsigned i = bb->index;
- return live[i] && bitmap_empty_p (live[i]);
-}
-
-void
-live_names::clear_block (basic_block bb)
-{
- unsigned i = bb->index;
- if (live[i])
- {
- sbitmap_free (live[i]);
- live[i] = NULL;
- }
-}
-
-void
-live_names::merge (basic_block dest, basic_block src)
-{
- init_bitmap_if_needed (dest);
- init_bitmap_if_needed (src);
- bitmap_ior (live[dest->index], live[dest->index], live[src->index]);
-}
-
-void
-live_names::set (tree name, basic_block bb)
-{
- init_bitmap_if_needed (bb);
- bitmap_set_bit (live[bb->index], SSA_NAME_VERSION (name));
-}
-
-void
-live_names::clear (tree name, basic_block bb)
-{
- unsigned i = bb->index;
- if (live[i])
- bitmap_clear_bit (live[i], SSA_NAME_VERSION (name));
-}
-
-live_names::live_names ()
-{
- num_blocks = last_basic_block_for_fn (cfun);
- live = XCNEWVEC (sbitmap, num_blocks);
-}
-
-live_names::~live_names ()
-{
- for (unsigned i = 0; i < num_blocks; ++i)
- if (live[i])
- sbitmap_free (live[i]);
- XDELETEVEC (live);
-}
-
-bool
-live_names::live_on_block_p (tree name, basic_block bb)
-{
- return (live[bb->index]
- && bitmap_bit_p (live[bb->index], SSA_NAME_VERSION (name)));
-}
-
-/* Return true if the SSA name NAME is live on the edge E. */
-
-bool
-live_names::live_on_edge_p (tree name, edge e)
-{
- return live_on_block_p (name, e->dest);
-}
-
-
/* VR_TYPE describes a range with mininum value *MIN and maximum
value *MAX. Restrict the range to the set of values that have
no bits set outside NONZERO_BITS. Update *MIN and *MAX and
@@ -417,7 +314,7 @@ range_int_cst_p (const value_range *vr)
otherwise. We only handle additive operations and set NEG to true if the
symbol is negated and INV to the invariant part, if any. */
-tree
+static tree
get_single_symbol (tree t, bool *neg, tree *inv)
{
bool neg_;
@@ -468,24 +365,6 @@ get_single_symbol (tree t, bool *neg, tree *inv)
return t;
}
-/* The reverse operation: build a symbolic expression with TYPE
- from symbol SYM, negated according to NEG, and invariant INV. */
-
-static tree
-build_symbolic_expr (tree type, tree sym, bool neg, tree inv)
-{
- const bool pointer_p = POINTER_TYPE_P (type);
- tree t = sym;
-
- if (neg)
- t = build1 (NEGATE_EXPR, type, t);
-
- if (integer_zerop (inv))
- return t;
-
- return build2 (pointer_p ? POINTER_PLUS_EXPR : PLUS_EXPR, type, t, inv);
-}
-
/* Return
1 if VAL < VAL2
0 if !(VAL < VAL2)
@@ -697,421 +576,15 @@ compare_values (tree val1, tree val2)
return compare_values_warnv (val1, val2, &sop);
}
-/* If BOUND will include a symbolic bound, adjust it accordingly,
- otherwise leave it as is.
-
- CODE is the original operation that combined the bounds (PLUS_EXPR
- or MINUS_EXPR).
-
- TYPE is the type of the original operation.
-
- SYM_OPn is the symbolic for OPn if it has a symbolic.
-
- NEG_OPn is TRUE if the OPn was negated. */
-
-static void
-adjust_symbolic_bound (tree &bound, enum tree_code code, tree type,
- tree sym_op0, tree sym_op1,
- bool neg_op0, bool neg_op1)
-{
- bool minus_p = (code == MINUS_EXPR);
- /* If the result bound is constant, we're done; otherwise, build the
- symbolic lower bound. */
- if (sym_op0 == sym_op1)
- ;
- else if (sym_op0)
- bound = build_symbolic_expr (type, sym_op0,
- neg_op0, bound);
- else if (sym_op1)
- {
- /* We may not negate if that might introduce
- undefined overflow. */
- if (!minus_p
- || neg_op1
- || TYPE_OVERFLOW_WRAPS (type))
- bound = build_symbolic_expr (type, sym_op1,
- neg_op1 ^ minus_p, bound);
- else
- bound = NULL_TREE;
- }
-}
-
-/* Combine OP1 and OP1, which are two parts of a bound, into one wide
- int bound according to CODE. CODE is the operation combining the
- bound (either a PLUS_EXPR or a MINUS_EXPR).
-
- TYPE is the type of the combine operation.
-
- WI is the wide int to store the result.
-
- OVF is -1 if an underflow occurred, +1 if an overflow occurred or 0
- if over/underflow occurred. */
-
-static void
-combine_bound (enum tree_code code, wide_int &wi, wi::overflow_type &ovf,
- tree type, tree op0, tree op1)
-{
- bool minus_p = (code == MINUS_EXPR);
- const signop sgn = TYPE_SIGN (type);
- const unsigned int prec = TYPE_PRECISION (type);
-
- /* Combine the bounds, if any. */
- if (op0 && op1)
- {
- if (minus_p)
- wi = wi::sub (wi::to_wide (op0), wi::to_wide (op1), sgn, &ovf);
- else
- wi = wi::add (wi::to_wide (op0), wi::to_wide (op1), sgn, &ovf);
- }
- else if (op0)
- wi = wi::to_wide (op0);
- else if (op1)
- {
- if (minus_p)
- wi = wi::neg (wi::to_wide (op1), &ovf);
- else
- wi = wi::to_wide (op1);
- }
- else
- wi = wi::shwi (0, prec);
-}
-
-/* Given a range in [WMIN, WMAX], adjust it for possible overflow and
- put the result in VR.
-
- TYPE is the type of the range.
-
- MIN_OVF and MAX_OVF indicate what type of overflow, if any,
- occurred while originally calculating WMIN or WMAX. -1 indicates
- underflow. +1 indicates overflow. 0 indicates neither. */
-
-static void
-set_value_range_with_overflow (value_range_kind &kind, tree &min, tree &max,
- tree type,
- const wide_int &wmin, const wide_int &wmax,
- wi::overflow_type min_ovf,
- wi::overflow_type max_ovf)
-{
- const signop sgn = TYPE_SIGN (type);
- const unsigned int prec = TYPE_PRECISION (type);
-
- /* For one bit precision if max < min, then the swapped
- range covers all values. */
- if (prec == 1 && wi::lt_p (wmax, wmin, sgn))
- {
- kind = VR_VARYING;
- return;
- }
-
- if (TYPE_OVERFLOW_WRAPS (type))
- {
- /* If overflow wraps, truncate the values and adjust the
- range kind and bounds appropriately. */
- wide_int tmin = wide_int::from (wmin, prec, sgn);
- wide_int tmax = wide_int::from (wmax, prec, sgn);
- if ((min_ovf != wi::OVF_NONE) == (max_ovf != wi::OVF_NONE))
- {
- /* If the limits are swapped, we wrapped around and cover
- the entire range. */
- if (wi::gt_p (tmin, tmax, sgn))
- kind = VR_VARYING;
- else
- {
- kind = VR_RANGE;
- /* No overflow or both overflow or underflow. The
- range kind stays VR_RANGE. */
- min = wide_int_to_tree (type, tmin);
- max = wide_int_to_tree (type, tmax);
- }
- return;
- }
- else if ((min_ovf == wi::OVF_UNDERFLOW && max_ovf == wi::OVF_NONE)
- || (max_ovf == wi::OVF_OVERFLOW && min_ovf == wi::OVF_NONE))
- {
- /* Min underflow or max overflow. The range kind
- changes to VR_ANTI_RANGE. */
- bool covers = false;
- wide_int tem = tmin;
- tmin = tmax + 1;
- if (wi::cmp (tmin, tmax, sgn) < 0)
- covers = true;
- tmax = tem - 1;
- if (wi::cmp (tmax, tem, sgn) > 0)
- covers = true;
- /* If the anti-range would cover nothing, drop to varying.
- Likewise if the anti-range bounds are outside of the
- types values. */
- if (covers || wi::cmp (tmin, tmax, sgn) > 0)
- {
- kind = VR_VARYING;
- return;
- }
- kind = VR_ANTI_RANGE;
- min = wide_int_to_tree (type, tmin);
- max = wide_int_to_tree (type, tmax);
- return;
- }
- else
- {
- /* Other underflow and/or overflow, drop to VR_VARYING. */
- kind = VR_VARYING;
- return;
- }
- }
- else
- {
- /* If overflow does not wrap, saturate to the types min/max
- value. */
- wide_int type_min = wi::min_value (prec, sgn);
- wide_int type_max = wi::max_value (prec, sgn);
- kind = VR_RANGE;
- if (min_ovf == wi::OVF_UNDERFLOW)
- min = wide_int_to_tree (type, type_min);
- else if (min_ovf == wi::OVF_OVERFLOW)
- min = wide_int_to_tree (type, type_max);
- else
- min = wide_int_to_tree (type, wmin);
-
- if (max_ovf == wi::OVF_UNDERFLOW)
- max = wide_int_to_tree (type, type_min);
- else if (max_ovf == wi::OVF_OVERFLOW)
- max = wide_int_to_tree (type, type_max);
- else
- max = wide_int_to_tree (type, wmax);
- }
-}
-
-/* Fold two value range's of a POINTER_PLUS_EXPR into VR. */
-
-static void
-extract_range_from_pointer_plus_expr (value_range *vr,
- enum tree_code code,
- tree expr_type,
- const value_range *vr0,
- const value_range *vr1)
-{
- gcc_checking_assert (POINTER_TYPE_P (expr_type)
- && code == POINTER_PLUS_EXPR);
- /* For pointer types, we are really only interested in asserting
- whether the expression evaluates to non-NULL.
- With -fno-delete-null-pointer-checks we need to be more
- conservative. As some object might reside at address 0,
- then some offset could be added to it and the same offset
- subtracted again and the result would be NULL.
- E.g.
- static int a[12]; where &a[0] is NULL and
- ptr = &a[6];
- ptr -= 6;
- ptr will be NULL here, even when there is POINTER_PLUS_EXPR
- where the first range doesn't include zero and the second one
- doesn't either. As the second operand is sizetype (unsigned),
- consider all ranges where the MSB could be set as possible
- subtractions where the result might be NULL. */
- if ((!range_includes_zero_p (vr0)
- || !range_includes_zero_p (vr1))
- && !TYPE_OVERFLOW_WRAPS (expr_type)
- && (flag_delete_null_pointer_checks
- || (range_int_cst_p (vr1)
- && !tree_int_cst_sign_bit (vr1->max ()))))
- vr->set_nonzero (expr_type);
- else if (vr0->zero_p () && vr1->zero_p ())
- vr->set_zero (expr_type);
- else
- vr->set_varying (expr_type);
-}
-
-/* Extract range information from a PLUS/MINUS_EXPR and store the
- result in *VR. */
-
-static void
-extract_range_from_plus_minus_expr (value_range *vr,
- enum tree_code code,
- tree expr_type,
- const value_range *vr0_,
- const value_range *vr1_)
-{
- gcc_checking_assert (code == PLUS_EXPR || code == MINUS_EXPR);
-
- value_range vr0 = *vr0_, vr1 = *vr1_;
- value_range vrtem0, vrtem1;
-
- /* Now canonicalize anti-ranges to ranges when they are not symbolic
- and express ~[] op X as ([]' op X) U ([]'' op X). */
- if (vr0.kind () == VR_ANTI_RANGE
- && ranges_from_anti_range (&vr0, &vrtem0, &vrtem1))
- {
- extract_range_from_plus_minus_expr (vr, code, expr_type, &vrtem0, vr1_);
- if (!vrtem1.undefined_p ())
- {
- value_range vrres;
- extract_range_from_plus_minus_expr (&vrres, code, expr_type,
- &vrtem1, vr1_);
- vr->union_ (vrres);
- }
- return;
- }
- /* Likewise for X op ~[]. */
- if (vr1.kind () == VR_ANTI_RANGE
- && ranges_from_anti_range (&vr1, &vrtem0, &vrtem1))
- {
- extract_range_from_plus_minus_expr (vr, code, expr_type, vr0_, &vrtem0);
- if (!vrtem1.undefined_p ())
- {
- value_range vrres;
- extract_range_from_plus_minus_expr (&vrres, code, expr_type,
- vr0_, &vrtem1);
- vr->union_ (vrres);
- }
- return;
- }
-
- value_range_kind kind;
- value_range_kind vr0_kind = vr0.kind (), vr1_kind = vr1.kind ();
- tree vr0_min = vr0.min (), vr0_max = vr0.max ();
- tree vr1_min = vr1.min (), vr1_max = vr1.max ();
- tree min = NULL_TREE, max = NULL_TREE;
-
- /* This will normalize things such that calculating
- [0,0] - VR_VARYING is not dropped to varying, but is
- calculated as [MIN+1, MAX]. */
- if (vr0.varying_p ())
- {
- vr0_kind = VR_RANGE;
- vr0_min = vrp_val_min (expr_type);
- vr0_max = vrp_val_max (expr_type);
- }
- if (vr1.varying_p ())
- {
- vr1_kind = VR_RANGE;
- vr1_min = vrp_val_min (expr_type);
- vr1_max = vrp_val_max (expr_type);
- }
-
- const bool minus_p = (code == MINUS_EXPR);
- tree min_op0 = vr0_min;
- tree min_op1 = minus_p ? vr1_max : vr1_min;
- tree max_op0 = vr0_max;
- tree max_op1 = minus_p ? vr1_min : vr1_max;
- tree sym_min_op0 = NULL_TREE;
- tree sym_min_op1 = NULL_TREE;
- tree sym_max_op0 = NULL_TREE;
- tree sym_max_op1 = NULL_TREE;
- bool neg_min_op0, neg_min_op1, neg_max_op0, neg_max_op1;
-
- neg_min_op0 = neg_min_op1 = neg_max_op0 = neg_max_op1 = false;
-
- /* If we have a PLUS or MINUS with two VR_RANGEs, either constant or
- single-symbolic ranges, try to compute the precise resulting range,
- but only if we know that this resulting range will also be constant
- or single-symbolic. */
- if (vr0_kind == VR_RANGE && vr1_kind == VR_RANGE
- && (TREE_CODE (min_op0) == INTEGER_CST
- || (sym_min_op0
- = get_single_symbol (min_op0, &neg_min_op0, &min_op0)))
- && (TREE_CODE (min_op1) == INTEGER_CST
- || (sym_min_op1
- = get_single_symbol (min_op1, &neg_min_op1, &min_op1)))
- && (!(sym_min_op0 && sym_min_op1)
- || (sym_min_op0 == sym_min_op1
- && neg_min_op0 == (minus_p ? neg_min_op1 : !neg_min_op1)))
- && (TREE_CODE (max_op0) == INTEGER_CST
- || (sym_max_op0
- = get_single_symbol (max_op0, &neg_max_op0, &max_op0)))
- && (TREE_CODE (max_op1) == INTEGER_CST
- || (sym_max_op1
- = get_single_symbol (max_op1, &neg_max_op1, &max_op1)))
- && (!(sym_max_op0 && sym_max_op1)
- || (sym_max_op0 == sym_max_op1
- && neg_max_op0 == (minus_p ? neg_max_op1 : !neg_max_op1))))
- {
- wide_int wmin, wmax;
- wi::overflow_type min_ovf = wi::OVF_NONE;
- wi::overflow_type max_ovf = wi::OVF_NONE;
-
- /* Build the bounds. */
- combine_bound (code, wmin, min_ovf, expr_type, min_op0, min_op1);
- combine_bound (code, wmax, max_ovf, expr_type, max_op0, max_op1);
-
- /* If the resulting range will be symbolic, we need to eliminate any
- explicit or implicit overflow introduced in the above computation
- because compare_values could make an incorrect use of it. That's
- why we require one of the ranges to be a singleton. */
- if ((sym_min_op0 != sym_min_op1 || sym_max_op0 != sym_max_op1)
- && ((bool)min_ovf || (bool)max_ovf
- || (min_op0 != max_op0 && min_op1 != max_op1)))
- {
- vr->set_varying (expr_type);
- return;
- }
-
- /* Adjust the range for possible overflow. */
- set_value_range_with_overflow (kind, min, max, expr_type,
- wmin, wmax, min_ovf, max_ovf);
- if (kind == VR_VARYING)
- {
- vr->set_varying (expr_type);
- return;
- }
-
- /* Build the symbolic bounds if needed. */
- adjust_symbolic_bound (min, code, expr_type,
- sym_min_op0, sym_min_op1,
- neg_min_op0, neg_min_op1);
- adjust_symbolic_bound (max, code, expr_type,
- sym_max_op0, sym_max_op1,
- neg_max_op0, neg_max_op1);
- }
- else
- {
- /* For other cases, for example if we have a PLUS_EXPR with two
- VR_ANTI_RANGEs, drop to VR_VARYING. It would take more effort
- to compute a precise range for such a case.
- ??? General even mixed range kind operations can be expressed
- by for example transforming ~[3, 5] + [1, 2] to range-only
- operations and a union primitive:
- [-INF, 2] + [1, 2] U [5, +INF] + [1, 2]
- [-INF+1, 4] U [6, +INF(OVF)]
- though usually the union is not exactly representable with
- a single range or anti-range as the above is
- [-INF+1, +INF(OVF)] intersected with ~[5, 5]
- but one could use a scheme similar to equivalences for this. */
- vr->set_varying (expr_type);
- return;
- }
-
- /* If either MIN or MAX overflowed, then set the resulting range to
- VARYING. */
- if (min == NULL_TREE
- || TREE_OVERFLOW_P (min)
- || max == NULL_TREE
- || TREE_OVERFLOW_P (max))
- {
- vr->set_varying (expr_type);
- return;
- }
-
- int cmp = compare_values (min, max);
- if (cmp == -2 || cmp == 1)
- {
- /* If the new range has its limits swapped around (MIN > MAX),
- then the operation caused one of them to wrap around, mark
- the new range VARYING. */
- vr->set_varying (expr_type);
- }
- else
- vr->set (min, max, kind);
-}
-
/* If the types passed are supported, return TRUE, otherwise set VR to
VARYING and return FALSE. */
static bool
supported_types_p (value_range *vr,
tree type0,
- tree type1 = NULL)
+ tree = NULL)
{
- if (!value_range_equiv::supports_p (type0)
- || (type1 && !value_range_equiv::supports_p (type1)))
+ if (!value_range::supports_p (type0))
{
vr->set_varying (type0);
return false;
@@ -1134,89 +607,6 @@ defined_ranges_p (value_range *vr,
return true;
}
-static value_range
-drop_undefines_to_varying (const value_range *vr, tree expr_type)
-{
- if (vr->undefined_p ())
- return value_range (expr_type);
- else
- return *vr;
-}
-
-/* If any operand is symbolic, perform a binary operation on them and
- return TRUE, otherwise return FALSE. */
-
-static bool
-range_fold_binary_symbolics_p (value_range *vr,
- tree_code code,
- tree expr_type,
- const value_range *vr0_,
- const value_range *vr1_)
-{
- if (vr0_->symbolic_p () || vr1_->symbolic_p ())
- {
- value_range vr0 = drop_undefines_to_varying (vr0_, expr_type);
- value_range vr1 = drop_undefines_to_varying (vr1_, expr_type);
- if ((code == PLUS_EXPR || code == MINUS_EXPR))
- {
- extract_range_from_plus_minus_expr (vr, code, expr_type,
- &vr0, &vr1);
- return true;
- }
- if (POINTER_TYPE_P (expr_type) && code == POINTER_PLUS_EXPR)
- {
- extract_range_from_pointer_plus_expr (vr, code, expr_type,
- &vr0, &vr1);
- return true;
- }
- range_op_handler op (code, expr_type);
- if (!op)
- vr->set_varying (expr_type);
- vr0.normalize_symbolics ();
- vr1.normalize_symbolics ();
- return op.fold_range (*vr, expr_type, vr0, vr1);
- }
- return false;
-}
-
-/* If operand is symbolic, perform a unary operation on it and return
- TRUE, otherwise return FALSE. */
-
-static bool
-range_fold_unary_symbolics_p (value_range *vr,
- tree_code code,
- tree expr_type,
- const value_range *vr0)
-{
- if (vr0->symbolic_p ())
- {
- if (code == NEGATE_EXPR)
- {
- /* -X is simply 0 - X. */
- value_range zero;
- zero.set_zero (vr0->type ());
- range_fold_binary_expr (vr, MINUS_EXPR, expr_type, &zero, vr0);
- return true;
- }
- if (code == BIT_NOT_EXPR)
- {
- /* ~X is simply -1 - X. */
- value_range minusone;
- tree t = build_int_cst (vr0->type (), -1);
- minusone.set (t, t);
- range_fold_binary_expr (vr, MINUS_EXPR, expr_type, &minusone, vr0);
- return true;
- }
- range_op_handler op (code, expr_type);
- if (!op)
- vr->set_varying (expr_type);
- value_range vr0_cst (*vr0);
- vr0_cst.normalize_symbolics ();
- return op.fold_range (*vr, expr_type, vr0_cst, value_range (expr_type));
- }
- return false;
-}
-
/* Perform a binary operation on a pair of ranges. */
void
@@ -1236,9 +626,6 @@ range_fold_binary_expr (value_range *vr,
return;
}
- if (range_fold_binary_symbolics_p (vr, code, expr_type, vr0_, vr1_))
- return;
-
value_range vr0 (*vr0_);
value_range vr1 (*vr1_);
if (vr0.undefined_p ())
@@ -1269,215 +656,12 @@ range_fold_unary_expr (value_range *vr,
return;
}
- if (range_fold_unary_symbolics_p (vr, code, expr_type, vr0))
- return;
-
value_range vr0_cst (*vr0);
vr0_cst.normalize_addresses ();
if (!op.fold_range (*vr, expr_type, vr0_cst, value_range (expr_type)))
vr->set_varying (expr_type);
}
-/* If the range of values taken by OP can be inferred after STMT executes,
- return the comparison code (COMP_CODE_P) and value (VAL_P) that
- describes the inferred range. Return true if a range could be
- inferred. */
-
-bool
-infer_value_range (gimple *stmt, tree op, tree_code *comp_code_p, tree *val_p)
-{
- *val_p = NULL_TREE;
- *comp_code_p = ERROR_MARK;
-
- /* Do not attempt to infer anything in names that flow through
- abnormal edges. */
- if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
- return false;
-
- /* If STMT is the last statement of a basic block with no normal
- successors, there is no point inferring anything about any of its
- operands. We would not be able to find a proper insertion point
- for the assertion, anyway. */
- if (stmt_ends_bb_p (stmt))
- {
- edge_iterator ei;
- edge e;
-
- FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
- if (!(e->flags & (EDGE_ABNORMAL|EDGE_EH)))
- break;
- if (e == NULL)
- return false;
- }
-
- if (infer_nonnull_range (stmt, op))
- {
- *val_p = build_int_cst (TREE_TYPE (op), 0);
- *comp_code_p = NE_EXPR;
- return true;
- }
-
- return false;
-}
-
-/* Dump assert_info structure. */
-
-void
-dump_assert_info (FILE *file, const assert_info &assert)
-{
- fprintf (file, "Assert for: ");
- print_generic_expr (file, assert.name);
- fprintf (file, "\n\tPREDICATE: expr=[");
- print_generic_expr (file, assert.expr);
- fprintf (file, "] %s ", get_tree_code_name (assert.comp_code));
- fprintf (file, "val=[");
- print_generic_expr (file, assert.val);
- fprintf (file, "]\n\n");
-}
-
-DEBUG_FUNCTION void
-debug (const assert_info &assert)
-{
- dump_assert_info (stderr, assert);
-}
-
-/* Dump a vector of assert_info's. */
-
-void
-dump_asserts_info (FILE *file, const vec<assert_info> &asserts)
-{
- for (unsigned i = 0; i < asserts.length (); ++i)
- {
- dump_assert_info (file, asserts[i]);
- fprintf (file, "\n");
- }
-}
-
-DEBUG_FUNCTION void
-debug (const vec<assert_info> &asserts)
-{
- dump_asserts_info (stderr, asserts);
-}
-
-/* Push the assert info for NAME, EXPR, COMP_CODE and VAL to ASSERTS. */
-
-static void
-add_assert_info (vec<assert_info> &asserts,
- tree name, tree expr, enum tree_code comp_code, tree val)
-{
- assert_info info;
- info.comp_code = comp_code;
- info.name = name;
- if (TREE_OVERFLOW_P (val))
- val = drop_tree_overflow (val);
- info.val = val;
- info.expr = expr;
- asserts.safe_push (info);
- if (dump_enabled_p ())
- dump_printf (MSG_NOTE | MSG_PRIORITY_INTERNALS,
- "Adding assert for %T from %T %s %T\n",
- name, expr, op_symbol_code (comp_code), val);
-}
-
-/* (COND_OP0 COND_CODE COND_OP1) is a predicate which uses NAME.
- Extract a suitable test code and value and store them into *CODE_P and
- *VAL_P so the predicate is normalized to NAME *CODE_P *VAL_P.
-
- If no extraction was possible, return FALSE, otherwise return TRUE.
-
- If INVERT is true, then we invert the result stored into *CODE_P. */
-
-static bool
-extract_code_and_val_from_cond_with_ops (tree name, enum tree_code cond_code,
- tree cond_op0, tree cond_op1,
- bool invert, enum tree_code *code_p,
- tree *val_p)
-{
- enum tree_code comp_code;
- tree val;
-
- /* Otherwise, we have a comparison of the form NAME COMP VAL
- or VAL COMP NAME. */
- if (name == cond_op1)
- {
- /* If the predicate is of the form VAL COMP NAME, flip
- COMP around because we need to register NAME as the
- first operand in the predicate. */
- comp_code = swap_tree_comparison (cond_code);
- val = cond_op0;
- }
- else if (name == cond_op0)
- {
- /* The comparison is of the form NAME COMP VAL, so the
- comparison code remains unchanged. */
- comp_code = cond_code;
- val = cond_op1;
- }
- else
- gcc_unreachable ();
-
- /* Invert the comparison code as necessary. */
- if (invert)
- comp_code = invert_tree_comparison (comp_code, 0);
-
- /* VRP only handles integral and pointer types. */
- if (! INTEGRAL_TYPE_P (TREE_TYPE (val))
- && ! POINTER_TYPE_P (TREE_TYPE (val)))
- return false;
-
- /* Do not register always-false predicates.
- FIXME: this works around a limitation in fold() when dealing with
- enumerations. Given 'enum { N1, N2 } x;', fold will not
- fold 'if (x > N2)' to 'if (0)'. */
- if ((comp_code == GT_EXPR || comp_code == LT_EXPR)
- && INTEGRAL_TYPE_P (TREE_TYPE (val)))
- {
- tree min = TYPE_MIN_VALUE (TREE_TYPE (val));
- tree max = TYPE_MAX_VALUE (TREE_TYPE (val));
-
- if (comp_code == GT_EXPR
- && (!max
- || compare_values (val, max) == 0))
- return false;
-
- if (comp_code == LT_EXPR
- && (!min
- || compare_values (val, min) == 0))
- return false;
- }
- *code_p = comp_code;
- *val_p = val;
- return true;
-}
-
-/* Find out smallest RES where RES > VAL && (RES & MASK) == RES, if any
- (otherwise return VAL). VAL and MASK must be zero-extended for
- precision PREC. If SGNBIT is non-zero, first xor VAL with SGNBIT
- (to transform signed values into unsigned) and at the end xor
- SGNBIT back. */
-
-wide_int
-masked_increment (const wide_int &val_in, const wide_int &mask,
- const wide_int &sgnbit, unsigned int prec)
-{
- wide_int bit = wi::one (prec), res;
- unsigned int i;
-
- wide_int val = val_in ^ sgnbit;
- for (i = 0; i < prec; i++, bit += bit)
- {
- res = mask;
- if ((res & bit) == 0)
- continue;
- res = bit - 1;
- res = wi::bit_and_not (val + bit, res);
- res &= mask;
- if (wi::gtu_p (res, val))
- return res ^ sgnbit;
- }
- return val ^ sgnbit;
-}
-
/* Helper for overflow_comparison_p
OP0 CODE OP1 is a comparison. Examine the comparison and potentially
@@ -1495,7 +679,7 @@ masked_increment (const wide_int &val_in, const wide_int &mask,
static bool
overflow_comparison_p_1 (enum tree_code code, tree op0, tree op1,
- bool follow_assert_exprs, bool reversed, tree *new_cst)
+ bool reversed, tree *new_cst)
{
/* See if this is a relational operation between two SSA_NAMES with
unsigned, overflow wrapping values. If so, check it more deeply. */
@@ -1509,19 +693,6 @@ overflow_comparison_p_1 (enum tree_code code, tree op0, tree op1,
{
gimple *op1_def = SSA_NAME_DEF_STMT (op1);
- /* If requested, follow any ASSERT_EXPRs backwards for OP1. */
- if (follow_assert_exprs)
- {
- while (gimple_assign_single_p (op1_def)
- && TREE_CODE (gimple_assign_rhs1 (op1_def)) == ASSERT_EXPR)
- {
- op1 = TREE_OPERAND (gimple_assign_rhs1 (op1_def), 0);
- if (TREE_CODE (op1) != SSA_NAME)
- break;
- op1_def = SSA_NAME_DEF_STMT (op1);
- }
- }
-
/* Now look at the defining statement of OP1 to see if it adds
or subtracts a nonzero constant from another operand. */
if (op1_def
@@ -1532,24 +703,6 @@ overflow_comparison_p_1 (enum tree_code code, tree op0, tree op1,
{
tree target = gimple_assign_rhs1 (op1_def);
- /* If requested, follow ASSERT_EXPRs backwards for op0 looking
- for one where TARGET appears on the RHS. */
- if (follow_assert_exprs)
- {
- /* Now see if that "other operand" is op0, following the chain
- of ASSERT_EXPRs if necessary. */
- gimple *op0_def = SSA_NAME_DEF_STMT (op0);
- while (op0 != target
- && gimple_assign_single_p (op0_def)
- && TREE_CODE (gimple_assign_rhs1 (op0_def)) == ASSERT_EXPR)
- {
- op0 = TREE_OPERAND (gimple_assign_rhs1 (op0_def), 0);
- if (TREE_CODE (op0) != SSA_NAME)
- break;
- op0_def = SSA_NAME_DEF_STMT (op0);
- }
- }
-
/* If we did not find our target SSA_NAME, then this is not
an overflow test. */
if (op0 != target)
@@ -1580,828 +733,12 @@ overflow_comparison_p_1 (enum tree_code code, tree op0, tree op1,
the alternate range representation is often useful within VRP. */
bool
-overflow_comparison_p (tree_code code, tree name, tree val,
- bool use_equiv_p, tree *new_cst)
+overflow_comparison_p (tree_code code, tree name, tree val, tree *new_cst)
{
- if (overflow_comparison_p_1 (code, name, val, use_equiv_p, false, new_cst))
+ if (overflow_comparison_p_1 (code, name, val, false, new_cst))
return true;
return overflow_comparison_p_1 (swap_tree_comparison (code), val, name,
- use_equiv_p, true, new_cst);
-}
-
-
-/* Try to register an edge assertion for SSA name NAME on edge E for
- the condition COND contributing to the conditional jump pointed to by BSI.
- Invert the condition COND if INVERT is true. */
-
-static void
-register_edge_assert_for_2 (tree name, edge e,
- enum tree_code cond_code,
- tree cond_op0, tree cond_op1, bool invert,
- vec<assert_info> &asserts)
-{
- tree val;
- enum tree_code comp_code;
-
- if (!extract_code_and_val_from_cond_with_ops (name, cond_code,
- cond_op0,
- cond_op1,
- invert, &comp_code, &val))
- return;
-
- /* Queue the assert. */
- tree x;
- if (overflow_comparison_p (comp_code, name, val, false, &x))
- {
- enum tree_code new_code = ((comp_code == GT_EXPR || comp_code == GE_EXPR)
- ? GT_EXPR : LE_EXPR);
- add_assert_info (asserts, name, name, new_code, x);
- }
- add_assert_info (asserts, name, name, comp_code, val);
-
- /* In the case of NAME <= CST and NAME being defined as
- NAME = (unsigned) NAME2 + CST2 we can assert NAME2 >= -CST2
- and NAME2 <= CST - CST2. We can do the same for NAME > CST.
- This catches range and anti-range tests. */
- if ((comp_code == LE_EXPR
- || comp_code == GT_EXPR)
- && TREE_CODE (val) == INTEGER_CST
- && TYPE_UNSIGNED (TREE_TYPE (val)))
- {
- gimple *def_stmt = SSA_NAME_DEF_STMT (name);
- tree cst2 = NULL_TREE, name2 = NULL_TREE, name3 = NULL_TREE;
-
- /* Extract CST2 from the (optional) addition. */
- if (is_gimple_assign (def_stmt)
- && gimple_assign_rhs_code (def_stmt) == PLUS_EXPR)
- {
- name2 = gimple_assign_rhs1 (def_stmt);
- cst2 = gimple_assign_rhs2 (def_stmt);
- if (TREE_CODE (name2) == SSA_NAME
- && TREE_CODE (cst2) == INTEGER_CST)
- def_stmt = SSA_NAME_DEF_STMT (name2);
- }
-
- /* Extract NAME2 from the (optional) sign-changing cast. */
- if (gassign *ass = dyn_cast <gassign *> (def_stmt))
- {
- if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (ass))
- && ! TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (ass)))
- && (TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (ass)))
- == TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (ass)))))
- name3 = gimple_assign_rhs1 (ass);
- }
-
- /* If name3 is used later, create an ASSERT_EXPR for it. */
- if (name3 != NULL_TREE
- && TREE_CODE (name3) == SSA_NAME
- && (cst2 == NULL_TREE
- || TREE_CODE (cst2) == INTEGER_CST)
- && INTEGRAL_TYPE_P (TREE_TYPE (name3)))
- {
- tree tmp;
-
- /* Build an expression for the range test. */
- tmp = build1 (NOP_EXPR, TREE_TYPE (name), name3);
- if (cst2 != NULL_TREE)
- tmp = build2 (PLUS_EXPR, TREE_TYPE (name), tmp, cst2);
- add_assert_info (asserts, name3, tmp, comp_code, val);
- }
-
- /* If name2 is used later, create an ASSERT_EXPR for it. */
- if (name2 != NULL_TREE
- && TREE_CODE (name2) == SSA_NAME
- && TREE_CODE (cst2) == INTEGER_CST
- && INTEGRAL_TYPE_P (TREE_TYPE (name2)))
- {
- tree tmp;
-
- /* Build an expression for the range test. */
- tmp = name2;
- if (TREE_TYPE (name) != TREE_TYPE (name2))
- tmp = build1 (NOP_EXPR, TREE_TYPE (name), tmp);
- if (cst2 != NULL_TREE)
- tmp = build2 (PLUS_EXPR, TREE_TYPE (name), tmp, cst2);
- add_assert_info (asserts, name2, tmp, comp_code, val);
- }
- }
-
- /* In the case of post-in/decrement tests like if (i++) ... and uses
- of the in/decremented value on the edge the extra name we want to
- assert for is not on the def chain of the name compared. Instead
- it is in the set of use stmts.
- Similar cases happen for conversions that were simplified through
- fold_{sign_changed,widened}_comparison. */
- if ((comp_code == NE_EXPR
- || comp_code == EQ_EXPR)
- && TREE_CODE (val) == INTEGER_CST)
- {
- imm_use_iterator ui;
- gimple *use_stmt;
- FOR_EACH_IMM_USE_STMT (use_stmt, ui, name)
- {
- if (!is_gimple_assign (use_stmt))
- continue;
-
- /* Cut off to use-stmts that are dominating the predecessor. */
- if (!dominated_by_p (CDI_DOMINATORS, e->src, gimple_bb (use_stmt)))
- continue;
-
- tree name2 = gimple_assign_lhs (use_stmt);
- if (TREE_CODE (name2) != SSA_NAME)
- continue;
-
- enum tree_code code = gimple_assign_rhs_code (use_stmt);
- tree cst;
- if (code == PLUS_EXPR
- || code == MINUS_EXPR)
- {
- cst = gimple_assign_rhs2 (use_stmt);
- if (TREE_CODE (cst) != INTEGER_CST)
- continue;
- cst = int_const_binop (code, val, cst);
- }
- else if (CONVERT_EXPR_CODE_P (code))
- {
- /* For truncating conversions we cannot record
- an inequality. */
- if (comp_code == NE_EXPR
- && (TYPE_PRECISION (TREE_TYPE (name2))
- < TYPE_PRECISION (TREE_TYPE (name))))
- continue;
- cst = fold_convert (TREE_TYPE (name2), val);
- }
- else
- continue;
-
- if (TREE_OVERFLOW_P (cst))
- cst = drop_tree_overflow (cst);
- add_assert_info (asserts, name2, name2, comp_code, cst);
- }
- }
-
- if (TREE_CODE_CLASS (comp_code) == tcc_comparison
- && TREE_CODE (val) == INTEGER_CST)
- {
- gimple *def_stmt = SSA_NAME_DEF_STMT (name);
- tree name2 = NULL_TREE, names[2], cst2 = NULL_TREE;
- tree val2 = NULL_TREE;
- unsigned int prec = TYPE_PRECISION (TREE_TYPE (val));
- wide_int mask = wi::zero (prec);
- unsigned int nprec = prec;
- enum tree_code rhs_code = ERROR_MARK;
-
- if (is_gimple_assign (def_stmt))
- rhs_code = gimple_assign_rhs_code (def_stmt);
-
- /* In the case of NAME != CST1 where NAME = A +- CST2 we can
- assert that A != CST1 -+ CST2. */
- if ((comp_code == EQ_EXPR || comp_code == NE_EXPR)
- && (rhs_code == PLUS_EXPR || rhs_code == MINUS_EXPR))
- {
- tree op0 = gimple_assign_rhs1 (def_stmt);
- tree op1 = gimple_assign_rhs2 (def_stmt);
- if (TREE_CODE (op0) == SSA_NAME
- && TREE_CODE (op1) == INTEGER_CST)
- {
- enum tree_code reverse_op = (rhs_code == PLUS_EXPR
- ? MINUS_EXPR : PLUS_EXPR);
- op1 = int_const_binop (reverse_op, val, op1);
- if (TREE_OVERFLOW (op1))
- op1 = drop_tree_overflow (op1);
- add_assert_info (asserts, op0, op0, comp_code, op1);
- }
- }
-
- /* Add asserts for NAME cmp CST and NAME being defined
- as NAME = (int) NAME2. */
- if (!TYPE_UNSIGNED (TREE_TYPE (val))
- && (comp_code == LE_EXPR || comp_code == LT_EXPR
- || comp_code == GT_EXPR || comp_code == GE_EXPR)
- && gimple_assign_cast_p (def_stmt))
- {
- name2 = gimple_assign_rhs1 (def_stmt);
- if (CONVERT_EXPR_CODE_P (rhs_code)
- && TREE_CODE (name2) == SSA_NAME
- && INTEGRAL_TYPE_P (TREE_TYPE (name2))
- && TYPE_UNSIGNED (TREE_TYPE (name2))
- && prec == TYPE_PRECISION (TREE_TYPE (name2))
- && (comp_code == LE_EXPR || comp_code == GT_EXPR
- || !tree_int_cst_equal (val,
- TYPE_MIN_VALUE (TREE_TYPE (val)))))
- {
- tree tmp, cst;
- enum tree_code new_comp_code = comp_code;
-
- cst = fold_convert (TREE_TYPE (name2),
- TYPE_MIN_VALUE (TREE_TYPE (val)));
- /* Build an expression for the range test. */
- tmp = build2 (PLUS_EXPR, TREE_TYPE (name2), name2, cst);
- cst = fold_build2 (PLUS_EXPR, TREE_TYPE (name2), cst,
- fold_convert (TREE_TYPE (name2), val));
- if (comp_code == LT_EXPR || comp_code == GE_EXPR)
- {
- new_comp_code = comp_code == LT_EXPR ? LE_EXPR : GT_EXPR;
- cst = fold_build2 (MINUS_EXPR, TREE_TYPE (name2), cst,
- build_int_cst (TREE_TYPE (name2), 1));
- }
- add_assert_info (asserts, name2, tmp, new_comp_code, cst);
- }
- }
-
- /* Add asserts for NAME cmp CST and NAME being defined as
- NAME = NAME2 >> CST2.
-
- Extract CST2 from the right shift. */
- if (rhs_code == RSHIFT_EXPR)
- {
- name2 = gimple_assign_rhs1 (def_stmt);
- cst2 = gimple_assign_rhs2 (def_stmt);
- if (TREE_CODE (name2) == SSA_NAME
- && tree_fits_uhwi_p (cst2)
- && INTEGRAL_TYPE_P (TREE_TYPE (name2))
- && IN_RANGE (tree_to_uhwi (cst2), 1, prec - 1)
- && type_has_mode_precision_p (TREE_TYPE (val)))
- {
- mask = wi::mask (tree_to_uhwi (cst2), false, prec);
- val2 = fold_binary (LSHIFT_EXPR, TREE_TYPE (val), val, cst2);
- }
- }
- if (val2 != NULL_TREE
- && TREE_CODE (val2) == INTEGER_CST
- && simple_cst_equal (fold_build2 (RSHIFT_EXPR,
- TREE_TYPE (val),
- val2, cst2), val))
- {
- enum tree_code new_comp_code = comp_code;
- tree tmp, new_val;
-
- tmp = name2;
- if (comp_code == EQ_EXPR || comp_code == NE_EXPR)
- {
- if (!TYPE_UNSIGNED (TREE_TYPE (val)))
- {
- tree type = build_nonstandard_integer_type (prec, 1);
- tmp = build1 (NOP_EXPR, type, name2);
- val2 = fold_convert (type, val2);
- }
- tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp, val2);
- new_val = wide_int_to_tree (TREE_TYPE (tmp), mask);
- new_comp_code = comp_code == EQ_EXPR ? LE_EXPR : GT_EXPR;
- }
- else if (comp_code == LT_EXPR || comp_code == GE_EXPR)
- {
- wide_int minval
- = wi::min_value (prec, TYPE_SIGN (TREE_TYPE (val)));
- new_val = val2;
- if (minval == wi::to_wide (new_val))
- new_val = NULL_TREE;
- }
- else
- {
- wide_int maxval
- = wi::max_value (prec, TYPE_SIGN (TREE_TYPE (val)));
- mask |= wi::to_wide (val2);
- if (wi::eq_p (mask, maxval))
- new_val = NULL_TREE;
- else
- new_val = wide_int_to_tree (TREE_TYPE (val2), mask);
- }
-
- if (new_val)
- add_assert_info (asserts, name2, tmp, new_comp_code, new_val);
- }
-
- /* If we have a conversion that doesn't change the value of the source
- simply register the same assert for it. */
- if (CONVERT_EXPR_CODE_P (rhs_code))
- {
- value_range vr;
- tree rhs1 = gimple_assign_rhs1 (def_stmt);
- if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
- && TREE_CODE (rhs1) == SSA_NAME
- /* Make sure the relation preserves the upper/lower boundary of
- the range conservatively. */
- && (comp_code == NE_EXPR
- || comp_code == EQ_EXPR
- || (TYPE_SIGN (TREE_TYPE (name))
- == TYPE_SIGN (TREE_TYPE (rhs1)))
- || ((comp_code == LE_EXPR
- || comp_code == LT_EXPR)
- && !TYPE_UNSIGNED (TREE_TYPE (rhs1)))
- || ((comp_code == GE_EXPR
- || comp_code == GT_EXPR)
- && TYPE_UNSIGNED (TREE_TYPE (rhs1))))
- /* And the conversion does not alter the value we compare
- against and all values in rhs1 can be represented in
- the converted to type. */
- && int_fits_type_p (val, TREE_TYPE (rhs1))
- && ((TYPE_PRECISION (TREE_TYPE (name))
- > TYPE_PRECISION (TREE_TYPE (rhs1)))
- || ((get_range_query (cfun)->range_of_expr (vr, rhs1)
- && vr.kind () == VR_RANGE)
- && wi::fits_to_tree_p
- (widest_int::from (vr.lower_bound (),
- TYPE_SIGN (TREE_TYPE (rhs1))),
- TREE_TYPE (name))
- && wi::fits_to_tree_p
- (widest_int::from (vr.upper_bound (),
- TYPE_SIGN (TREE_TYPE (rhs1))),
- TREE_TYPE (name)))))
- add_assert_info (asserts, rhs1, rhs1,
- comp_code, fold_convert (TREE_TYPE (rhs1), val));
- }
-
- /* Add asserts for NAME cmp CST and NAME being defined as
- NAME = NAME2 & CST2.
-
- Extract CST2 from the and.
-
- Also handle
- NAME = (unsigned) NAME2;
- casts where NAME's type is unsigned and has smaller precision
- than NAME2's type as if it was NAME = NAME2 & MASK. */
- names[0] = NULL_TREE;
- names[1] = NULL_TREE;
- cst2 = NULL_TREE;
- if (rhs_code == BIT_AND_EXPR
- || (CONVERT_EXPR_CODE_P (rhs_code)
- && INTEGRAL_TYPE_P (TREE_TYPE (val))
- && TYPE_UNSIGNED (TREE_TYPE (val))
- && TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt)))
- > prec))
- {
- name2 = gimple_assign_rhs1 (def_stmt);
- if (rhs_code == BIT_AND_EXPR)
- cst2 = gimple_assign_rhs2 (def_stmt);
- else
- {
- cst2 = TYPE_MAX_VALUE (TREE_TYPE (val));
- nprec = TYPE_PRECISION (TREE_TYPE (name2));
- }
- if (TREE_CODE (name2) == SSA_NAME
- && INTEGRAL_TYPE_P (TREE_TYPE (name2))
- && TREE_CODE (cst2) == INTEGER_CST
- && !integer_zerop (cst2)
- && (nprec > 1
- || TYPE_UNSIGNED (TREE_TYPE (val))))
- {
- gimple *def_stmt2 = SSA_NAME_DEF_STMT (name2);
- if (gimple_assign_cast_p (def_stmt2))
- {
- names[1] = gimple_assign_rhs1 (def_stmt2);
- if (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt2))
- || TREE_CODE (names[1]) != SSA_NAME
- || !INTEGRAL_TYPE_P (TREE_TYPE (names[1]))
- || (TYPE_PRECISION (TREE_TYPE (name2))
- != TYPE_PRECISION (TREE_TYPE (names[1]))))
- names[1] = NULL_TREE;
- }
- names[0] = name2;
- }
- }
- if (names[0] || names[1])
- {
- wide_int minv, maxv, valv, cst2v;
- wide_int tem, sgnbit;
- bool valid_p = false, valn, cst2n;
- enum tree_code ccode = comp_code;
-
- valv = wide_int::from (wi::to_wide (val), nprec, UNSIGNED);
- cst2v = wide_int::from (wi::to_wide (cst2), nprec, UNSIGNED);
- valn = wi::neg_p (valv, TYPE_SIGN (TREE_TYPE (val)));
- cst2n = wi::neg_p (cst2v, TYPE_SIGN (TREE_TYPE (val)));
- /* If CST2 doesn't have most significant bit set,
- but VAL is negative, we have comparison like
- if ((x & 0x123) > -4) (always true). Just give up. */
- if (!cst2n && valn)
- ccode = ERROR_MARK;
- if (cst2n)
- sgnbit = wi::set_bit_in_zero (nprec - 1, nprec);
- else
- sgnbit = wi::zero (nprec);
- minv = valv & cst2v;
- switch (ccode)
- {
- case EQ_EXPR:
- /* Minimum unsigned value for equality is VAL & CST2
- (should be equal to VAL, otherwise we probably should
- have folded the comparison into false) and
- maximum unsigned value is VAL | ~CST2. */
- maxv = valv | ~cst2v;
- valid_p = true;
- break;
-
- case NE_EXPR:
- tem = valv | ~cst2v;
- /* If VAL is 0, handle (X & CST2) != 0 as (X & CST2) > 0U. */
- if (valv == 0)
- {
- cst2n = false;
- sgnbit = wi::zero (nprec);
- goto gt_expr;
- }
- /* If (VAL | ~CST2) is all ones, handle it as
- (X & CST2) < VAL. */
- if (tem == -1)
- {
- cst2n = false;
- valn = false;
- sgnbit = wi::zero (nprec);
- goto lt_expr;
- }
- if (!cst2n && wi::neg_p (cst2v))
- sgnbit = wi::set_bit_in_zero (nprec - 1, nprec);
- if (sgnbit != 0)
- {
- if (valv == sgnbit)
- {
- cst2n = true;
- valn = true;
- goto gt_expr;
- }
- if (tem == wi::mask (nprec - 1, false, nprec))
- {
- cst2n = true;
- goto lt_expr;
- }
- if (!cst2n)
- sgnbit = wi::zero (nprec);
- }
- break;
-
- case GE_EXPR:
- /* Minimum unsigned value for >= if (VAL & CST2) == VAL
- is VAL and maximum unsigned value is ~0. For signed
- comparison, if CST2 doesn't have most significant bit
- set, handle it similarly. If CST2 has MSB set,
- the minimum is the same, and maximum is ~0U/2. */
- if (minv != valv)
- {
- /* If (VAL & CST2) != VAL, X & CST2 can't be equal to
- VAL. */
- minv = masked_increment (valv, cst2v, sgnbit, nprec);
- if (minv == valv)
- break;
- }
- maxv = wi::mask (nprec - (cst2n ? 1 : 0), false, nprec);
- valid_p = true;
- break;
-
- case GT_EXPR:
- gt_expr:
- /* Find out smallest MINV where MINV > VAL
- && (MINV & CST2) == MINV, if any. If VAL is signed and
- CST2 has MSB set, compute it biased by 1 << (nprec - 1). */
- minv = masked_increment (valv, cst2v, sgnbit, nprec);
- if (minv == valv)
- break;
- maxv = wi::mask (nprec - (cst2n ? 1 : 0), false, nprec);
- valid_p = true;
- break;
-
- case LE_EXPR:
- /* Minimum unsigned value for <= is 0 and maximum
- unsigned value is VAL | ~CST2 if (VAL & CST2) == VAL.
- Otherwise, find smallest VAL2 where VAL2 > VAL
- && (VAL2 & CST2) == VAL2 and use (VAL2 - 1) | ~CST2
- as maximum.
- For signed comparison, if CST2 doesn't have most
- significant bit set, handle it similarly. If CST2 has
- MSB set, the maximum is the same and minimum is INT_MIN. */
- if (minv == valv)
- maxv = valv;
- else
- {
- maxv = masked_increment (valv, cst2v, sgnbit, nprec);
- if (maxv == valv)
- break;
- maxv -= 1;
- }
- maxv |= ~cst2v;
- minv = sgnbit;
- valid_p = true;
- break;
-
- case LT_EXPR:
- lt_expr:
- /* Minimum unsigned value for < is 0 and maximum
- unsigned value is (VAL-1) | ~CST2 if (VAL & CST2) == VAL.
- Otherwise, find smallest VAL2 where VAL2 > VAL
- && (VAL2 & CST2) == VAL2 and use (VAL2 - 1) | ~CST2
- as maximum.
- For signed comparison, if CST2 doesn't have most
- significant bit set, handle it similarly. If CST2 has
- MSB set, the maximum is the same and minimum is INT_MIN. */
- if (minv == valv)
- {
- if (valv == sgnbit)
- break;
- maxv = valv;
- }
- else
- {
- maxv = masked_increment (valv, cst2v, sgnbit, nprec);
- if (maxv == valv)
- break;
- }
- maxv -= 1;
- maxv |= ~cst2v;
- minv = sgnbit;
- valid_p = true;
- break;
-
- default:
- break;
- }
- if (valid_p
- && (maxv - minv) != -1)
- {
- tree tmp, new_val, type;
- int i;
-
- for (i = 0; i < 2; i++)
- if (names[i])
- {
- wide_int maxv2 = maxv;
- tmp = names[i];
- type = TREE_TYPE (names[i]);
- if (!TYPE_UNSIGNED (type))
- {
- type = build_nonstandard_integer_type (nprec, 1);
- tmp = build1 (NOP_EXPR, type, names[i]);
- }
- if (minv != 0)
- {
- tmp = build2 (PLUS_EXPR, type, tmp,
- wide_int_to_tree (type, -minv));
- maxv2 = maxv - minv;
- }
- new_val = wide_int_to_tree (type, maxv2);
- add_assert_info (asserts, names[i], tmp, LE_EXPR, new_val);
- }
- }
- }
- }
-}
-
-/* OP is an operand of a truth value expression which is known to have
- a particular value. Register any asserts for OP and for any
- operands in OP's defining statement.
-
- If CODE is EQ_EXPR, then we want to register OP is zero (false),
- if CODE is NE_EXPR, then we want to register OP is nonzero (true). */
-
-static void
-register_edge_assert_for_1 (tree op, enum tree_code code,
- edge e, vec<assert_info> &asserts)
-{
- gimple *op_def;
- tree val;
- enum tree_code rhs_code;
-
- /* We only care about SSA_NAMEs. */
- if (TREE_CODE (op) != SSA_NAME)
- return;
-
- /* We know that OP will have a zero or nonzero value. */
- val = build_int_cst (TREE_TYPE (op), 0);
- add_assert_info (asserts, op, op, code, val);
-
- /* Now look at how OP is set. If it's set from a comparison,
- a truth operation or some bit operations, then we may be able
- to register information about the operands of that assignment. */
- op_def = SSA_NAME_DEF_STMT (op);
- if (gimple_code (op_def) != GIMPLE_ASSIGN)
- return;
-
- rhs_code = gimple_assign_rhs_code (op_def);
-
- if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
- {
- bool invert = (code == EQ_EXPR ? true : false);
- tree op0 = gimple_assign_rhs1 (op_def);
- tree op1 = gimple_assign_rhs2 (op_def);
-
- if (TREE_CODE (op0) == SSA_NAME)
- register_edge_assert_for_2 (op0, e, rhs_code, op0, op1, invert, asserts);
- if (TREE_CODE (op1) == SSA_NAME)
- register_edge_assert_for_2 (op1, e, rhs_code, op0, op1, invert, asserts);
- }
- else if ((code == NE_EXPR
- && gimple_assign_rhs_code (op_def) == BIT_AND_EXPR)
- || (code == EQ_EXPR
- && gimple_assign_rhs_code (op_def) == BIT_IOR_EXPR))
- {
- /* Recurse on each operand. */
- tree op0 = gimple_assign_rhs1 (op_def);
- tree op1 = gimple_assign_rhs2 (op_def);
- if (TREE_CODE (op0) == SSA_NAME
- && has_single_use (op0))
- register_edge_assert_for_1 (op0, code, e, asserts);
- if (TREE_CODE (op1) == SSA_NAME
- && has_single_use (op1))
- register_edge_assert_for_1 (op1, code, e, asserts);
- }
- else if (gimple_assign_rhs_code (op_def) == BIT_NOT_EXPR
- && TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (op_def))) == 1)
- {
- /* Recurse, flipping CODE. */
- code = invert_tree_comparison (code, false);
- register_edge_assert_for_1 (gimple_assign_rhs1 (op_def), code, e, asserts);
- }
- else if (gimple_assign_rhs_code (op_def) == SSA_NAME)
- {
- /* Recurse through the copy. */
- register_edge_assert_for_1 (gimple_assign_rhs1 (op_def), code, e, asserts);
- }
- else if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (op_def)))
- {
- /* Recurse through the type conversion, unless it is a narrowing
- conversion or conversion from non-integral type. */
- tree rhs = gimple_assign_rhs1 (op_def);
- if (INTEGRAL_TYPE_P (TREE_TYPE (rhs))
- && (TYPE_PRECISION (TREE_TYPE (rhs))
- <= TYPE_PRECISION (TREE_TYPE (op))))
- register_edge_assert_for_1 (rhs, code, e, asserts);
- }
-}
-
-/* Check if comparison
- NAME COND_OP INTEGER_CST
- has a form of
- (X & 11...100..0) COND_OP XX...X00...0
- Such comparison can yield assertions like
- X >= XX...X00...0
- X <= XX...X11...1
- in case of COND_OP being EQ_EXPR or
- X < XX...X00...0
- X > XX...X11...1
- in case of NE_EXPR. */
-
-static bool
-is_masked_range_test (tree name, tree valt, enum tree_code cond_code,
- tree *new_name, tree *low, enum tree_code *low_code,
- tree *high, enum tree_code *high_code)
-{
- gimple *def_stmt = SSA_NAME_DEF_STMT (name);
-
- if (!is_gimple_assign (def_stmt)
- || gimple_assign_rhs_code (def_stmt) != BIT_AND_EXPR)
- return false;
-
- tree t = gimple_assign_rhs1 (def_stmt);
- tree maskt = gimple_assign_rhs2 (def_stmt);
- if (TREE_CODE (t) != SSA_NAME || TREE_CODE (maskt) != INTEGER_CST)
- return false;
-
- wi::tree_to_wide_ref mask = wi::to_wide (maskt);
- wide_int inv_mask = ~mask;
- /* Must have been removed by now so don't bother optimizing. */
- if (mask == 0 || inv_mask == 0)
- return false;
-
- /* Assume VALT is INTEGER_CST. */
- wi::tree_to_wide_ref val = wi::to_wide (valt);
-
- if ((inv_mask & (inv_mask + 1)) != 0
- || (val & mask) != val)
- return false;
-
- bool is_range = cond_code == EQ_EXPR;
-
- tree type = TREE_TYPE (t);
- wide_int min = wi::min_value (type),
- max = wi::max_value (type);
-
- if (is_range)
- {
- *low_code = val == min ? ERROR_MARK : GE_EXPR;
- *high_code = val == max ? ERROR_MARK : LE_EXPR;
- }
- else
- {
- /* We can still generate assertion if one of alternatives
- is known to always be false. */
- if (val == min)
- {
- *low_code = (enum tree_code) 0;
- *high_code = GT_EXPR;
- }
- else if ((val | inv_mask) == max)
- {
- *low_code = LT_EXPR;
- *high_code = (enum tree_code) 0;
- }
- else
- return false;
- }
-
- *new_name = t;
- *low = wide_int_to_tree (type, val);
- *high = wide_int_to_tree (type, val | inv_mask);
-
- return true;
-}
-
-/* Try to register an edge assertion for SSA name NAME on edge E for
- the condition COND contributing to the conditional jump pointed to by
- SI. */
-
-void
-register_edge_assert_for (tree name, edge e,
- enum tree_code cond_code, tree cond_op0,
- tree cond_op1, vec<assert_info> &asserts)
-{
- tree val;
- enum tree_code comp_code;
- bool is_else_edge = (e->flags & EDGE_FALSE_VALUE) != 0;
-
- /* Do not attempt to infer anything in names that flow through
- abnormal edges. */
- if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
- return;
-
- if (!extract_code_and_val_from_cond_with_ops (name, cond_code,
- cond_op0, cond_op1,
- is_else_edge,
- &comp_code, &val))
- return;
-
- /* Register ASSERT_EXPRs for name. */
- register_edge_assert_for_2 (name, e, cond_code, cond_op0,
- cond_op1, is_else_edge, asserts);
-
-
- /* If COND is effectively an equality test of an SSA_NAME against
- the value zero or one, then we may be able to assert values
- for SSA_NAMEs which flow into COND. */
-
- /* In the case of NAME == 1 or NAME != 0, for BIT_AND_EXPR defining
- statement of NAME we can assert both operands of the BIT_AND_EXPR
- have nonzero value. */
- if ((comp_code == EQ_EXPR && integer_onep (val))
- || (comp_code == NE_EXPR && integer_zerop (val)))
- {
- gimple *def_stmt = SSA_NAME_DEF_STMT (name);
-
- if (is_gimple_assign (def_stmt)
- && gimple_assign_rhs_code (def_stmt) == BIT_AND_EXPR)
- {
- tree op0 = gimple_assign_rhs1 (def_stmt);
- tree op1 = gimple_assign_rhs2 (def_stmt);
- register_edge_assert_for_1 (op0, NE_EXPR, e, asserts);
- register_edge_assert_for_1 (op1, NE_EXPR, e, asserts);
- }
- else if (is_gimple_assign (def_stmt)
- && (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))
- == tcc_comparison))
- register_edge_assert_for_1 (name, NE_EXPR, e, asserts);
- }
-
- /* In the case of NAME == 0 or NAME != 1, for BIT_IOR_EXPR defining
- statement of NAME we can assert both operands of the BIT_IOR_EXPR
- have zero value. */
- if ((comp_code == EQ_EXPR && integer_zerop (val))
- || (comp_code == NE_EXPR
- && integer_onep (val)
- && TYPE_PRECISION (TREE_TYPE (name)) == 1))
- {
- gimple *def_stmt = SSA_NAME_DEF_STMT (name);
-
- /* For BIT_IOR_EXPR only if NAME == 0 both operands have
- necessarily zero value, or if type-precision is one. */
- if (is_gimple_assign (def_stmt)
- && gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR)
- {
- tree op0 = gimple_assign_rhs1 (def_stmt);
- tree op1 = gimple_assign_rhs2 (def_stmt);
- register_edge_assert_for_1 (op0, EQ_EXPR, e, asserts);
- register_edge_assert_for_1 (op1, EQ_EXPR, e, asserts);
- }
- else if (is_gimple_assign (def_stmt)
- && (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))
- == tcc_comparison))
- register_edge_assert_for_1 (name, EQ_EXPR, e, asserts);
- }
-
- /* Sometimes we can infer ranges from (NAME & MASK) == VALUE. */
- if ((comp_code == EQ_EXPR || comp_code == NE_EXPR)
- && TREE_CODE (val) == INTEGER_CST)
- {
- enum tree_code low_code, high_code;
- tree low, high;
- if (is_masked_range_test (name, val, comp_code, &name, &low,
- &low_code, &high, &high_code))
- {
- if (low_code != ERROR_MARK)
- register_edge_assert_for_2 (name, e, low_code, name,
- low, /*invert*/false, asserts);
- if (high_code != ERROR_MARK)
- register_edge_assert_for_2 (name, e, high_code, name,
- high, /*invert*/false, asserts);
- }
- }
+ true, new_cst);
}
/* Handle
@@ -2413,10 +750,9 @@ register_edge_assert_for (tree name, edge e,
<bb 6>:
__builtin_unreachable ();
<bb 7>:
- x_5 = ASSERT_EXPR <x_3, ...>;
- If x_3 has no other immediate uses (checked by caller),
- var is the x_3 var from ASSERT_EXPR, we can clear low 5 bits
- from the non-zero bitmask. */
+
+ If x_3 has no other immediate uses (checked by caller), var is the
+ x_3 var, we can clear low 5 bits from the non-zero bitmask. */
void
maybe_set_nonzero_bits (edge e, tree var)
@@ -2457,54 +793,6 @@ maybe_set_nonzero_bits (edge e, tree var)
wi::to_wide (cst)));
}
-/* Return true if STMT is interesting for VRP. */
-
-bool
-stmt_interesting_for_vrp (gimple *stmt)
-{
- if (gimple_code (stmt) == GIMPLE_PHI)
- {
- tree res = gimple_phi_result (stmt);
- return (!virtual_operand_p (res)
- && (INTEGRAL_TYPE_P (TREE_TYPE (res))
- || POINTER_TYPE_P (TREE_TYPE (res))));
- }
- else if (is_gimple_assign (stmt) || is_gimple_call (stmt))
- {
- tree lhs = gimple_get_lhs (stmt);
-
- /* In general, assignments with virtual operands are not useful
- for deriving ranges, with the obvious exception of calls to
- builtin functions. */
- if (lhs && TREE_CODE (lhs) == SSA_NAME
- && (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
- || POINTER_TYPE_P (TREE_TYPE (lhs)))
- && (is_gimple_call (stmt)
- || !gimple_vuse (stmt)))
- return true;
- else if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
- switch (gimple_call_internal_fn (stmt))
- {
- case IFN_ADD_OVERFLOW:
- case IFN_SUB_OVERFLOW:
- case IFN_MUL_OVERFLOW:
- case IFN_ATOMIC_COMPARE_EXCHANGE:
- /* These internal calls return _Complex integer type,
- but are interesting to VRP nevertheless. */
- if (lhs && TREE_CODE (lhs) == SSA_NAME)
- return true;
- break;
- default:
- break;
- }
- }
- else if (gimple_code (stmt) == GIMPLE_COND
- || gimple_code (stmt) == GIMPLE_SWITCH)
- return true;
-
- return false;
-}
-
/* Searches the case label vector VEC for the index *IDX of the CASE_LABEL
that includes the value VAL. The search is restricted to the range
[START_IDX, n - 1] where n is the size of VEC.
@@ -2545,7 +833,7 @@ find_case_label_index (gswitch *stmt, size_t start_idx, tree val, size_t *idx)
return true;
}
else if (cmp > 0)
- high = i;
+ high = i;
else
{
low = i + 1;
@@ -2555,7 +843,7 @@ find_case_label_index (gswitch *stmt, size_t start_idx, tree val, size_t *idx)
*idx = i;
return true;
}
- }
+ }
}
*idx = high;
@@ -2627,8 +915,7 @@ tree
find_case_label_range (gswitch *switch_stmt, const irange *range_of_op)
{
if (range_of_op->undefined_p ()
- || range_of_op->varying_p ()
- || range_of_op->symbolic_p ())
+ || range_of_op->varying_p ())
return NULL_TREE;
size_t i, j;
@@ -2684,1750 +971,6 @@ struct case_info
basic_block bb;
};
-/* Location information for ASSERT_EXPRs. Each instance of this
- structure describes an ASSERT_EXPR for an SSA name. Since a single
- SSA name may have more than one assertion associated with it, these
- locations are kept in a linked list attached to the corresponding
- SSA name. */
-struct assert_locus
-{
- /* Basic block where the assertion would be inserted. */
- basic_block bb;
-
- /* Some assertions need to be inserted on an edge (e.g., assertions
- generated by COND_EXPRs). In those cases, BB will be NULL. */
- edge e;
-
- /* Pointer to the statement that generated this assertion. */
- gimple_stmt_iterator si;
-
- /* Predicate code for the ASSERT_EXPR. Must be COMPARISON_CLASS_P. */
- enum tree_code comp_code;
-
- /* Value being compared against. */
- tree val;
-
- /* Expression to compare. */
- tree expr;
-
- /* Next node in the linked list. */
- assert_locus *next;
-};
-
-/* Class to traverse the flowgraph looking for conditional jumps to
- insert ASSERT_EXPR range expressions. These range expressions are
- meant to provide information to optimizations that need to reason
- in terms of value ranges. They will not be expanded into RTL. */
-
-class vrp_asserts
-{
-public:
- vrp_asserts (struct function *fn) : fun (fn) { }
-
- void insert_range_assertions ();
-
- /* Convert range assertion expressions into the implied copies and
- copy propagate away the copies. */
- void remove_range_assertions ();
-
- /* Dump all the registered assertions for all the names to FILE. */
- void dump (FILE *);
-
- /* Dump all the registered assertions for NAME to FILE. */
- void dump (FILE *file, tree name);
-
- /* Dump all the registered assertions for NAME to stderr. */
- void debug (tree name)
- {
- dump (stderr, name);
- }
-
- /* Dump all the registered assertions for all the names to stderr. */
- void debug ()
- {
- dump (stderr);
- }
-
-private:
- /* Set of SSA names found live during the RPO traversal of the function
- for still active basic-blocks. */
- live_names live;
-
- /* Function to work on. */
- struct function *fun;
-
- /* If bit I is present, it means that SSA name N_i has a list of
- assertions that should be inserted in the IL. */
- bitmap need_assert_for;
-
- /* Array of locations lists where to insert assertions. ASSERTS_FOR[I]
- holds a list of ASSERT_LOCUS_T nodes that describe where
- ASSERT_EXPRs for SSA name N_I should be inserted. */
- assert_locus **asserts_for;
-
- /* Finish found ASSERTS for E and register them at GSI. */
- void finish_register_edge_assert_for (edge e, gimple_stmt_iterator gsi,
- vec<assert_info> &asserts);
-
- /* Determine whether the outgoing edges of BB should receive an
- ASSERT_EXPR for each of the operands of BB's LAST statement. The
- last statement of BB must be a SWITCH_EXPR.
-
- If any of the sub-graphs rooted at BB have an interesting use of
- the predicate operands, an assert location node is added to the
- list of assertions for the corresponding operands. */
- void find_switch_asserts (basic_block bb, gswitch *last);
-
- /* Do an RPO walk over the function computing SSA name liveness
- on-the-fly and deciding on assert expressions to insert. */
- void find_assert_locations ();
-
- /* Traverse all the statements in block BB looking for statements that
- may generate useful assertions for the SSA names in their operand.
- See method implementation comentary for more information. */
- void find_assert_locations_in_bb (basic_block bb);
-
- /* Determine whether the outgoing edges of BB should receive an
- ASSERT_EXPR for each of the operands of BB's LAST statement.
- The last statement of BB must be a COND_EXPR.
-
- If any of the sub-graphs rooted at BB have an interesting use of
- the predicate operands, an assert location node is added to the
- list of assertions for the corresponding operands. */
- void find_conditional_asserts (basic_block bb, gcond *last);
-
- /* Process all the insertions registered for every name N_i registered
- in NEED_ASSERT_FOR. The list of assertions to be inserted are
- found in ASSERTS_FOR[i]. */
- void process_assert_insertions ();
-
- /* If NAME doesn't have an ASSERT_EXPR registered for asserting
- 'EXPR COMP_CODE VAL' at a location that dominates block BB or
- E->DEST, then register this location as a possible insertion point
- for ASSERT_EXPR <NAME, EXPR COMP_CODE VAL>.
-
- BB, E and SI provide the exact insertion point for the new
- ASSERT_EXPR. If BB is NULL, then the ASSERT_EXPR is to be inserted
- on edge E. Otherwise, if E is NULL, the ASSERT_EXPR is inserted on
- BB. If SI points to a COND_EXPR or a SWITCH_EXPR statement, then E
- must not be NULL. */
- void register_new_assert_for (tree name, tree expr,
- enum tree_code comp_code,
- tree val, basic_block bb,
- edge e, gimple_stmt_iterator si);
-
- /* Given a COND_EXPR COND of the form 'V OP W', and an SSA name V,
- create a new SSA name N and return the assertion assignment
- 'N = ASSERT_EXPR <V, V OP W>'. */
- gimple *build_assert_expr_for (tree cond, tree v);
-
- /* Create an ASSERT_EXPR for NAME and insert it in the location
- indicated by LOC. Return true if we made any edge insertions. */
- bool process_assert_insertions_for (tree name, assert_locus *loc);
-
- /* Qsort callback for sorting assert locations. */
- template <bool stable> static int compare_assert_loc (const void *,
- const void *);
-
- /* Return false if EXPR is a predicate expression involving floating
- point values. */
- bool fp_predicate (gimple *stmt)
- {
- GIMPLE_CHECK (stmt, GIMPLE_COND);
- return FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)));
- }
-
- bool all_imm_uses_in_stmt_or_feed_cond (tree var, gimple *stmt,
- basic_block cond_bb);
-
- static int compare_case_labels (const void *, const void *);
-};
-
-/* Given a COND_EXPR COND of the form 'V OP W', and an SSA name V,
- create a new SSA name N and return the assertion assignment
- 'N = ASSERT_EXPR <V, V OP W>'. */
-
-gimple *
-vrp_asserts::build_assert_expr_for (tree cond, tree v)
-{
- tree a;
- gassign *assertion;
-
- gcc_assert (TREE_CODE (v) == SSA_NAME
- && COMPARISON_CLASS_P (cond));
-
- a = build2 (ASSERT_EXPR, TREE_TYPE (v), v, cond);
- assertion = gimple_build_assign (NULL_TREE, a);
-
- /* The new ASSERT_EXPR, creates a new SSA name that replaces the
- operand of the ASSERT_EXPR. Create it so the new name and the old one
- are registered in the replacement table so that we can fix the SSA web
- after adding all the ASSERT_EXPRs. */
- tree new_def = create_new_def_for (v, assertion, NULL);
- /* Make sure we preserve abnormalness throughout an ASSERT_EXPR chain
- given we have to be able to fully propagate those out to re-create
- valid SSA when removing the asserts. */
- if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (v))
- SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_def) = 1;
-
- return assertion;
-}
-
-/* Dump all the registered assertions for NAME to FILE. */
-
-void
-vrp_asserts::dump (FILE *file, tree name)
-{
- assert_locus *loc;
-
- fprintf (file, "Assertions to be inserted for ");
- print_generic_expr (file, name);
- fprintf (file, "\n");
-
- loc = asserts_for[SSA_NAME_VERSION (name)];
- while (loc)
- {
- fprintf (file, "\t");
- print_gimple_stmt (file, gsi_stmt (loc->si), 0);
- fprintf (file, "\n\tBB #%d", loc->bb->index);
- if (loc->e)
- {
- fprintf (file, "\n\tEDGE %d->%d", loc->e->src->index,
- loc->e->dest->index);
- dump_edge_info (file, loc->e, dump_flags, 0);
- }
- fprintf (file, "\n\tPREDICATE: ");
- print_generic_expr (file, loc->expr);
- fprintf (file, " %s ", get_tree_code_name (loc->comp_code));
- print_generic_expr (file, loc->val);
- fprintf (file, "\n\n");
- loc = loc->next;
- }
-
- fprintf (file, "\n");
-}
-
-/* Dump all the registered assertions for all the names to FILE. */
-
-void
-vrp_asserts::dump (FILE *file)
-{
- unsigned i;
- bitmap_iterator bi;
-
- fprintf (file, "\nASSERT_EXPRs to be inserted\n\n");
- EXECUTE_IF_SET_IN_BITMAP (need_assert_for, 0, i, bi)
- dump (file, ssa_name (i));
- fprintf (file, "\n");
-}
-
-/* If NAME doesn't have an ASSERT_EXPR registered for asserting
- 'EXPR COMP_CODE VAL' at a location that dominates block BB or
- E->DEST, then register this location as a possible insertion point
- for ASSERT_EXPR <NAME, EXPR COMP_CODE VAL>.
-
- BB, E and SI provide the exact insertion point for the new
- ASSERT_EXPR. If BB is NULL, then the ASSERT_EXPR is to be inserted
- on edge E. Otherwise, if E is NULL, the ASSERT_EXPR is inserted on
- BB. If SI points to a COND_EXPR or a SWITCH_EXPR statement, then E
- must not be NULL. */
-
-void
-vrp_asserts::register_new_assert_for (tree name, tree expr,
- enum tree_code comp_code,
- tree val,
- basic_block bb,
- edge e,
- gimple_stmt_iterator si)
-{
- assert_locus *n, *loc, *last_loc;
- basic_block dest_bb;
-
- gcc_checking_assert (bb == NULL || e == NULL);
-
- if (e == NULL)
- gcc_checking_assert (gimple_code (gsi_stmt (si)) != GIMPLE_COND
- && gimple_code (gsi_stmt (si)) != GIMPLE_SWITCH);
-
- /* Never build an assert comparing against an integer constant with
- TREE_OVERFLOW set. This confuses our undefined overflow warning
- machinery. */
- if (TREE_OVERFLOW_P (val))
- val = drop_tree_overflow (val);
-
- /* The new assertion A will be inserted at BB or E. We need to
- determine if the new location is dominated by a previously
- registered location for A. If we are doing an edge insertion,
- assume that A will be inserted at E->DEST. Note that this is not
- necessarily true.
-
- If E is a critical edge, it will be split. But even if E is
- split, the new block will dominate the same set of blocks that
- E->DEST dominates.
-
- The reverse, however, is not true, blocks dominated by E->DEST
- will not be dominated by the new block created to split E. So,
- if the insertion location is on a critical edge, we will not use
- the new location to move another assertion previously registered
- at a block dominated by E->DEST. */
- dest_bb = (bb) ? bb : e->dest;
-
- /* If NAME already has an ASSERT_EXPR registered for COMP_CODE and
- VAL at a block dominating DEST_BB, then we don't need to insert a new
- one. Similarly, if the same assertion already exists at a block
- dominated by DEST_BB and the new location is not on a critical
- edge, then update the existing location for the assertion (i.e.,
- move the assertion up in the dominance tree).
-
- Note, this is implemented as a simple linked list because there
- should not be more than a handful of assertions registered per
- name. If this becomes a performance problem, a table hashed by
- COMP_CODE and VAL could be implemented. */
- loc = asserts_for[SSA_NAME_VERSION (name)];
- last_loc = loc;
- while (loc)
- {
- if (loc->comp_code == comp_code
- && (loc->val == val
- || operand_equal_p (loc->val, val, 0))
- && (loc->expr == expr
- || operand_equal_p (loc->expr, expr, 0)))
- {
- /* If E is not a critical edge and DEST_BB
- dominates the existing location for the assertion, move
- the assertion up in the dominance tree by updating its
- location information. */
- if ((e == NULL || !EDGE_CRITICAL_P (e))
- && dominated_by_p (CDI_DOMINATORS, loc->bb, dest_bb))
- {
- loc->bb = dest_bb;
- loc->e = e;
- loc->si = si;
- return;
- }
- }
-
- /* Update the last node of the list and move to the next one. */
- last_loc = loc;
- loc = loc->next;
- }
-
- /* If we didn't find an assertion already registered for
- NAME COMP_CODE VAL, add a new one at the end of the list of
- assertions associated with NAME. */
- n = XNEW (struct assert_locus);
- n->bb = dest_bb;
- n->e = e;
- n->si = si;
- n->comp_code = comp_code;
- n->val = val;
- n->expr = expr;
- n->next = NULL;
-
- if (last_loc)
- last_loc->next = n;
- else
- asserts_for[SSA_NAME_VERSION (name)] = n;
-
- bitmap_set_bit (need_assert_for, SSA_NAME_VERSION (name));
-}
-
-/* Finish found ASSERTS for E and register them at GSI. */
-
-void
-vrp_asserts::finish_register_edge_assert_for (edge e,
- gimple_stmt_iterator gsi,
- vec<assert_info> &asserts)
-{
- for (unsigned i = 0; i < asserts.length (); ++i)
- /* Only register an ASSERT_EXPR if NAME was found in the sub-graph
- reachable from E. */
- if (live.live_on_edge_p (asserts[i].name, e))
- register_new_assert_for (asserts[i].name, asserts[i].expr,
- asserts[i].comp_code, asserts[i].val,
- NULL, e, gsi);
-}
-
-/* Determine whether the outgoing edges of BB should receive an
- ASSERT_EXPR for each of the operands of BB's LAST statement.
- The last statement of BB must be a COND_EXPR.
-
- If any of the sub-graphs rooted at BB have an interesting use of
- the predicate operands, an assert location node is added to the
- list of assertions for the corresponding operands. */
-
-void
-vrp_asserts::find_conditional_asserts (basic_block bb, gcond *last)
-{
- gimple_stmt_iterator bsi;
- tree op;
- edge_iterator ei;
- edge e;
- ssa_op_iter iter;
-
- bsi = gsi_for_stmt (last);
-
- /* Look for uses of the operands in each of the sub-graphs
- rooted at BB. We need to check each of the outgoing edges
- separately, so that we know what kind of ASSERT_EXPR to
- insert. */
- FOR_EACH_EDGE (e, ei, bb->succs)
- {
- if (e->dest == bb)
- continue;
-
- /* Register the necessary assertions for each operand in the
- conditional predicate. */
- auto_vec<assert_info, 8> asserts;
- FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
- register_edge_assert_for (op, e,
- gimple_cond_code (last),
- gimple_cond_lhs (last),
- gimple_cond_rhs (last), asserts);
- finish_register_edge_assert_for (e, bsi, asserts);
- }
-}
-
-/* Compare two case labels sorting first by the destination bb index
- and then by the case value. */
-
-int
-vrp_asserts::compare_case_labels (const void *p1, const void *p2)
-{
- const struct case_info *ci1 = (const struct case_info *) p1;
- const struct case_info *ci2 = (const struct case_info *) p2;
- int idx1 = ci1->bb->index;
- int idx2 = ci2->bb->index;
-
- if (idx1 < idx2)
- return -1;
- else if (idx1 == idx2)
- {
- /* Make sure the default label is first in a group. */
- if (!CASE_LOW (ci1->expr))
- return -1;
- else if (!CASE_LOW (ci2->expr))
- return 1;
- else
- return tree_int_cst_compare (CASE_LOW (ci1->expr),
- CASE_LOW (ci2->expr));
- }
- else
- return 1;
-}
-
-/* Determine whether the outgoing edges of BB should receive an
- ASSERT_EXPR for each of the operands of BB's LAST statement.
- The last statement of BB must be a SWITCH_EXPR.
-
- If any of the sub-graphs rooted at BB have an interesting use of
- the predicate operands, an assert location node is added to the
- list of assertions for the corresponding operands. */
-
-void
-vrp_asserts::find_switch_asserts (basic_block bb, gswitch *last)
-{
- gimple_stmt_iterator bsi;
- tree op;
- edge e;
- struct case_info *ci;
- size_t n = gimple_switch_num_labels (last);
-#if GCC_VERSION >= 4000
- unsigned int idx;
-#else
- /* Work around GCC 3.4 bug (PR 37086). */
- volatile unsigned int idx;
-#endif
-
- bsi = gsi_for_stmt (last);
- op = gimple_switch_index (last);
- if (TREE_CODE (op) != SSA_NAME)
- return;
-
- /* Build a vector of case labels sorted by destination label. */
- ci = XNEWVEC (struct case_info, n);
- for (idx = 0; idx < n; ++idx)
- {
- ci[idx].expr = gimple_switch_label (last, idx);
- ci[idx].bb = label_to_block (fun, CASE_LABEL (ci[idx].expr));
- }
- edge default_edge = find_edge (bb, ci[0].bb);
- qsort (ci, n, sizeof (struct case_info), compare_case_labels);
-
- for (idx = 0; idx < n; ++idx)
- {
- tree min, max;
- tree cl = ci[idx].expr;
- basic_block cbb = ci[idx].bb;
-
- min = CASE_LOW (cl);
- max = CASE_HIGH (cl);
-
- /* If there are multiple case labels with the same destination
- we need to combine them to a single value range for the edge. */
- if (idx + 1 < n && cbb == ci[idx + 1].bb)
- {
- /* Skip labels until the last of the group. */
- do {
- ++idx;
- } while (idx < n && cbb == ci[idx].bb);
- --idx;
-
- /* Pick up the maximum of the case label range. */
- if (CASE_HIGH (ci[idx].expr))
- max = CASE_HIGH (ci[idx].expr);
- else
- max = CASE_LOW (ci[idx].expr);
- }
-
- /* Can't extract a useful assertion out of a range that includes the
- default label. */
- if (min == NULL_TREE)
- continue;
-
- /* Find the edge to register the assert expr on. */
- e = find_edge (bb, cbb);
-
- /* Register the necessary assertions for the operand in the
- SWITCH_EXPR. */
- auto_vec<assert_info, 8> asserts;
- register_edge_assert_for (op, e,
- max ? GE_EXPR : EQ_EXPR,
- op, fold_convert (TREE_TYPE (op), min),
- asserts);
- if (max)
- register_edge_assert_for (op, e, LE_EXPR, op,
- fold_convert (TREE_TYPE (op), max),
- asserts);
- finish_register_edge_assert_for (e, bsi, asserts);
- }
-
- XDELETEVEC (ci);
-
- if (!live.live_on_edge_p (op, default_edge))
- return;
-
- /* Now register along the default label assertions that correspond to the
- anti-range of each label. */
- int insertion_limit = param_max_vrp_switch_assertions;
- if (insertion_limit == 0)
- return;
-
- /* We can't do this if the default case shares a label with another case. */
- tree default_cl = gimple_switch_default_label (last);
- for (idx = 1; idx < n; idx++)
- {
- tree min, max;
- tree cl = gimple_switch_label (last, idx);
- if (CASE_LABEL (cl) == CASE_LABEL (default_cl))
- continue;
-
- min = CASE_LOW (cl);
- max = CASE_HIGH (cl);
-
- /* Combine contiguous case ranges to reduce the number of assertions
- to insert. */
- for (idx = idx + 1; idx < n; idx++)
- {
- tree next_min, next_max;
- tree next_cl = gimple_switch_label (last, idx);
- if (CASE_LABEL (next_cl) == CASE_LABEL (default_cl))
- break;
-
- next_min = CASE_LOW (next_cl);
- next_max = CASE_HIGH (next_cl);
-
- wide_int difference = (wi::to_wide (next_min)
- - wi::to_wide (max ? max : min));
- if (wi::eq_p (difference, 1))
- max = next_max ? next_max : next_min;
- else
- break;
- }
- idx--;
-
- if (max == NULL_TREE)
- {
- /* Register the assertion OP != MIN. */
- auto_vec<assert_info, 8> asserts;
- min = fold_convert (TREE_TYPE (op), min);
- register_edge_assert_for (op, default_edge, NE_EXPR, op, min,
- asserts);
- finish_register_edge_assert_for (default_edge, bsi, asserts);
- }
- else
- {
- /* Register the assertion (unsigned)OP - MIN > (MAX - MIN),
- which will give OP the anti-range ~[MIN,MAX]. */
- tree uop = fold_convert (unsigned_type_for (TREE_TYPE (op)), op);
- min = fold_convert (TREE_TYPE (uop), min);
- max = fold_convert (TREE_TYPE (uop), max);
-
- tree lhs = fold_build2 (MINUS_EXPR, TREE_TYPE (uop), uop, min);
- tree rhs = int_const_binop (MINUS_EXPR, max, min);
- register_new_assert_for (op, lhs, GT_EXPR, rhs,
- NULL, default_edge, bsi);
- }
-
- if (--insertion_limit == 0)
- break;
- }
-}
-
-/* Traverse all the statements in block BB looking for statements that
- may generate useful assertions for the SSA names in their operand.
- If a statement produces a useful assertion A for name N_i, then the
- list of assertions already generated for N_i is scanned to
- determine if A is actually needed.
-
- If N_i already had the assertion A at a location dominating the
- current location, then nothing needs to be done. Otherwise, the
- new location for A is recorded instead.
-
- 1- For every statement S in BB, all the variables used by S are
- added to bitmap FOUND_IN_SUBGRAPH.
-
- 2- If statement S uses an operand N in a way that exposes a known
- value range for N, then if N was not already generated by an
- ASSERT_EXPR, create a new assert location for N. For instance,
- if N is a pointer and the statement dereferences it, we can
- assume that N is not NULL.
-
- 3- COND_EXPRs are a special case of #2. We can derive range
- information from the predicate but need to insert different
- ASSERT_EXPRs for each of the sub-graphs rooted at the
- conditional block. If the last statement of BB is a conditional
- expression of the form 'X op Y', then
-
- a) Remove X and Y from the set FOUND_IN_SUBGRAPH.
-
- b) If the conditional is the only entry point to the sub-graph
- corresponding to the THEN_CLAUSE, recurse into it. On
- return, if X and/or Y are marked in FOUND_IN_SUBGRAPH, then
- an ASSERT_EXPR is added for the corresponding variable.
-
- c) Repeat step (b) on the ELSE_CLAUSE.
-
- d) Mark X and Y in FOUND_IN_SUBGRAPH.
-
- For instance,
-
- if (a == 9)
- b = a;
- else
- b = c + 1;
-
- In this case, an assertion on the THEN clause is useful to
- determine that 'a' is always 9 on that edge. However, an assertion
- on the ELSE clause would be unnecessary.
-
- 4- If BB does not end in a conditional expression, then we recurse
- into BB's dominator children.
-
- At the end of the recursive traversal, every SSA name will have a
- list of locations where ASSERT_EXPRs should be added. When a new
- location for name N is found, it is registered by calling
- register_new_assert_for. That function keeps track of all the
- registered assertions to prevent adding unnecessary assertions.
- For instance, if a pointer P_4 is dereferenced more than once in a
- dominator tree, only the location dominating all the dereference of
- P_4 will receive an ASSERT_EXPR. */
-
-void
-vrp_asserts::find_assert_locations_in_bb (basic_block bb)
-{
- gimple *last;
-
- last = last_stmt (bb);
-
- /* If BB's last statement is a conditional statement involving integer
- operands, determine if we need to add ASSERT_EXPRs. */
- if (last
- && gimple_code (last) == GIMPLE_COND
- && !fp_predicate (last)
- && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
- find_conditional_asserts (bb, as_a <gcond *> (last));
-
- /* If BB's last statement is a switch statement involving integer
- operands, determine if we need to add ASSERT_EXPRs. */
- if (last
- && gimple_code (last) == GIMPLE_SWITCH
- && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
- find_switch_asserts (bb, as_a <gswitch *> (last));
-
- /* Traverse all the statements in BB marking used names and looking
- for statements that may infer assertions for their used operands. */
- for (gimple_stmt_iterator si = gsi_last_bb (bb); !gsi_end_p (si);
- gsi_prev (&si))
- {
- gimple *stmt;
- tree op;
- ssa_op_iter i;
-
- stmt = gsi_stmt (si);
-
- if (is_gimple_debug (stmt))
- continue;
-
- /* See if we can derive an assertion for any of STMT's operands. */
- FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
- {
- tree value;
- enum tree_code comp_code;
-
- /* If op is not live beyond this stmt, do not bother to insert
- asserts for it. */
- if (!live.live_on_block_p (op, bb))
- continue;
-
- /* If OP is used in such a way that we can infer a value
- range for it, and we don't find a previous assertion for
- it, create a new assertion location node for OP. */
- if (infer_value_range (stmt, op, &comp_code, &value))
- {
- /* If we are able to infer a nonzero value range for OP,
- then walk backwards through the use-def chain to see if OP
- was set via a typecast.
-
- If so, then we can also infer a nonzero value range
- for the operand of the NOP_EXPR. */
- if (comp_code == NE_EXPR && integer_zerop (value))
- {
- tree t = op;
- gimple *def_stmt = SSA_NAME_DEF_STMT (t);
-
- while (is_gimple_assign (def_stmt)
- && CONVERT_EXPR_CODE_P
- (gimple_assign_rhs_code (def_stmt))
- && TREE_CODE
- (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
- && POINTER_TYPE_P
- (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
- {
- t = gimple_assign_rhs1 (def_stmt);
- def_stmt = SSA_NAME_DEF_STMT (t);
-
- /* Note we want to register the assert for the
- operand of the NOP_EXPR after SI, not after the
- conversion. */
- if (live.live_on_block_p (t, bb))
- register_new_assert_for (t, t, comp_code, value,
- bb, NULL, si);
- }
- }
-
- register_new_assert_for (op, op, comp_code, value, bb, NULL, si);
- }
- }
-
- /* Update live. */
- FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
- live.set (op, bb);
- FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF)
- live.clear (op, bb);
- }
-
- /* Traverse all PHI nodes in BB, updating live. */
- for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
- gsi_next (&si))
- {
- use_operand_p arg_p;
- ssa_op_iter i;
- gphi *phi = si.phi ();
- tree res = gimple_phi_result (phi);
-
- if (virtual_operand_p (res))
- continue;
-
- FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_USE)
- {
- tree arg = USE_FROM_PTR (arg_p);
- if (TREE_CODE (arg) == SSA_NAME)
- live.set (arg, bb);
- }
-
- live.clear (res, bb);
- }
-}
-
-/* Do an RPO walk over the function computing SSA name liveness
- on-the-fly and deciding on assert expressions to insert. */
-
-void
-vrp_asserts::find_assert_locations (void)
-{
- int *rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
- int *bb_rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
- int *last_rpo = XCNEWVEC (int, last_basic_block_for_fn (fun));
- int rpo_cnt, i;
-
- rpo_cnt = pre_and_rev_post_order_compute (NULL, rpo, false);
- for (i = 0; i < rpo_cnt; ++i)
- bb_rpo[rpo[i]] = i;
-
- /* Pre-seed loop latch liveness from loop header PHI nodes. Due to
- the order we compute liveness and insert asserts we otherwise
- fail to insert asserts into the loop latch. */
- for (auto loop : loops_list (cfun, 0))
- {
- i = loop->latch->index;
- unsigned int j = single_succ_edge (loop->latch)->dest_idx;
- for (gphi_iterator gsi = gsi_start_phis (loop->header);
- !gsi_end_p (gsi); gsi_next (&gsi))
- {
- gphi *phi = gsi.phi ();
- if (virtual_operand_p (gimple_phi_result (phi)))
- continue;
- tree arg = gimple_phi_arg_def (phi, j);
- if (TREE_CODE (arg) == SSA_NAME)
- live.set (arg, loop->latch);
- }
- }
-
- for (i = rpo_cnt - 1; i >= 0; --i)
- {
- basic_block bb = BASIC_BLOCK_FOR_FN (fun, rpo[i]);
- edge e;
- edge_iterator ei;
-
- /* Process BB and update the live information with uses in
- this block. */
- find_assert_locations_in_bb (bb);
-
- /* Merge liveness into the predecessor blocks and free it. */
- if (!live.block_has_live_names_p (bb))
- {
- int pred_rpo = i;
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- int pred = e->src->index;
- if ((e->flags & EDGE_DFS_BACK) || pred == ENTRY_BLOCK)
- continue;
-
- live.merge (e->src, bb);
-
- if (bb_rpo[pred] < pred_rpo)
- pred_rpo = bb_rpo[pred];
- }
-
- /* Record the RPO number of the last visited block that needs
- live information from this block. */
- last_rpo[rpo[i]] = pred_rpo;
- }
- else
- live.clear_block (bb);
-
- /* We can free all successors live bitmaps if all their
- predecessors have been visited already. */
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (last_rpo[e->dest->index] == i)
- live.clear_block (e->dest);
- }
-
- XDELETEVEC (rpo);
- XDELETEVEC (bb_rpo);
- XDELETEVEC (last_rpo);
-}
-
-/* Create an ASSERT_EXPR for NAME and insert it in the location
- indicated by LOC. Return true if we made any edge insertions. */
-
-bool
-vrp_asserts::process_assert_insertions_for (tree name, assert_locus *loc)
-{
- /* Build the comparison expression NAME_i COMP_CODE VAL. */
- gimple *stmt;
- tree cond;
- gimple *assert_stmt;
- edge_iterator ei;
- edge e;
-
- /* If we have X <=> X do not insert an assert expr for that. */
- if (loc->expr == loc->val)
- return false;
-
- cond = build2 (loc->comp_code, boolean_type_node, loc->expr, loc->val);
- assert_stmt = build_assert_expr_for (cond, name);
- if (loc->e)
- {
- /* We have been asked to insert the assertion on an edge. This
- is used only by COND_EXPR and SWITCH_EXPR assertions. */
- gcc_checking_assert (gimple_code (gsi_stmt (loc->si)) == GIMPLE_COND
- || (gimple_code (gsi_stmt (loc->si))
- == GIMPLE_SWITCH));
-
- gsi_insert_on_edge (loc->e, assert_stmt);
- return true;
- }
-
- /* If the stmt iterator points at the end then this is an insertion
- at the beginning of a block. */
- if (gsi_end_p (loc->si))
- {
- gimple_stmt_iterator si = gsi_after_labels (loc->bb);
- gsi_insert_before (&si, assert_stmt, GSI_SAME_STMT);
- return false;
-
- }
- /* Otherwise, we can insert right after LOC->SI iff the
- statement must not be the last statement in the block. */
- stmt = gsi_stmt (loc->si);
- if (!stmt_ends_bb_p (stmt))
- {
- gsi_insert_after (&loc->si, assert_stmt, GSI_SAME_STMT);
- return false;
- }
-
- /* If STMT must be the last statement in BB, we can only insert new
- assertions on the non-abnormal edge out of BB. Note that since
- STMT is not control flow, there may only be one non-abnormal/eh edge
- out of BB. */
- FOR_EACH_EDGE (e, ei, loc->bb->succs)
- if (!(e->flags & (EDGE_ABNORMAL|EDGE_EH)))
- {
- gsi_insert_on_edge (e, assert_stmt);
- return true;
- }
-
- gcc_unreachable ();
-}
-
-/* Qsort helper for sorting assert locations. If stable is true, don't
- use iterative_hash_expr because it can be unstable for -fcompare-debug,
- on the other side some pointers might be NULL. */
-
-template <bool stable>
-int
-vrp_asserts::compare_assert_loc (const void *pa, const void *pb)
-{
- assert_locus * const a = *(assert_locus * const *)pa;
- assert_locus * const b = *(assert_locus * const *)pb;
-
- /* If stable, some asserts might be optimized away already, sort
- them last. */
- if (stable)
- {
- if (a == NULL)
- return b != NULL;
- else if (b == NULL)
- return -1;
- }
-
- if (a->e == NULL && b->e != NULL)
- return 1;
- else if (a->e != NULL && b->e == NULL)
- return -1;
-
- /* After the above checks, we know that (a->e == NULL) == (b->e == NULL),
- no need to test both a->e and b->e. */
-
- /* Sort after destination index. */
- if (a->e == NULL)
- ;
- else if (a->e->dest->index > b->e->dest->index)
- return 1;
- else if (a->e->dest->index < b->e->dest->index)
- return -1;
-
- /* Sort after comp_code. */
- if (a->comp_code > b->comp_code)
- return 1;
- else if (a->comp_code < b->comp_code)
- return -1;
-
- hashval_t ha, hb;
-
- /* E.g. if a->val is ADDR_EXPR of a VAR_DECL, iterative_hash_expr
- uses DECL_UID of the VAR_DECL, so sorting might differ between
- -g and -g0. When doing the removal of redundant assert exprs
- and commonization to successors, this does not matter, but for
- the final sort needs to be stable. */
- if (stable)
- {
- ha = 0;
- hb = 0;
- }
- else
- {
- ha = iterative_hash_expr (a->expr, iterative_hash_expr (a->val, 0));
- hb = iterative_hash_expr (b->expr, iterative_hash_expr (b->val, 0));
- }
-
- /* Break the tie using hashing and source/bb index. */
- if (ha == hb)
- return (a->e != NULL
- ? a->e->src->index - b->e->src->index
- : a->bb->index - b->bb->index);
- return ha > hb ? 1 : -1;
-}
-
-/* Process all the insertions registered for every name N_i registered
- in NEED_ASSERT_FOR. The list of assertions to be inserted are
- found in ASSERTS_FOR[i]. */
-
-void
-vrp_asserts::process_assert_insertions ()
-{
- unsigned i;
- bitmap_iterator bi;
- bool update_edges_p = false;
- int num_asserts = 0;
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- dump (dump_file);
-
- EXECUTE_IF_SET_IN_BITMAP (need_assert_for, 0, i, bi)
- {
- assert_locus *loc = asserts_for[i];
- gcc_assert (loc);
-
- auto_vec<assert_locus *, 16> asserts;
- for (; loc; loc = loc->next)
- asserts.safe_push (loc);
- asserts.qsort (compare_assert_loc<false>);
-
- /* Push down common asserts to successors and remove redundant ones. */
- unsigned ecnt = 0;
- assert_locus *common = NULL;
- unsigned commonj = 0;
- for (unsigned j = 0; j < asserts.length (); ++j)
- {
- loc = asserts[j];
- if (! loc->e)
- common = NULL;
- else if (! common
- || loc->e->dest != common->e->dest
- || loc->comp_code != common->comp_code
- || ! operand_equal_p (loc->val, common->val, 0)
- || ! operand_equal_p (loc->expr, common->expr, 0))
- {
- commonj = j;
- common = loc;
- ecnt = 1;
- }
- else if (loc->e == asserts[j-1]->e)
- {
- /* Remove duplicate asserts. */
- if (commonj == j - 1)
- {
- commonj = j;
- common = loc;
- }
- free (asserts[j-1]);
- asserts[j-1] = NULL;
- }
- else
- {
- ecnt++;
- if (EDGE_COUNT (common->e->dest->preds) == ecnt)
- {
- /* We have the same assertion on all incoming edges of a BB.
- Insert it at the beginning of that block. */
- loc->bb = loc->e->dest;
- loc->e = NULL;
- loc->si = gsi_none ();
- common = NULL;
- /* Clear asserts commoned. */
- for (; commonj != j; ++commonj)
- if (asserts[commonj])
- {
- free (asserts[commonj]);
- asserts[commonj] = NULL;
- }
- }
- }
- }
-
- /* The asserts vector sorting above might be unstable for
- -fcompare-debug, sort again to ensure a stable sort. */
- asserts.qsort (compare_assert_loc<true>);
- for (unsigned j = 0; j < asserts.length (); ++j)
- {
- loc = asserts[j];
- if (! loc)
- break;
- update_edges_p |= process_assert_insertions_for (ssa_name (i), loc);
- num_asserts++;
- free (loc);
- }
- }
-
- if (update_edges_p)
- gsi_commit_edge_inserts ();
-
- statistics_counter_event (fun, "Number of ASSERT_EXPR expressions inserted",
- num_asserts);
-}
-
-/* Traverse the flowgraph looking for conditional jumps to insert range
- expressions. These range expressions are meant to provide information
- to optimizations that need to reason in terms of value ranges. They
- will not be expanded into RTL. For instance, given:
-
- x = ...
- y = ...
- if (x < y)
- y = x - 2;
- else
- x = y + 3;
-
- this pass will transform the code into:
-
- x = ...
- y = ...
- if (x < y)
- {
- x = ASSERT_EXPR <x, x < y>
- y = x - 2
- }
- else
- {
- y = ASSERT_EXPR <y, x >= y>
- x = y + 3
- }
-
- The idea is that once copy and constant propagation have run, other
- optimizations will be able to determine what ranges of values can 'x'
- take in different paths of the code, simply by checking the reaching
- definition of 'x'. */
-
-void
-vrp_asserts::insert_range_assertions (void)
-{
- need_assert_for = BITMAP_ALLOC (NULL);
- asserts_for = XCNEWVEC (assert_locus *, num_ssa_names);
-
- calculate_dominance_info (CDI_DOMINATORS);
-
- find_assert_locations ();
- if (!bitmap_empty_p (need_assert_for))
- {
- process_assert_insertions ();
- update_ssa (TODO_update_ssa_no_phi);
- }
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "\nSSA form after inserting ASSERT_EXPRs\n");
- dump_function_to_file (current_function_decl, dump_file, dump_flags);
- }
-
- free (asserts_for);
- BITMAP_FREE (need_assert_for);
-}
-
-/* Return true if all imm uses of VAR are either in STMT, or
- feed (optionally through a chain of single imm uses) GIMPLE_COND
- in basic block COND_BB. */
-
-bool
-vrp_asserts::all_imm_uses_in_stmt_or_feed_cond (tree var,
- gimple *stmt,
- basic_block cond_bb)
-{
- use_operand_p use_p, use2_p;
- imm_use_iterator iter;
-
- FOR_EACH_IMM_USE_FAST (use_p, iter, var)
- if (USE_STMT (use_p) != stmt)
- {
- gimple *use_stmt = USE_STMT (use_p), *use_stmt2;
- if (is_gimple_debug (use_stmt))
- continue;
- while (is_gimple_assign (use_stmt)
- && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
- && single_imm_use (gimple_assign_lhs (use_stmt),
- &use2_p, &use_stmt2))
- use_stmt = use_stmt2;
- if (gimple_code (use_stmt) != GIMPLE_COND
- || gimple_bb (use_stmt) != cond_bb)
- return false;
- }
- return true;
-}
-
-/* Convert range assertion expressions into the implied copies and
- copy propagate away the copies. Doing the trivial copy propagation
- here avoids the need to run the full copy propagation pass after
- VRP.
-
- FIXME, this will eventually lead to copy propagation removing the
- names that had useful range information attached to them. For
- instance, if we had the assertion N_i = ASSERT_EXPR <N_j, N_j > 3>,
- then N_i will have the range [3, +INF].
-
- However, by converting the assertion into the implied copy
- operation N_i = N_j, we will then copy-propagate N_j into the uses
- of N_i and lose the range information.
-
- The problem with keeping ASSERT_EXPRs around is that passes after
- VRP need to handle them appropriately.
-
- Another approach would be to make the range information a first
- class property of the SSA_NAME so that it can be queried from
- any pass. This is made somewhat more complex by the need for
- multiple ranges to be associated with one SSA_NAME. */
-
-void
-vrp_asserts::remove_range_assertions ()
-{
- basic_block bb;
- gimple_stmt_iterator si;
- /* 1 if looking at ASSERT_EXPRs immediately at the beginning of
- a basic block preceeded by GIMPLE_COND branching to it and
- __builtin_trap, -1 if not yet checked, 0 otherwise. */
- int is_unreachable;
-
- /* Note that the BSI iterator bump happens at the bottom of the
- loop and no bump is necessary if we're removing the statement
- referenced by the current BSI. */
- FOR_EACH_BB_FN (bb, fun)
- for (si = gsi_after_labels (bb), is_unreachable = -1; !gsi_end_p (si);)
- {
- gimple *stmt = gsi_stmt (si);
-
- if (is_gimple_assign (stmt)
- && gimple_assign_rhs_code (stmt) == ASSERT_EXPR)
- {
- tree lhs = gimple_assign_lhs (stmt);
- tree rhs = gimple_assign_rhs1 (stmt);
- tree var;
-
- var = ASSERT_EXPR_VAR (rhs);
-
- if (TREE_CODE (var) == SSA_NAME
- && !POINTER_TYPE_P (TREE_TYPE (lhs))
- && SSA_NAME_RANGE_INFO (lhs))
- {
- if (is_unreachable == -1)
- {
- is_unreachable = 0;
- if (single_pred_p (bb)
- && assert_unreachable_fallthru_edge_p
- (single_pred_edge (bb)))
- is_unreachable = 1;
- }
- /* Handle
- if (x_7 >= 10 && x_7 < 20)
- __builtin_unreachable ();
- x_8 = ASSERT_EXPR <x_7, ...>;
- if the only uses of x_7 are in the ASSERT_EXPR and
- in the condition. In that case, we can copy the
- range info from x_8 computed in this pass also
- for x_7. */
- if (is_unreachable
- && all_imm_uses_in_stmt_or_feed_cond (var, stmt,
- single_pred (bb)))
- {
- if (SSA_NAME_RANGE_INFO (var))
- {
- /* ?? This is a minor wart exposing the
- internals of SSA_NAME_RANGE_INFO in order
- to maintain existing behavior. This is
- because duplicate_ssa_name_range_info below
- needs a NULL destination range. This is
- all slated for removal... */
- ggc_free (SSA_NAME_RANGE_INFO (var));
- SSA_NAME_RANGE_INFO (var) = NULL;
- }
- duplicate_ssa_name_range_info (var, lhs);
- maybe_set_nonzero_bits (single_pred_edge (bb), var);
- }
- }
-
- /* Propagate the RHS into every use of the LHS. For SSA names
- also propagate abnormals as it merely restores the original
- IL in this case (an replace_uses_by would assert). */
- if (TREE_CODE (var) == SSA_NAME)
- {
- imm_use_iterator iter;
- use_operand_p use_p;
- gimple *use_stmt;
- FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
- FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
- SET_USE (use_p, var);
- }
- else
- replace_uses_by (lhs, var);
-
- /* And finally, remove the copy, it is not needed. */
- gsi_remove (&si, true);
- release_defs (stmt);
- }
- else
- {
- if (!is_gimple_debug (gsi_stmt (si)))
- is_unreachable = 0;
- gsi_next (&si);
- }
- }
-}
-
-class vrp_prop : public ssa_propagation_engine
-{
-public:
- vrp_prop (vr_values *v)
- : ssa_propagation_engine (),
- m_vr_values (v) { }
-
- void initialize (struct function *);
- void finalize ();
-
-private:
- enum ssa_prop_result visit_stmt (gimple *, edge *, tree *) final override;
- enum ssa_prop_result visit_phi (gphi *) final override;
-
- struct function *fun;
- vr_values *m_vr_values;
-};
-
-/* Initialization required by ssa_propagate engine. */
-
-void
-vrp_prop::initialize (struct function *fn)
-{
- basic_block bb;
- fun = fn;
-
- FOR_EACH_BB_FN (bb, fun)
- {
- for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
- gsi_next (&si))
- {
- gphi *phi = si.phi ();
- if (!stmt_interesting_for_vrp (phi))
- {
- tree lhs = PHI_RESULT (phi);
- m_vr_values->set_def_to_varying (lhs);
- prop_set_simulate_again (phi, false);
- }
- else
- prop_set_simulate_again (phi, true);
- }
-
- for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si);
- gsi_next (&si))
- {
- gimple *stmt = gsi_stmt (si);
-
- /* If the statement is a control insn, then we do not
- want to avoid simulating the statement once. Failure
- to do so means that those edges will never get added. */
- if (stmt_ends_bb_p (stmt))
- prop_set_simulate_again (stmt, true);
- else if (!stmt_interesting_for_vrp (stmt))
- {
- m_vr_values->set_defs_to_varying (stmt);
- prop_set_simulate_again (stmt, false);
- }
- else
- prop_set_simulate_again (stmt, true);
- }
- }
-}
-
-/* Evaluate statement STMT. If the statement produces a useful range,
- return SSA_PROP_INTERESTING and record the SSA name with the
- interesting range into *OUTPUT_P.
-
- If STMT is a conditional branch and we can determine its truth
- value, the taken edge is recorded in *TAKEN_EDGE_P.
-
- If STMT produces a varying value, return SSA_PROP_VARYING. */
-
-enum ssa_prop_result
-vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
-{
- tree lhs = gimple_get_lhs (stmt);
- value_range_equiv vr;
- m_vr_values->extract_range_from_stmt (stmt, taken_edge_p, output_p, &vr);
-
- if (*output_p)
- {
- if (m_vr_values->update_value_range (*output_p, &vr))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Found new range for ");
- print_generic_expr (dump_file, *output_p);
- fprintf (dump_file, ": ");
- dump_value_range (dump_file, &vr);
- fprintf (dump_file, "\n");
- }
-
- if (vr.varying_p ())
- return SSA_PROP_VARYING;
-
- return SSA_PROP_INTERESTING;
- }
- return SSA_PROP_NOT_INTERESTING;
- }
-
- if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
- switch (gimple_call_internal_fn (stmt))
- {
- case IFN_ADD_OVERFLOW:
- case IFN_SUB_OVERFLOW:
- case IFN_MUL_OVERFLOW:
- case IFN_ATOMIC_COMPARE_EXCHANGE:
- /* These internal calls return _Complex integer type,
- which VRP does not track, but the immediate uses
- thereof might be interesting. */
- if (lhs && TREE_CODE (lhs) == SSA_NAME)
- {
- imm_use_iterator iter;
- use_operand_p use_p;
- enum ssa_prop_result res = SSA_PROP_VARYING;
-
- m_vr_values->set_def_to_varying (lhs);
-
- FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
- {
- gimple *use_stmt = USE_STMT (use_p);
- if (!is_gimple_assign (use_stmt))
- continue;
- enum tree_code rhs_code = gimple_assign_rhs_code (use_stmt);
- if (rhs_code != REALPART_EXPR && rhs_code != IMAGPART_EXPR)
- continue;
- tree rhs1 = gimple_assign_rhs1 (use_stmt);
- tree use_lhs = gimple_assign_lhs (use_stmt);
- if (TREE_CODE (rhs1) != rhs_code
- || TREE_OPERAND (rhs1, 0) != lhs
- || TREE_CODE (use_lhs) != SSA_NAME
- || !stmt_interesting_for_vrp (use_stmt)
- || (!INTEGRAL_TYPE_P (TREE_TYPE (use_lhs))
- || !TYPE_MIN_VALUE (TREE_TYPE (use_lhs))
- || !TYPE_MAX_VALUE (TREE_TYPE (use_lhs))))
- continue;
-
- /* If there is a change in the value range for any of the
- REALPART_EXPR/IMAGPART_EXPR immediate uses, return
- SSA_PROP_INTERESTING. If there are any REALPART_EXPR
- or IMAGPART_EXPR immediate uses, but none of them have
- a change in their value ranges, return
- SSA_PROP_NOT_INTERESTING. If there are no
- {REAL,IMAG}PART_EXPR uses at all,
- return SSA_PROP_VARYING. */
- value_range_equiv new_vr;
- m_vr_values->extract_range_basic (&new_vr, use_stmt);
- const value_range_equiv *old_vr
- = m_vr_values->get_value_range (use_lhs);
- if (!old_vr->equal_p (new_vr, /*ignore_equivs=*/false))
- res = SSA_PROP_INTERESTING;
- else
- res = SSA_PROP_NOT_INTERESTING;
- new_vr.equiv_clear ();
- if (res == SSA_PROP_INTERESTING)
- {
- *output_p = lhs;
- return res;
- }
- }
-
- return res;
- }
- break;
- default:
- break;
- }
-
- /* All other statements produce nothing of interest for VRP, so mark
- their outputs varying and prevent further simulation. */
- m_vr_values->set_defs_to_varying (stmt);
-
- return (*taken_edge_p) ? SSA_PROP_INTERESTING : SSA_PROP_VARYING;
-}
-
-/* Visit all arguments for PHI node PHI that flow through executable
- edges. If a valid value range can be derived from all the incoming
- value ranges, set a new range for the LHS of PHI. */
-
-enum ssa_prop_result
-vrp_prop::visit_phi (gphi *phi)
-{
- tree lhs = PHI_RESULT (phi);
- value_range_equiv vr_result;
- m_vr_values->extract_range_from_phi_node (phi, &vr_result);
- if (m_vr_values->update_value_range (lhs, &vr_result))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Found new range for ");
- print_generic_expr (dump_file, lhs);
- fprintf (dump_file, ": ");
- dump_value_range (dump_file, &vr_result);
- fprintf (dump_file, "\n");
- }
-
- if (vr_result.varying_p ())
- return SSA_PROP_VARYING;
-
- return SSA_PROP_INTERESTING;
- }
-
- /* Nothing changed, don't add outgoing edges. */
- return SSA_PROP_NOT_INTERESTING;
-}
-
-/* Traverse all the blocks folding conditionals with known ranges. */
-
-void
-vrp_prop::finalize ()
-{
- size_t i;
-
- /* We have completed propagating through the lattice. */
- m_vr_values->set_lattice_propagation_complete ();
-
- if (dump_file)
- {
- fprintf (dump_file, "\nValue ranges after VRP:\n\n");
- m_vr_values->dump (dump_file);
- fprintf (dump_file, "\n");
- }
-
- /* Set value range to non pointer SSA_NAMEs. */
- for (i = 0; i < num_ssa_names; i++)
- {
- tree name = ssa_name (i);
- if (!name)
- continue;
-
- const value_range_equiv *vr = m_vr_values->get_value_range (name);
- if (!name || vr->varying_p () || !vr->constant_p ())
- continue;
-
- if (POINTER_TYPE_P (TREE_TYPE (name))
- && range_includes_zero_p (vr) == 0)
- set_ptr_nonnull (name);
- else if (!POINTER_TYPE_P (TREE_TYPE (name)))
- set_range_info (name, *vr);
- }
-}
-
-class vrp_folder : public substitute_and_fold_engine
-{
- public:
- vrp_folder (vr_values *v)
- : substitute_and_fold_engine (/* Fold all stmts. */ true),
- m_vr_values (v), simplifier (v)
- { }
- void simplify_casted_conds (function *fun);
-
-private:
- tree value_of_expr (tree name, gimple *stmt) override
- {
- return m_vr_values->value_of_expr (name, stmt);
- }
- bool fold_stmt (gimple_stmt_iterator *) final override;
- bool fold_predicate_in (gimple_stmt_iterator *);
-
- vr_values *m_vr_values;
- simplify_using_ranges simplifier;
-};
-
-/* If the statement pointed by SI has a predicate whose value can be
- computed using the value range information computed by VRP, compute
- its value and return true. Otherwise, return false. */
-
-bool
-vrp_folder::fold_predicate_in (gimple_stmt_iterator *si)
-{
- bool assignment_p = false;
- tree val;
- gimple *stmt = gsi_stmt (*si);
-
- if (is_gimple_assign (stmt)
- && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
- {
- assignment_p = true;
- val = simplifier.vrp_evaluate_conditional (gimple_assign_rhs_code (stmt),
- gimple_assign_rhs1 (stmt),
- gimple_assign_rhs2 (stmt),
- stmt);
- }
- else if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
- val = simplifier.vrp_evaluate_conditional (gimple_cond_code (cond_stmt),
- gimple_cond_lhs (cond_stmt),
- gimple_cond_rhs (cond_stmt),
- stmt);
- else
- return false;
-
- if (val)
- {
- if (assignment_p)
- val = fold_convert (TREE_TYPE (gimple_assign_lhs (stmt)), val);
-
- if (dump_file)
- {
- fprintf (dump_file, "Folding predicate ");
- print_gimple_expr (dump_file, stmt, 0);
- fprintf (dump_file, " to ");
- print_generic_expr (dump_file, val);
- fprintf (dump_file, "\n");
- }
-
- if (is_gimple_assign (stmt))
- gimple_assign_set_rhs_from_tree (si, val);
- else
- {
- gcc_assert (gimple_code (stmt) == GIMPLE_COND);
- gcond *cond_stmt = as_a <gcond *> (stmt);
- if (integer_zerop (val))
- gimple_cond_make_false (cond_stmt);
- else if (integer_onep (val))
- gimple_cond_make_true (cond_stmt);
- else
- gcc_unreachable ();
- }
-
- return true;
- }
-
- return false;
-}
-
-/* Callback for substitute_and_fold folding the stmt at *SI. */
-
-bool
-vrp_folder::fold_stmt (gimple_stmt_iterator *si)
-{
- if (fold_predicate_in (si))
- return true;
-
- return simplifier.simplify (si);
-}
-
-/* A comparison of an SSA_NAME against a constant where the SSA_NAME
- was set by a type conversion can often be rewritten to use the RHS
- of the type conversion. Do this optimization for all conditionals
- in FUN. */
-
-void
-vrp_folder::simplify_casted_conds (function *fun)
-{
- basic_block bb;
- FOR_EACH_BB_FN (bb, fun)
- {
- gimple *last = last_stmt (bb);
- if (last && gimple_code (last) == GIMPLE_COND)
- {
- if (simplifier.simplify_casted_cond (as_a <gcond *> (last)))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Folded into: ");
- print_gimple_stmt (dump_file, last, 0, TDF_SLIM);
- fprintf (dump_file, "\n");
- }
- }
- }
- }
-}
-
-/* Main entry point to VRP (Value Range Propagation). This pass is
- loosely based on J. R. C. Patterson, ``Accurate Static Branch
- Prediction by Value Range Propagation,'' in SIGPLAN Conference on
- Programming Language Design and Implementation, pp. 67-78, 1995.
- Also available at http://citeseer.ist.psu.edu/patterson95accurate.html
-
- This is essentially an SSA-CCP pass modified to deal with ranges
- instead of constants.
-
- While propagating ranges, we may find that two or more SSA name
- have equivalent, though distinct ranges. For instance,
-
- 1 x_9 = p_3->a;
- 2 p_4 = ASSERT_EXPR <p_3, p_3 != 0>
- 3 if (p_4 == q_2)
- 4 p_5 = ASSERT_EXPR <p_4, p_4 == q_2>;
- 5 endif
- 6 if (q_2)
-
- In the code above, pointer p_5 has range [q_2, q_2], but from the
- code we can also determine that p_5 cannot be NULL and, if q_2 had
- a non-varying range, p_5's range should also be compatible with it.
-
- These equivalences are created by two expressions: ASSERT_EXPR and
- copy operations. Since p_5 is an assertion on p_4, and p_4 was the
- result of another assertion, then we can use the fact that p_5 and
- p_4 are equivalent when evaluating p_5's range.
-
- Together with value ranges, we also propagate these equivalences
- between names so that we can take advantage of information from
- multiple ranges when doing final replacement. Note that this
- equivalency relation is transitive but not symmetric.
-
- In the example above, p_5 is equivalent to p_4, q_2 and p_3, but we
- cannot assert that q_2 is equivalent to p_5 because q_2 may be used
- in contexts where that assertion does not hold (e.g., in line 6).
-
- TODO, the main difference between this pass and Patterson's is that
- we do not propagate edge probabilities. We only compute whether
- edges can be taken or not. That is, instead of having a spectrum
- of jump probabilities between 0 and 1, we only deal with 0, 1 and
- DON'T KNOW. In the future, it may be worthwhile to propagate
- probabilities to aid branch prediction. */
-
-static unsigned int
-execute_vrp (struct function *fun, bool warn_array_bounds_p)
-{
- loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
- rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
- scev_initialize ();
-
- /* ??? This ends up using stale EDGE_DFS_BACK for liveness computation.
- Inserting assertions may split edges which will invalidate
- EDGE_DFS_BACK. */
- vrp_asserts assert_engine (fun);
- assert_engine.insert_range_assertions ();
-
- /* For visiting PHI nodes we need EDGE_DFS_BACK computed. */
- mark_dfs_back_edges ();
-
- vr_values vrp_vr_values;
-
- class vrp_prop vrp_prop (&vrp_vr_values);
- vrp_prop.initialize (fun);
- vrp_prop.ssa_propagate ();
-
- /* Instantiate the folder here, so that edge cleanups happen at the
- end of this function. */
- vrp_folder folder (&vrp_vr_values);
- vrp_prop.finalize ();
-
- /* If we're checking array refs, we want to merge information on
- the executability of each edge between vrp_folder and the
- check_array_bounds_dom_walker: each can clear the
- EDGE_EXECUTABLE flag on edges, in different ways.
-
- Hence, if we're going to call check_all_array_refs, set
- the flag on every edge now, rather than in
- check_array_bounds_dom_walker's ctor; vrp_folder may clear
- it from some edges. */
- if (warn_array_bounds && warn_array_bounds_p)
- set_all_edges_as_executable (fun);
-
- folder.substitute_and_fold ();
-
- if (warn_array_bounds && warn_array_bounds_p)
- {
- array_bounds_checker array_checker (fun, &vrp_vr_values);
- array_checker.check ();
- }
-
- folder.simplify_casted_conds (fun);
-
- free_numbers_of_iterations_estimates (fun);
-
- assert_engine.remove_range_assertions ();
-
- scev_finalize ();
- loop_optimizer_finalize ();
- return 0;
-}
-
// This is a ranger based folder which continues to use the dominator
// walk to access the substitute and fold machinery. Ranges are calculated
// on demand.
@@ -4442,6 +985,7 @@ public:
{
m_ranger = r;
m_pta = new pointer_equiv_analyzer (m_ranger);
+ m_last_bb_stmt = NULL;
}
~rvrp_folder ()
@@ -4485,6 +1029,7 @@ public:
for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
gsi_next (&gsi))
m_ranger->register_inferred_ranges (gsi.phi ());
+ m_last_bb_stmt = last_stmt (bb);
}
void post_fold_bb (basic_block bb) override
@@ -4497,6 +1042,10 @@ public:
void pre_fold_stmt (gimple *stmt) override
{
m_pta->visit_stmt (stmt);
+ // If this is the last stmt and there are inferred ranges, reparse the
+ // block for transitive inferred ranges that occur earlier in the block.
+ if (stmt == m_last_bb_stmt)
+ m_ranger->register_transitive_inferred_ranges (gimple_bb (stmt));
}
bool fold_stmt (gimple_stmt_iterator *gsi) override
@@ -4514,6 +1063,7 @@ private:
gimple_ranger *m_ranger;
simplify_using_ranges m_simplifier;
pointer_equiv_analyzer *m_pta;
+ gimple *m_last_bb_stmt;
};
/* Main entry point for a VRP pass using just ranger. This can be called
@@ -4614,10 +1164,7 @@ public:
if (my_pass == 0)
return execute_ranger_vrp (fun, /*warn_array_bounds_p=*/false, false);
- if ((my_pass == 1 && param_vrp1_mode == VRP_MODE_RANGER)
- || (my_pass == 2 && param_vrp2_mode == VRP_MODE_RANGER))
- return execute_ranger_vrp (fun, warn_array_bounds_p, my_pass == 2);
- return execute_vrp (fun, warn_array_bounds_p);
+ return execute_ranger_vrp (fun, warn_array_bounds_p, my_pass == 2);
}
private:
diff --git a/gcc/tree-vrp.h b/gcc/tree-vrp.h
index b8644e9..1279096 100644
--- a/gcc/tree-vrp.h
+++ b/gcc/tree-vrp.h
@@ -22,26 +22,6 @@ along with GCC; see the file COPYING3. If not see
#include "value-range.h"
-struct assert_info
-{
- /* Predicate code for the ASSERT_EXPR. Must be COMPARISON_CLASS_P. */
- enum tree_code comp_code;
-
- /* Name to register the assert for. */
- tree name;
-
- /* Value being compared against. */
- tree val;
-
- /* Expression to compare. */
- tree expr;
-};
-
-extern void register_edge_assert_for (tree, edge, enum tree_code,
- tree, tree, vec<assert_info> &);
-extern bool stmt_interesting_for_vrp (gimple *);
-extern bool infer_value_range (gimple *, tree, tree_code *, tree *);
-
extern bool range_int_cst_p (const value_range *);
extern int compare_values (tree, tree);
@@ -59,12 +39,7 @@ extern enum value_range_kind intersect_range_with_nonzero_bits
extern bool find_case_label_range (gswitch *, tree, tree, size_t *, size_t *);
extern tree find_case_label_range (gswitch *, const irange *vr);
extern bool find_case_label_index (gswitch *, size_t, tree, size_t *);
-extern bool overflow_comparison_p (tree_code, tree, tree, bool, tree *);
-extern tree get_single_symbol (tree, bool *, tree *);
+extern bool overflow_comparison_p (tree_code, tree, tree, tree *);
extern void maybe_set_nonzero_bits (edge, tree);
-extern wide_int masked_increment (const wide_int &val_in, const wide_int &mask,
- const wide_int &sgnbit, unsigned int prec);
-extern unsigned int execute_ranger_vrp (struct function *fun,
- bool warn_array_bounds_p = false);
#endif /* GCC_TREE_VRP_H */
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 1720987..0a51f9d 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -74,31 +74,7 @@ along with GCC; see the file COPYING3. If not see
#include "asan.h"
#include "ubsan.h"
-/* Tree code classes. */
-#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
-#define END_OF_BASE_TREE_CODES tcc_exceptional,
-
-const enum tree_code_class tree_code_type[] = {
-#include "all-tree.def"
-};
-
-#undef DEFTREECODE
-#undef END_OF_BASE_TREE_CODES
-
-/* Table indexed by tree code giving number of expression
- operands beyond the fixed part of the node structure.
- Not used for types or decls. */
-
-#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
-#define END_OF_BASE_TREE_CODES 0,
-
-const unsigned char tree_code_length[] = {
-#include "all-tree.def"
-};
-
-#undef DEFTREECODE
-#undef END_OF_BASE_TREE_CODES
/* Names of tree components.
Used for printing out the tree and error messages. */
@@ -12038,6 +12014,18 @@ strip_invariant_refs (const_tree op)
return op;
}
+/* Strip handled components with zero offset from OP. */
+
+tree
+strip_zero_offset_components (tree op)
+{
+ while (TREE_CODE (op) == COMPONENT_REF
+ && integer_zerop (DECL_FIELD_OFFSET (TREE_OPERAND (op, 1)))
+ && integer_zerop (DECL_FIELD_BIT_OFFSET (TREE_OPERAND (op, 1))))
+ op = TREE_OPERAND (op, 0);
+ return op;
+}
+
static GTY(()) tree gcc_eh_personality_decl;
/* Return the GCC personality function decl. */
@@ -12727,8 +12715,8 @@ array_ref_up_bound (tree exp)
return NULL_TREE;
}
-/* Returns true if REF is an array reference, component reference,
- or memory reference to an array whose actual size might be larger
+/* Returns true if REF is an array reference, a component reference,
+ or a memory reference to an array whose actual size might be larger
than its upper bound implies, there are multiple cases:
A. a ref to a flexible array member at the end of a structure;
B. a ref to an array with a different type against the original decl;
@@ -12744,14 +12732,20 @@ array_ref_up_bound (tree exp)
for (int i = 0; i < 4; i++, p++)
t[i][0] = ...;
- FIXME, the name of this routine need to be changed to be more accurate. */
+ If non-null, set IS_TRAILING_ARRAY to true if the ref is the above case A.
+*/
+
bool
-array_at_struct_end_p (tree ref)
+array_ref_flexible_size_p (tree ref, bool *is_trailing_array /* = NULL */)
{
- /* the TYPE for this array referece. */
+ /* The TYPE for this array referece. */
tree atype = NULL_TREE;
- /* the FIELD_DECL for the array field in the containing structure. */
+ /* The FIELD_DECL for the array field in the containing structure. */
tree afield_decl = NULL_TREE;
+ /* Whether this array is the trailing array of a structure. */
+ bool is_trailing_array_tmp = false;
+ if (!is_trailing_array)
+ is_trailing_array = &is_trailing_array_tmp;
if (TREE_CODE (ref) == ARRAY_REF
|| TREE_CODE (ref) == ARRAY_RANGE_REF)
@@ -12839,7 +12833,10 @@ array_at_struct_end_p (tree ref)
if (! TYPE_SIZE (atype)
|| ! TYPE_DOMAIN (atype)
|| ! TYPE_MAX_VALUE (TYPE_DOMAIN (atype)))
- return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true;
+ {
+ *is_trailing_array = afield_decl && TREE_CODE (afield_decl) == FIELD_DECL;
+ return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true;
+ }
/* If the reference is based on a declared entity, the size of the array
is constrained by its given domain. (Do not trust commons PR/69368). */
@@ -12861,9 +12858,17 @@ array_at_struct_end_p (tree ref)
if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (atype))) != INTEGER_CST
|| TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (atype))) != INTEGER_CST
|| TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (atype))) != INTEGER_CST)
- return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true;
+ {
+ *is_trailing_array
+ = afield_decl && TREE_CODE (afield_decl) == FIELD_DECL;
+ return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true;
+ }
if (! get_addr_base_and_unit_offset (ref_to_array, &offset))
- return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true;
+ {
+ *is_trailing_array
+ = afield_decl && TREE_CODE (afield_decl) == FIELD_DECL;
+ return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true;
+ }
/* If at least one extra element fits it is a flexarray. */
if (known_le ((wi::to_offset (TYPE_MAX_VALUE (TYPE_DOMAIN (atype)))
@@ -12871,14 +12876,20 @@ array_at_struct_end_p (tree ref)
+ 2)
* wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (atype))),
wi::to_offset (DECL_SIZE_UNIT (ref)) - offset))
- return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true;
+ {
+ *is_trailing_array
+ = afield_decl && TREE_CODE (afield_decl) == FIELD_DECL;
+ return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true;
+ }
return false;
}
+ *is_trailing_array = afield_decl && TREE_CODE (afield_decl) == FIELD_DECL;
return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true;
}
+
/* Return a tree representing the offset, in bytes, of the field referenced
by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */
@@ -12936,11 +12947,63 @@ get_initializer_for (tree init, tree decl)
return NULL_TREE;
}
+/* Determines the special array member type for the array reference REF. */
+special_array_member
+component_ref_sam_type (tree ref)
+{
+ special_array_member sam_type = special_array_member::none;
+
+ tree member = TREE_OPERAND (ref, 1);
+ tree memsize = DECL_SIZE_UNIT (member);
+ if (memsize)
+ {
+ tree memtype = TREE_TYPE (member);
+ if (TREE_CODE (memtype) != ARRAY_TYPE)
+ return sam_type;
+
+ bool trailing = false;
+ (void)array_ref_flexible_size_p (ref, &trailing);
+ bool zero_length = integer_zerop (memsize);
+ if (!trailing && !zero_length)
+ /* MEMBER is an interior array with
+ more than one element. */
+ return special_array_member::int_n;
+
+ if (zero_length)
+ {
+ if (trailing)
+ return special_array_member::trail_0;
+ else
+ return special_array_member::int_0;
+ }
+
+ if (!zero_length)
+ if (tree dom = TYPE_DOMAIN (memtype))
+ if (tree min = TYPE_MIN_VALUE (dom))
+ if (tree max = TYPE_MAX_VALUE (dom))
+ if (TREE_CODE (min) == INTEGER_CST
+ && TREE_CODE (max) == INTEGER_CST)
+ {
+ offset_int minidx = wi::to_offset (min);
+ offset_int maxidx = wi::to_offset (max);
+ offset_int neltsm1 = maxidx - minidx;
+ if (neltsm1 > 0)
+ /* MEMBER is a trailing array with more than
+ one elements. */
+ return special_array_member::trail_n;
+
+ if (neltsm1 == 0)
+ return special_array_member::trail_1;
+ }
+ }
+
+ return sam_type;
+}
+
/* Determines the size of the member referenced by the COMPONENT_REF
REF, using its initializer expression if necessary in order to
determine the size of an initialized flexible array member.
- If non-null, set *ARK when REF refers to an interior zero-length
- array or a trailing one-element array.
+ If non-null, set *SAM to the type of special array member.
Returns the size as sizetype (which might be zero for an object
with an uninitialized flexible array member) or null if the size
cannot be determined. */
@@ -12953,7 +13016,7 @@ component_ref_size (tree ref, special_array_member *sam /* = NULL */)
special_array_member sambuf;
if (!sam)
sam = &sambuf;
- *sam = special_array_member::none;
+ *sam = component_ref_sam_type (ref);
/* The object/argument referenced by the COMPONENT_REF and its type. */
tree arg = TREE_OPERAND (ref, 0);
@@ -12974,43 +13037,46 @@ component_ref_size (tree ref, special_array_member *sam /* = NULL */)
return (tree_int_cst_equal (memsize, TYPE_SIZE_UNIT (memtype))
? memsize : NULL_TREE);
- bool trailing = array_at_struct_end_p (ref);
- bool zero_length = integer_zerop (memsize);
- if (!trailing && !zero_length)
- /* MEMBER is either an interior array or is an array with
- more than one element. */
+ /* 2-or-more elements arrays are treated as normal arrays by default. */
+ if (*sam == special_array_member::int_n
+ || *sam == special_array_member::trail_n)
return memsize;
- if (zero_length)
+ /* flag_strict_flex_arrays will control how to treat
+ the trailing arrays as flexiable array members. */
+
+ tree afield_decl = TREE_OPERAND (ref, 1);
+ unsigned int strict_flex_array_level
+ = strict_flex_array_level_of (afield_decl);
+
+ switch (strict_flex_array_level)
{
- if (trailing)
- *sam = special_array_member::trail_0;
- else
- {
- *sam = special_array_member::int_0;
- memsize = NULL_TREE;
- }
+ case 3:
+ /* Treaing 0-length trailing arrays as normal array. */
+ if (*sam == special_array_member::trail_0)
+ return size_zero_node;
+ /* FALLTHROUGH. */
+ case 2:
+ /* Treating 1-element trailing arrays as normal array. */
+ if (*sam == special_array_member::trail_1)
+ return memsize;
+ /* FALLTHROUGH. */
+ case 1:
+ /* Treating 2-or-more elements trailing arrays as normal
+ array. */
+ if (*sam == special_array_member::trail_n)
+ return memsize;
+ /* FALLTHROUGH. */
+ case 0:
+ break;
+ default:
+ gcc_unreachable ();
}
- if (!zero_length)
- if (tree dom = TYPE_DOMAIN (memtype))
- if (tree min = TYPE_MIN_VALUE (dom))
- if (tree max = TYPE_MAX_VALUE (dom))
- if (TREE_CODE (min) == INTEGER_CST
- && TREE_CODE (max) == INTEGER_CST)
- {
- offset_int minidx = wi::to_offset (min);
- offset_int maxidx = wi::to_offset (max);
- offset_int neltsm1 = maxidx - minidx;
- if (neltsm1 > 0)
- /* MEMBER is an array with more than one element. */
- return memsize;
-
- if (neltsm1 == 0)
- *sam = special_array_member::trail_1;
- }
+ if (*sam == special_array_member::int_0)
+ memsize = NULL_TREE;
- /* For a reference to a zero- or one-element array member of a union
+ /* For a reference to a flexible array member of a union
use the size of the union instead of the size of the member. */
if (TREE_CODE (argtype) == UNION_TYPE)
memsize = TYPE_SIZE_UNIT (argtype);
diff --git a/gcc/tree.def b/gcc/tree.def
index 62650b6..69783bd 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -1025,7 +1025,10 @@ DEFTREECODE (POLYNOMIAL_CHREC, "polynomial_chrec", tcc_expression, 2)
Use the interface in tree-iterator.h to access this node. */
DEFTREECODE (STATEMENT_LIST, "statement_list", tcc_exceptional, 0)
-/* Predicate assertion. Artificial expression generated by the optimizers
+/* NOTE: This code is deprecated and should only be used internally by ipa* as
+ temporary construct.
+
+ Predicate assertion. Artificial expression generated by the optimizers
to keep track of predicate values. This expression may only appear on
the RHS of assignments.
diff --git a/gcc/tree.h b/gcc/tree.h
index d6a5fdf..31d0dca 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1406,10 +1406,6 @@ class auto_suppress_location_wrappers
#define OBJ_TYPE_REF_OBJECT(NODE) TREE_OPERAND (OBJ_TYPE_REF_CHECK (NODE), 1)
#define OBJ_TYPE_REF_TOKEN(NODE) TREE_OPERAND (OBJ_TYPE_REF_CHECK (NODE), 2)
-/* ASSERT_EXPR accessors. */
-#define ASSERT_EXPR_VAR(NODE) TREE_OPERAND (ASSERT_EXPR_CHECK (NODE), 0)
-#define ASSERT_EXPR_COND(NODE) TREE_OPERAND (ASSERT_EXPR_CHECK (NODE), 1)
-
/* CALL_EXPR accessors. */
#define CALL_EXPR_FN(NODE) TREE_OPERAND (CALL_EXPR_CHECK (NODE), 1)
#define CALL_EXPR_STATIC_CHAIN(NODE) TREE_OPERAND (CALL_EXPR_CHECK (NODE), 2)
@@ -4726,6 +4722,7 @@ extern tree signed_or_unsigned_type_for (int, tree);
extern tree signed_type_for (tree);
extern tree unsigned_type_for (tree);
extern bool is_truth_type_for (tree, tree);
+extern bool tree_zero_one_valued_p (tree);
extern tree truth_type_for (tree);
extern tree build_pointer_type_for_mode (tree, machine_mode, bool);
extern tree build_pointer_type (tree);
@@ -5373,6 +5370,7 @@ extern bool tree_nop_conversion_p (const_tree, const_tree);
extern tree tree_strip_nop_conversions (tree);
extern tree tree_strip_sign_nop_conversions (tree);
extern const_tree strip_invariant_refs (const_tree);
+extern tree strip_zero_offset_components (tree);
extern tree lhd_gcc_personality (void);
extern void assign_assembler_name_if_needed (tree);
extern bool warn_deprecated_use (tree, tree);
@@ -5554,25 +5552,29 @@ extern tree array_ref_up_bound (tree);
EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
extern tree array_ref_low_bound (tree);
-/* Returns true if REF is an array reference or a component reference
- to an array at the end of a structure. If this is the case, the array
- may be allocated larger than its upper bound implies. */
-extern bool array_at_struct_end_p (tree);
+/* Returns true if REF is an array reference, a component reference,
+ or a memory reference to an array whose actual size might be larger
+ than its upper bound implies. */
+extern bool array_ref_flexible_size_p (tree, bool * = NULL);
/* Return a tree representing the offset, in bytes, of the field referenced
by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */
extern tree component_ref_field_offset (tree);
-/* Describes a "special" array member due to which component_ref_size
- returns null. */
+/* Describes a "special" array member for a COMPONENT_REF. */
enum struct special_array_member
{
none, /* Not a special array member. */
int_0, /* Interior array member with size zero. */
trail_0, /* Trailing array member with size zero. */
- trail_1 /* Trailing array member with one element. */
+ trail_1, /* Trailing array member with one element. */
+ trail_n, /* Trailing array member with two or more elements. */
+ int_n /* Interior array member with one or more elements. */
};
+/* Determines the special array member type for a COMPONENT_REF. */
+extern special_array_member component_ref_sam_type (tree);
+
/* Return the size of the member referenced by the COMPONENT_REF, using
its initializer expression if necessary in order to determine the size
of an initialized flexible array member. The size might be zero for
diff --git a/gcc/tristate.h b/gcc/tristate.h
index 8476b9a..bccfa8b 100644
--- a/gcc/tristate.h
+++ b/gcc/tristate.h
@@ -38,6 +38,7 @@ class tristate {
const char *as_string () const;
bool is_known () const { return m_value != TS_UNKNOWN; }
+ bool is_unknown () const { return m_value == TS_UNKNOWN; }
bool is_true () const { return m_value == TS_TRUE; }
bool is_false () const { return m_value == TS_FALSE; }
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index e8988ed..f89225d 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -28,7 +28,6 @@ along with GCC; see the file COPYING3. If not see
#include "ssa.h"
#include "tree-pretty-print.h"
#include "fold-const.h"
-#include "value-range-equiv.h"
#include "value-query.h"
#include "alloc-pool.h"
#include "gimple-range.h"
@@ -143,34 +142,22 @@ range_query::dump (FILE *)
{
}
-// valuation_query support routines for value_range_equiv's.
+// valuation_query support routines for value_range's.
-class equiv_allocator : public object_allocator<value_range_equiv>
+class equiv_allocator : public object_allocator<value_range>
{
public:
equiv_allocator ()
- : object_allocator<value_range_equiv> ("equiv_allocator pool") { }
+ : object_allocator<value_range> ("equiv_allocator pool") { }
};
-value_range_equiv *
-range_query::allocate_value_range_equiv ()
-{
- return new (equiv_alloc->allocate ()) value_range_equiv;
-}
-
-void
-range_query::free_value_range_equiv (value_range_equiv *v)
-{
- equiv_alloc->remove (v);
-}
-
-const class value_range_equiv *
+const value_range *
range_query::get_value_range (const_tree expr, gimple *stmt)
{
int_range_max r;
if (range_of_expr (r, const_cast<tree> (expr), stmt))
- return new (equiv_alloc->allocate ()) value_range_equiv (r);
- return new (equiv_alloc->allocate ()) value_range_equiv (TREE_TYPE (expr));
+ return new (equiv_alloc->allocate ()) value_range (r);
+ return new (equiv_alloc->allocate ()) value_range (TREE_TYPE (expr));
}
range_query::range_query ()
diff --git a/gcc/value-query.h b/gcc/value-query.h
index fc638eb..b860d66 100644
--- a/gcc/value-query.h
+++ b/gcc/value-query.h
@@ -93,6 +93,9 @@ public:
virtual bool range_on_edge (vrange &r, edge, tree expr);
virtual bool range_of_stmt (vrange &r, gimple *, tree name = NULL);
+ // When the IL in a stmt is changed, call this for better results.
+ virtual void update_stmt (gimple *) { }
+
// Query if there is any relation between SSA1 and SSA2.
relation_kind query_relation (gimple *s, tree ssa1, tree ssa2,
bool get_range = true);
@@ -103,13 +106,10 @@ public:
// DEPRECATED: This method is used from vr-values. The plan is to
// rewrite all uses of it to the above API.
- virtual const class value_range_equiv *get_value_range (const_tree,
- gimple * = NULL);
+ virtual const value_range *get_value_range (const_tree, gimple * = NULL);
virtual void dump (FILE *);
protected:
- class value_range_equiv *allocate_value_range_equiv ();
- void free_value_range_equiv (class value_range_equiv *);
bool get_tree_range (vrange &v, tree expr, gimple *stmt);
bool get_arith_expr_range (vrange &r, tree expr, gimple *stmt);
relation_oracle *m_oracle;
diff --git a/gcc/value-range-equiv.cc b/gcc/value-range-equiv.cc
deleted file mode 100644
index bd58e5a..0000000
--- a/gcc/value-range-equiv.cc
+++ /dev/null
@@ -1,330 +0,0 @@
-/* Support routines for value ranges with equivalences.
- Copyright (C) 2020-2022 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "backend.h"
-#include "tree.h"
-#include "gimple.h"
-#include "ssa.h"
-#include "tree-pretty-print.h"
-#include "value-range-equiv.h"
-
-value_range_equiv::value_range_equiv (tree min, tree max, bitmap equiv,
- value_range_kind kind)
-{
- m_equiv = NULL;
- set (min, max, equiv, kind);
-}
-
-value_range_equiv::value_range_equiv (const value_range &other)
-{
- m_equiv = NULL;
- set (other.min(), other.max (), NULL, other.kind ());
-}
-
-void
-value_range_equiv::set (tree min, tree max, bitmap equiv,
- value_range_kind kind)
-{
- value_range::set (min, max, kind);
- set_equiv (equiv);
- if (flag_checking)
- check ();
-}
-
-void
-value_range_equiv::set (tree min, tree max, value_range_kind kind)
-{
- set (min, max, m_equiv, kind);
-}
-
-void
-value_range_equiv::set (tree val)
-{
- gcc_assert (TREE_CODE (val) == SSA_NAME || is_gimple_min_invariant (val));
- if (TREE_OVERFLOW_P (val))
- val = drop_tree_overflow (val);
- set (val, val);
-}
-
-void
-value_range_equiv::set_undefined ()
-{
- set (NULL, NULL, NULL, VR_UNDEFINED);
-}
-
-void
-value_range_equiv::set_varying (tree type)
-{
- value_range::set_varying (type);
- equiv_clear ();
-}
-
-/* Like set, but keep the equivalences in place. */
-
-void
-value_range_equiv::update (tree min, tree max, value_range_kind kind)
-{
- set (min, max,
- (kind != VR_UNDEFINED && kind != VR_VARYING) ? m_equiv : NULL, kind);
-}
-
-/* Copy value_range in FROM into THIS while avoiding bitmap sharing.
-
- Note: The code that avoids the bitmap sharing looks at the existing
- this->m_equiv, so this function cannot be used to initalize an
- object. Use the constructors for initialization. */
-
-void
-value_range_equiv::deep_copy (const value_range_equiv *from)
-{
- set (from->min (), from->max (), from->m_equiv, from->kind ());
-}
-
-void
-value_range_equiv::move (value_range_equiv *from)
-{
- set (from->min (), from->max (), NULL, from->kind ());
- m_equiv = from->m_equiv;
- from->m_equiv = NULL;
-}
-
-void
-value_range_equiv::set_equiv (bitmap equiv)
-{
- if (undefined_p () || varying_p ())
- equiv = NULL;
- /* Since updating the equivalence set involves deep copying the
- bitmaps, only do it if absolutely necessary.
-
- All equivalence bitmaps are allocated from the same obstack. So
- we can use the obstack associated with EQUIV to allocate vr->equiv. */
- if (m_equiv == NULL
- && equiv != NULL)
- m_equiv = BITMAP_ALLOC (equiv->obstack);
-
- if (equiv != m_equiv)
- {
- if (equiv && !bitmap_empty_p (equiv))
- bitmap_copy (m_equiv, equiv);
- else
- bitmap_clear (m_equiv);
- }
-}
-
-void
-value_range_equiv::check ()
-{
- value_range::verify_range ();
- switch (kind ())
- {
- case VR_UNDEFINED:
- case VR_VARYING:
- gcc_assert (!m_equiv || bitmap_empty_p (m_equiv));
- default:;
- }
-}
-
-/* Return true if the bitmaps B1 and B2 are equal. */
-
-static bool
-vr_bitmap_equal_p (const_bitmap b1, const_bitmap b2)
-{
- return (b1 == b2
- || ((!b1 || bitmap_empty_p (b1))
- && (!b2 || bitmap_empty_p (b2)))
- || (b1 && b2
- && bitmap_equal_p (b1, b2)));
-}
-
-/* Returns TRUE if THIS == OTHER. Ignores the equivalence bitmap if
- IGNORE_EQUIVS is TRUE. */
-
-bool
-value_range_equiv::equal_p (const value_range_equiv &other,
- bool ignore_equivs) const
-{
- return (value_range::operator== (other)
- && (ignore_equivs || vr_bitmap_equal_p (m_equiv, other.m_equiv)));
-}
-
-void
-value_range_equiv::equiv_clear ()
-{
- if (m_equiv)
- bitmap_clear (m_equiv);
-}
-
-/* Add VAR and VAR's equivalence set (VAR_VR) to the equivalence
- bitmap. If no equivalence table has been created, OBSTACK is the
- obstack to use (NULL for the default obstack).
-
- This is the central point where equivalence processing can be
- turned on/off. */
-
-void
-value_range_equiv::equiv_add (const_tree var,
- const value_range_equiv *var_vr,
- bitmap_obstack *obstack)
-{
- if (!m_equiv)
- m_equiv = BITMAP_ALLOC (obstack);
- unsigned ver = SSA_NAME_VERSION (var);
- bitmap_set_bit (m_equiv, ver);
- if (var_vr && var_vr->m_equiv)
- bitmap_ior_into (m_equiv, var_vr->m_equiv);
-}
-
-void
-value_range_equiv::legacy_verbose_intersect (const value_range_equiv *other)
-{
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Intersecting\n ");
- dump_value_range (dump_file, this);
- fprintf (dump_file, "\nand\n ");
- dump_value_range (dump_file, other);
- fprintf (dump_file, "\n");
- }
-
- /* If THIS is varying we want to pick up equivalences from OTHER.
- Just special-case this here rather than trying to fixup after the
- fact. */
- if (this->varying_p ())
- this->deep_copy (other);
- else
- {
- legacy_intersect (this, other);
- if (varying_p () || undefined_p ())
- equiv_clear ();
-
- /* If the result is VR_UNDEFINED there is no need to mess with
- equivalencies. */
- if (!undefined_p ())
- {
- /* The resulting set of equivalences for range intersection
- is the union of the two sets. */
- if (m_equiv && other->m_equiv && m_equiv != other->m_equiv)
- bitmap_ior_into (m_equiv, other->m_equiv);
- else if (other->m_equiv && !m_equiv)
- {
- /* All equivalence bitmaps are allocated from the same
- obstack. So we can use the obstack associated with
- VR to allocate this->m_equiv. */
- m_equiv = BITMAP_ALLOC (other->m_equiv->obstack);
- bitmap_copy (m_equiv, other->m_equiv);
- }
- }
- }
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "to\n ");
- dump_value_range (dump_file, this);
- fprintf (dump_file, "\n");
- }
-}
-
-void
-value_range_equiv::legacy_verbose_union_ (const value_range_equiv *other)
-{
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Meeting\n ");
- dump_value_range (dump_file, this);
- fprintf (dump_file, "\nand\n ");
- dump_value_range (dump_file, other);
- fprintf (dump_file, "\n");
- }
-
- /* If THIS is undefined we want to pick up equivalences from OTHER.
- Just special-case this here rather than trying to fixup after the fact. */
- if (this->undefined_p ())
- this->deep_copy (other);
- else
- {
- legacy_union (this, other);
- if (varying_p () || undefined_p ())
- equiv_clear ();
-
- /* The resulting set of equivalences is always the intersection of
- the two sets. */
- if (this->m_equiv && other->m_equiv && this->m_equiv != other->m_equiv)
- bitmap_and_into (this->m_equiv, other->m_equiv);
- else if (this->m_equiv && !other->m_equiv)
- bitmap_clear (this->m_equiv);
- }
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "to\n ");
- dump_value_range (dump_file, this);
- fprintf (dump_file, "\n");
- }
-}
-
-void
-value_range_equiv::dump (FILE *file) const
-{
- value_range::dump (file);
- if ((kind () == VR_RANGE || kind () == VR_ANTI_RANGE)
- && m_equiv)
- {
- bitmap_iterator bi;
- unsigned i, c = 0;
-
- fprintf (file, " EQUIVALENCES: { ");
- EXECUTE_IF_SET_IN_BITMAP (m_equiv, 0, i, bi)
- {
- print_generic_expr (file, ssa_name (i));
- fprintf (file, " ");
- c++;
- }
- fprintf (file, "} (%u elements)", c);
- }
-}
-
-void
-value_range_equiv::dump () const
-{
- dump (stderr);
-}
-
-void
-dump_value_range (FILE *file, const value_range_equiv *vr)
-{
- if (!vr)
- fprintf (file, "[]");
- else
- vr->dump (file);
-}
-
-DEBUG_FUNCTION void
-debug (const value_range_equiv *vr)
-{
- dump_value_range (stderr, vr);
-}
-
-DEBUG_FUNCTION void
-debug (const value_range_equiv &vr)
-{
- dump_value_range (stderr, &vr);
-}
diff --git a/gcc/value-range-equiv.h b/gcc/value-range-equiv.h
deleted file mode 100644
index 1a8014d..0000000
--- a/gcc/value-range-equiv.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Support routines for value ranges with equivalences.
- Copyright (C) 2020-2022 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-#ifndef GCC_VALUE_RANGE_EQUIV_H
-#define GCC_VALUE_RANGE_EQUIV_H
-
-#include "value-range.h"
-
-/* Note value_range_equiv cannot currently be used with GC memory,
- only value_range is fully set up for this. */
-class GTY((user)) value_range_equiv : public value_range
-{
- public:
- value_range_equiv () : value_range () { m_equiv = NULL; }
- value_range_equiv (const value_range &);
- /* Deep-copies equiv bitmap argument. */
- value_range_equiv (tree, tree, bitmap = NULL, value_range_kind = VR_RANGE);
-
- /* Shallow-copies equiv bitmap. */
- value_range_equiv (const value_range_equiv &) /* = delete */;
- /* Shallow-copies equiv bitmap. */
- value_range_equiv& operator=(const value_range_equiv &) /* = delete */;
-
- /* Virtual destructor. */
- virtual ~value_range_equiv () = default;
-
- /* Move equiv bitmap from source range. */
- void move (value_range_equiv *);
-
- /* Leaves equiv bitmap alone. */
- virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
- void update (tree, tree, value_range_kind = VR_RANGE);
- /* Deep-copies equiv bitmap argument. */
- void set (tree, tree, bitmap, value_range_kind = VR_RANGE);
- void set (tree);
-
- bool operator== (const value_range_equiv &) const /* = delete */;
- bool operator!= (const value_range_equiv &) const /* = delete */;
- void legacy_verbose_intersect (const value_range_equiv *);
- void legacy_verbose_union_ (const value_range_equiv *);
- bool equal_p (const value_range_equiv &, bool ignore_equivs) const;
-
- /* Types of value ranges. */
- void set_undefined () override;
- void set_varying (tree) override;
-
- /* Equivalence bitmap methods. */
- bitmap equiv () const { return m_equiv; }
- void equiv_clear ();
- void equiv_add (const_tree, const value_range_equiv *,
- bitmap_obstack * = NULL);
-
- /* Misc methods. */
- void deep_copy (const value_range_equiv *);
- void dump (FILE *) const;
- void dump () const;
- static bool supports_p (tree type)
- {
- return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type);
- }
-
- private:
- /* Deep-copies bitmap argument. */
- void set_equiv (bitmap);
- void check ();
-
- /* Set of SSA names whose value ranges are equivalent to this one.
- This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE. */
- bitmap m_equiv;
-};
-
-extern void dump_value_range (FILE *, const value_range_equiv *);
-
-#endif // GCC_VALUE_RANGE_EQUIV_H
diff --git a/gcc/value-range-storage.cc b/gcc/value-range-storage.cc
index 462447b..b57701f 100644
--- a/gcc/value-range-storage.cc
+++ b/gcc/value-range-storage.cc
@@ -276,13 +276,20 @@ frange_storage_slot::get_frange (frange &r, tree type) const
return;
}
- // Use the constructor because it will canonicalize the range.
+ // We use the constructor to create the new range instead of writing
+ // out the bits into the frange directly, because the global range
+ // being read may be being inlined into a function with different
+ // restrictions as when it was originally written. We want to make
+ // sure the resulting range is canonicalized correctly for the new
+ // consumer.
r = frange (type, m_min, m_max, m_kind);
// The constructor will set the NAN bits for HONOR_NANS, but we must
// make sure to set the NAN sign if known.
if (HONOR_NANS (type) && (m_pos_nan ^ m_neg_nan) == 1)
r.update_nan (m_neg_nan);
+ else if (!m_pos_nan && !m_neg_nan)
+ r.clear_nan ();
}
bool
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 3743ec7..34fac63 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -266,15 +266,16 @@ frange::flush_denormals_to_zero ()
if (undefined_p () || known_isnan ())
return;
+ machine_mode mode = TYPE_MODE (type ());
// Flush [x, -DENORMAL] to [x, -0.0].
- if (real_isdenormal (&m_max) && real_isneg (&m_max))
+ if (real_isdenormal (&m_max, mode) && real_isneg (&m_max))
{
m_max = dconst0;
if (HONOR_SIGNED_ZEROS (m_type))
m_max.sign = 1;
}
// Flush [+DENORMAL, x] to [+0.0, x].
- if (real_isdenormal (&m_min) && !real_isneg (&m_min))
+ if (real_isdenormal (&m_min, mode) && !real_isneg (&m_min))
m_min = dconst0;
}
@@ -661,7 +662,7 @@ frange::contains_p (tree cst) const
{
// Make sure the signs are equal for signed zeros.
if (HONOR_SIGNED_ZEROS (m_type) && real_iszero (rv))
- return m_min.sign == m_max.sign && m_min.sign == rv->sign;
+ return rv->sign == m_min.sign || rv->sign == m_max.sign;
return true;
}
return false;
@@ -796,14 +797,17 @@ frange::zero_p () const
&& real_iszero (&m_max));
}
+// Set the range to non-negative numbers, that is [+0.0, +INF].
+//
+// The NAN in the resulting range (if HONOR_NANS) has a varying sign
+// as there are no guarantees in IEEE 754 wrt to the sign of a NAN,
+// except for copy, abs, and copysign. It is the responsibility of
+// the caller to set the NAN's sign if desired.
+
void
frange::set_nonnegative (tree type)
{
set (type, dconst0, frange_val_max (type));
-
- // Set +NAN as the only possibility.
- if (HONOR_NANS (type))
- update_nan (/*sign=*/false);
}
// Here we copy between any two irange's. The ranges can be legacy or
@@ -3859,6 +3863,14 @@ range_tests_signed_zeros ()
ASSERT_TRUE (r0.contains_p (neg_zero));
ASSERT_FALSE (r0.contains_p (zero));
+ r0 = frange (neg_zero, zero);
+ ASSERT_TRUE (r0.contains_p (neg_zero));
+ ASSERT_TRUE (r0.contains_p (zero));
+
+ r0 = frange_float ("-3", "5");
+ ASSERT_TRUE (r0.contains_p (neg_zero));
+ ASSERT_TRUE (r0.contains_p (zero));
+
// The intersection of zeros that differ in sign is a NAN (or
// undefined if not honoring NANs).
r0 = frange (neg_zero, neg_zero);
@@ -3914,9 +3926,13 @@ range_tests_signed_zeros ()
ASSERT_TRUE (r0.undefined_p ());
r0.set_nonnegative (float_type_node);
- ASSERT_TRUE (r0.signbit_p (signbit) && !signbit);
if (HONOR_NANS (float_type_node))
ASSERT_TRUE (r0.maybe_isnan ());
+
+ // Numbers containing zero should have an unknown SIGNBIT.
+ r0 = frange_float ("0", "10");
+ r0.clear_nan ();
+ ASSERT_TRUE (r0.signbit_p (signbit) && !signbit);
}
static void
@@ -3933,10 +3949,6 @@ range_tests_signbit ()
r0 = frange_float ("1", "10");
r0.clear_nan ();
ASSERT_TRUE (r0.signbit_p (signbit) && !signbit);
- // Numbers containing zero should have an unknown SIGNBIT.
- r0 = frange_float ("0", "10");
- r0.clear_nan ();
- ASSERT_TRUE (r0.signbit_p (signbit) && !signbit);
// Numbers spanning both positive and negative should have an
// unknown SIGNBIT.
r0 = frange_float ("-10", "10");
@@ -4042,6 +4054,15 @@ range_tests_floats ()
ASSERT_TRUE (real_isinf (&r0.lower_bound (), true));
ASSERT_TRUE (real_isinf (&r0.upper_bound (), true));
}
+
+ // Test that reading back a global range yields the same result as
+ // what we wrote into it.
+ tree ssa = make_temp_ssa_name (float_type_node, NULL, "blah");
+ r0.set_varying (float_type_node);
+ r0.clear_nan ();
+ set_range_info (ssa, r0);
+ get_global_range_query ()->range_of_expr (r1, ssa);
+ ASSERT_EQ (r0, r1);
}
// Run floating range tests for various combinations of NAN and INF
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index d0beac8..6851201b 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -2400,7 +2400,7 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
else
{
/* Special-case handling of vtv comdat sections. */
- if (sect->named.name
+ if (SECTION_STYLE (sect) == SECTION_NAMED
&& (strcmp (sect->named.name, ".vtable_map_vars") == 0))
handle_vtv_comdat_section (sect, decl);
else
@@ -6915,11 +6915,16 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE);
if (flags & SECTION_LINK_ORDER)
{
- tree id = DECL_ASSEMBLER_NAME (decl);
- ultimate_transparent_alias_target (&id);
- const char *name = IDENTIFIER_POINTER (id);
- name = targetm.strip_name_encoding (name);
- fprintf (asm_out_file, ",%s", name);
+ /* For now, only section "__patchable_function_entries"
+ adopts flag SECTION_LINK_ORDER, internal label LPFE*
+ was emitted in default_print_patchable_function_entry,
+ just place it here for linked_to section. */
+ gcc_assert (!strcmp (name, "__patchable_function_entries"));
+ fprintf (asm_out_file, ",");
+ char buf[256];
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LPFE",
+ current_function_funcdef_no);
+ assemble_name_raw (asm_out_file, buf);
}
if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
{
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index 71fed1e..a1f7346 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -52,415 +52,6 @@ along with GCC; see the file COPYING3. If not see
#include "range-op.h"
#include "gimple-range.h"
-/* Set value range VR to a non-negative range of type TYPE. */
-
-static inline void
-set_value_range_to_nonnegative (value_range_equiv *vr, tree type)
-{
- tree zero = build_int_cst (type, 0);
- vr->update (zero, vrp_val_max (type));
-}
-
-/* Set value range VR to a range of a truthvalue of type TYPE. */
-
-static inline void
-set_value_range_to_truthvalue (value_range_equiv *vr, tree type)
-{
- if (TYPE_PRECISION (type) == 1)
- vr->set_varying (type);
- else
- vr->update (build_int_cst (type, 0), build_int_cst (type, 1));
-}
-
-/* Return the lattice entry for VAR or NULL if it doesn't exist or cannot
- be initialized. */
-
-value_range_equiv *
-vr_values::get_lattice_entry (const_tree var)
-{
- value_range_equiv *vr;
- tree sym;
- unsigned ver = SSA_NAME_VERSION (var);
-
- /* If we query the entry for a new SSA name avoid reallocating the lattice
- since we should get here at most from the substitute-and-fold stage which
- will never try to change values. */
- if (ver >= num_vr_values)
- return NULL;
-
- vr = vr_value[ver];
- if (vr)
- return vr;
-
- /* Create a default value range. */
- vr = allocate_value_range_equiv ();
- vr_value[ver] = vr;
-
- /* After propagation finished return varying. */
- if (values_propagated)
- {
- vr->set_varying (TREE_TYPE (var));
- return vr;
- }
-
- vr->set_undefined ();
-
- /* If VAR is a default definition of a parameter, the variable can
- take any value in VAR's type. */
- if (SSA_NAME_IS_DEFAULT_DEF (var))
- {
- sym = SSA_NAME_VAR (var);
- if (TREE_CODE (sym) == PARM_DECL)
- {
- /* Try to use the "nonnull" attribute to create ~[0, 0]
- anti-ranges for pointers. Note that this is only valid with
- default definitions of PARM_DECLs. */
- if (POINTER_TYPE_P (TREE_TYPE (sym))
- && (nonnull_arg_p (sym)
- || (get_global_range_query ()->range_of_expr (*vr,
- const_cast <tree> (var))
- && vr->nonzero_p ())))
- {
- vr->set_nonzero (TREE_TYPE (sym));
- vr->equiv_clear ();
- }
- else if (INTEGRAL_TYPE_P (TREE_TYPE (sym)))
- {
- get_global_range_query ()->range_of_expr (*vr, const_cast <tree> (var));
- if (vr->undefined_p ())
- vr->set_varying (TREE_TYPE (sym));
- }
- else
- vr->set_varying (TREE_TYPE (sym));
- }
- else if (TREE_CODE (sym) == RESULT_DECL
- && DECL_BY_REFERENCE (sym))
- {
- vr->set_nonzero (TREE_TYPE (sym));
- vr->equiv_clear ();
- }
- }
-
- return vr;
-}
-
-/* Return value range information for VAR.
-
- If we have no values ranges recorded (ie, VRP is not running), then
- return NULL. Otherwise create an empty range if none existed for VAR. */
-
-const value_range_equiv *
-vr_values::get_value_range (const_tree var,
- gimple *stmt ATTRIBUTE_UNUSED)
-{
- /* If we have no recorded ranges, then return NULL. */
- if (!vr_value)
- return NULL;
-
- value_range_equiv *vr = get_lattice_entry (var);
-
- /* Reallocate the lattice if needed. */
- if (!vr)
- {
- unsigned int old_sz = num_vr_values;
- num_vr_values = num_ssa_names + num_ssa_names / 10;
- vr_value = XRESIZEVEC (value_range_equiv *, vr_value, num_vr_values);
- for ( ; old_sz < num_vr_values; old_sz++)
- vr_value [old_sz] = NULL;
-
- /* Now that the lattice has been resized, we should never fail. */
- vr = get_lattice_entry (var);
- gcc_assert (vr);
- }
-
- return vr;
-}
-
-bool
-vr_values::range_of_expr (vrange &r, tree expr, gimple *stmt)
-{
- if (!gimple_range_ssa_p (expr))
- return get_tree_range (r, expr, stmt);
-
- if (const value_range *vr = get_value_range (expr, stmt))
- {
- if (!vr->supports_type_p (TREE_TYPE (expr)))
- {
- // vr_values::extract_range_basic() use of ranger's
- // fold_range() can create a situation where we are asked
- // for the range of an unsupported legacy type. Since
- // get_value_range() above will return varying or undefined
- // for such types, avoid copying incompatible range types.
- if (vr->undefined_p ())
- r.set_undefined ();
- else
- r.set_varying (TREE_TYPE (expr));
- return true;
- }
- if (vr->undefined_p () || vr->constant_p ())
- r = *vr;
- else
- {
- value_range tmp = *vr;
- tmp.normalize_symbolics ();
- r = tmp;
- }
- return true;
- }
- return false;
-}
-
-tree
-vr_values::value_of_expr (tree op, gimple *)
-{
- return op_with_constant_singleton_value_range (op);
-}
-
-tree
-vr_values::value_on_edge (edge, tree op)
-{
- return op_with_constant_singleton_value_range (op);
-}
-
-tree
-vr_values::value_of_stmt (gimple *stmt, tree op)
-{
- if (!op)
- op = gimple_get_lhs (stmt);
-
- gcc_checking_assert (!op|| op == gimple_get_lhs (stmt));
-
- if (op)
- return op_with_constant_singleton_value_range (op);
- return NULL_TREE;
-}
-
-/* Set the lattice entry for DEF to VARYING. */
-
-void
-vr_values::set_def_to_varying (const_tree def)
-{
- value_range_equiv *vr = get_lattice_entry (def);
- if (vr)
- vr->set_varying (TREE_TYPE (def));
-}
-
-/* Set value-ranges of all SSA names defined by STMT to varying. */
-
-void
-vr_values::set_defs_to_varying (gimple *stmt)
-{
- ssa_op_iter i;
- tree def;
- FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
- set_def_to_varying (def);
-}
-
-/* Update the value range and equivalence set for variable VAR to
- NEW_VR. Return true if NEW_VR is different from VAR's previous
- value.
-
- NOTE: This function assumes that NEW_VR is a temporary value range
- object created for the sole purpose of updating VAR's range. The
- storage used by the equivalence set from NEW_VR will be freed by
- this function. Do not call update_value_range when NEW_VR
- is the range object associated with another SSA name. */
-
-bool
-vr_values::update_value_range (const_tree var, value_range_equiv *new_vr)
-{
- value_range_equiv *old_vr;
- bool is_new;
-
- /* If there is a value-range on the SSA name from earlier analysis
- factor that in. */
- if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
- {
- value_range_equiv nr;
- get_global_range_query ()->range_of_expr (nr, const_cast <tree> (var));
- if (!nr.undefined_p ())
- new_vr->legacy_verbose_intersect (&nr);
- }
-
- /* Update the value range, if necessary. If we cannot allocate a lattice
- entry for VAR keep it at VARYING. This happens when DOM feeds us stmts
- with SSA names allocated after setting up the lattice. */
- old_vr = get_lattice_entry (var);
- if (!old_vr)
- return false;
- is_new = !old_vr->equal_p (*new_vr, /*ignore_equivs=*/false);
-
- if (is_new)
- {
- /* Do not allow transitions up the lattice. The following
- is slightly more awkward than just new_vr->type < old_vr->type
- because VR_RANGE and VR_ANTI_RANGE need to be considered
- the same. We may not have is_new when transitioning to
- UNDEFINED. If old_vr->type is VARYING, we shouldn't be
- called, if we are anyway, keep it VARYING. */
- if (old_vr->varying_p ())
- {
- new_vr->set_varying (TREE_TYPE (var));
- is_new = false;
- }
- else if (new_vr->undefined_p ())
- {
- old_vr->set_varying (TREE_TYPE (var));
- new_vr->set_varying (TREE_TYPE (var));
- return true;
- }
- else
- old_vr->set (new_vr->min (), new_vr->max (), new_vr->equiv (),
- new_vr->kind ());
- }
-
- new_vr->equiv_clear ();
-
- return is_new;
-}
-
-/* Return true if value range VR involves exactly one symbol SYM. */
-
-static bool
-symbolic_range_based_on_p (value_range *vr, const_tree sym)
-{
- bool neg, min_has_symbol, max_has_symbol;
- tree inv;
-
- if (is_gimple_min_invariant (vr->min ()))
- min_has_symbol = false;
- else if (get_single_symbol (vr->min (), &neg, &inv) == sym)
- min_has_symbol = true;
- else
- return false;
-
- if (is_gimple_min_invariant (vr->max ()))
- max_has_symbol = false;
- else if (get_single_symbol (vr->max (), &neg, &inv) == sym)
- max_has_symbol = true;
- else
- return false;
-
- return (min_has_symbol || max_has_symbol);
-}
-
-/* Return true if the result of assignment STMT is know to be non-zero. */
-
-static bool
-gimple_assign_nonzero_p (gimple *stmt)
-{
- enum tree_code code = gimple_assign_rhs_code (stmt);
- bool strict_overflow_p;
- tree type = TREE_TYPE (gimple_assign_lhs (stmt));
- switch (get_gimple_rhs_class (code))
- {
- case GIMPLE_UNARY_RHS:
- return tree_unary_nonzero_warnv_p (gimple_assign_rhs_code (stmt),
- type,
- gimple_assign_rhs1 (stmt),
- &strict_overflow_p);
- case GIMPLE_BINARY_RHS:
- return tree_binary_nonzero_warnv_p (gimple_assign_rhs_code (stmt),
- type,
- gimple_assign_rhs1 (stmt),
- gimple_assign_rhs2 (stmt),
- &strict_overflow_p);
- case GIMPLE_TERNARY_RHS:
- return false;
- case GIMPLE_SINGLE_RHS:
- return tree_single_nonzero_warnv_p (gimple_assign_rhs1 (stmt),
- &strict_overflow_p);
- case GIMPLE_INVALID_RHS:
- gcc_unreachable ();
- default:
- gcc_unreachable ();
- }
-}
-
-/* Return true if STMT is known to compute a non-zero value. */
-
-static bool
-gimple_stmt_nonzero_p (gimple *stmt)
-{
- switch (gimple_code (stmt))
- {
- case GIMPLE_ASSIGN:
- return gimple_assign_nonzero_p (stmt);
- case GIMPLE_CALL:
- {
- gcall *call_stmt = as_a<gcall *> (stmt);
- return (gimple_call_nonnull_result_p (call_stmt)
- || gimple_call_nonnull_arg (call_stmt));
- }
- default:
- gcc_unreachable ();
- }
-}
-/* Like tree_expr_nonzero_p, but this function uses value ranges
- obtained so far. */
-
-bool
-vr_values::vrp_stmt_computes_nonzero (gimple *stmt)
-{
- if (gimple_stmt_nonzero_p (stmt))
- return true;
-
- /* If we have an expression of the form &X->a, then the expression
- is nonnull if X is nonnull. */
- if (is_gimple_assign (stmt)
- && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
- {
- tree expr = gimple_assign_rhs1 (stmt);
- poly_int64 bitsize, bitpos;
- tree offset;
- machine_mode mode;
- int unsignedp, reversep, volatilep;
- tree base = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize,
- &bitpos, &offset, &mode, &unsignedp,
- &reversep, &volatilep);
-
- if (base != NULL_TREE
- && TREE_CODE (base) == MEM_REF
- && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
- {
- poly_offset_int off = 0;
- bool off_cst = false;
- if (offset == NULL_TREE || TREE_CODE (offset) == INTEGER_CST)
- {
- off = mem_ref_offset (base);
- if (offset)
- off += poly_offset_int::from (wi::to_poly_wide (offset),
- SIGNED);
- off <<= LOG2_BITS_PER_UNIT;
- off += bitpos;
- off_cst = true;
- }
- /* If &X->a is equal to X and X is ~[0, 0], the result is too.
- For -fdelete-null-pointer-checks -fno-wrapv-pointer we don't
- allow going from non-NULL pointer to NULL. */
- if ((off_cst && known_eq (off, 0))
- || (flag_delete_null_pointer_checks
- && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr))))
- {
- const value_range_equiv *vr
- = get_value_range (TREE_OPERAND (base, 0), stmt);
- if (!range_includes_zero_p (vr))
- return true;
- }
- /* If MEM_REF has a "positive" offset, consider it non-NULL
- always, for -fdelete-null-pointer-checks also "negative"
- ones. Punt for unknown offsets (e.g. variable ones). */
- if (!TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr))
- && off_cst
- && known_ne (off, 0)
- && (flag_delete_null_pointer_checks || known_gt (off, 0)))
- return true;
- }
- }
-
- return false;
-}
-
/* Returns true if EXPR is a valid value (as expected by compare_values) --
a gimple invariant, or SSA_NAME +- CST. */
@@ -478,25 +69,6 @@ valid_value_p (tree expr)
return is_gimple_min_invariant (expr);
}
-/* If OP has a value range with a single constant value return that,
- otherwise return NULL_TREE. This returns OP itself if OP is a
- constant. */
-
-tree
-vr_values::op_with_constant_singleton_value_range (tree op)
-{
- if (is_gimple_min_invariant (op))
- return op;
-
- if (TREE_CODE (op) != SSA_NAME)
- return NULL_TREE;
-
- tree t;
- if (get_value_range (op)->singleton_p (&t))
- return t;
- return NULL;
-}
-
/* Return true if op is in a boolean [0, 1] value-range. */
bool
@@ -519,549 +91,6 @@ simplify_using_ranges::op_with_boolean_value_range_p (tree op, gimple *s)
build_one_cst (TREE_TYPE (op)));
}
-/* Extract value range information for VAR when (OP COND_CODE LIMIT) is
- true and store it in *VR_P. */
-
-void
-vr_values::extract_range_for_var_from_comparison_expr (tree var,
- enum tree_code cond_code,
- tree op, tree limit,
- value_range_equiv *vr_p)
-{
- tree min, max, type;
- const value_range_equiv *limit_vr;
- type = TREE_TYPE (var);
-
- /* For pointer arithmetic, we only keep track of pointer equality
- and inequality. If we arrive here with unfolded conditions like
- _1 > _1 do not derive anything. */
- if ((POINTER_TYPE_P (type) && cond_code != NE_EXPR && cond_code != EQ_EXPR)
- || limit == var)
- {
- vr_p->set_varying (type);
- return;
- }
-
- /* If LIMIT is another SSA name and LIMIT has a range of its own,
- try to use LIMIT's range to avoid creating symbolic ranges
- unnecessarily. */
- limit_vr = (TREE_CODE (limit) == SSA_NAME) ? get_value_range (limit) : NULL;
-
- /* LIMIT's range is only interesting if it has any useful information. */
- if (! limit_vr
- || limit_vr->undefined_p ()
- || limit_vr->varying_p ()
- || (limit_vr->symbolic_p ()
- && ! (limit_vr->kind () == VR_RANGE
- && (limit_vr->min () == limit_vr->max ()
- || operand_equal_p (limit_vr->min (),
- limit_vr->max (), 0)))))
- limit_vr = NULL;
-
- /* Initially, the new range has the same set of equivalences of
- VAR's range. This will be revised before returning the final
- value. Since assertions may be chained via mutually exclusive
- predicates, we will need to trim the set of equivalences before
- we are done. */
- gcc_assert (vr_p->equiv () == NULL);
- vr_p->equiv_add (var, get_value_range (var), &vrp_equiv_obstack);
-
- /* Extract a new range based on the asserted comparison for VAR and
- LIMIT's value range. Notice that if LIMIT has an anti-range, we
- will only use it for equality comparisons (EQ_EXPR). For any
- other kind of assertion, we cannot derive a range from LIMIT's
- anti-range that can be used to describe the new range. For
- instance, ASSERT_EXPR <x_2, x_2 <= b_4>. If b_4 is ~[2, 10],
- then b_4 takes on the ranges [-INF, 1] and [11, +INF]. There is
- no single range for x_2 that could describe LE_EXPR, so we might
- as well build the range [b_4, +INF] for it.
- One special case we handle is extracting a range from a
- range test encoded as (unsigned)var + CST <= limit. */
- if (TREE_CODE (op) == NOP_EXPR
- || TREE_CODE (op) == PLUS_EXPR)
- {
- if (TREE_CODE (op) == PLUS_EXPR)
- {
- min = fold_build1 (NEGATE_EXPR, TREE_TYPE (TREE_OPERAND (op, 1)),
- TREE_OPERAND (op, 1));
- max = int_const_binop (PLUS_EXPR, limit, min);
- op = TREE_OPERAND (op, 0);
- }
- else
- {
- min = build_int_cst (TREE_TYPE (var), 0);
- max = limit;
- }
-
- /* Make sure to not set TREE_OVERFLOW on the final type
- conversion. We are willingly interpreting large positive
- unsigned values as negative signed values here. */
- min = force_fit_type (TREE_TYPE (var), wi::to_widest (min), 0, false);
- max = force_fit_type (TREE_TYPE (var), wi::to_widest (max), 0, false);
-
- /* We can transform a max, min range to an anti-range or
- vice-versa. Use set_and_canonicalize which does this for
- us. */
- if (cond_code == LE_EXPR)
- vr_p->set (min, max, vr_p->equiv ());
- else if (cond_code == GT_EXPR)
- vr_p->set (min, max, vr_p->equiv (), VR_ANTI_RANGE);
- else
- gcc_unreachable ();
- }
- else if (cond_code == EQ_EXPR)
- {
- enum value_range_kind range_kind;
-
- if (limit_vr)
- {
- range_kind = limit_vr->kind ();
- min = limit_vr->min ();
- max = limit_vr->max ();
- }
- else
- {
- range_kind = VR_RANGE;
- min = limit;
- max = limit;
- }
-
- vr_p->update (min, max, range_kind);
-
- /* When asserting the equality VAR == LIMIT and LIMIT is another
- SSA name, the new range will also inherit the equivalence set
- from LIMIT. */
- if (TREE_CODE (limit) == SSA_NAME)
- vr_p->equiv_add (limit, get_value_range (limit), &vrp_equiv_obstack);
- }
- else if (cond_code == NE_EXPR)
- {
- /* As described above, when LIMIT's range is an anti-range and
- this assertion is an inequality (NE_EXPR), then we cannot
- derive anything from the anti-range. For instance, if
- LIMIT's range was ~[0, 0], the assertion 'VAR != LIMIT' does
- not imply that VAR's range is [0, 0]. So, in the case of
- anti-ranges, we just assert the inequality using LIMIT and
- not its anti-range.
-
- If LIMIT_VR is a range, we can only use it to build a new
- anti-range if LIMIT_VR is a single-valued range. For
- instance, if LIMIT_VR is [0, 1], the predicate
- VAR != [0, 1] does not mean that VAR's range is ~[0, 1].
- Rather, it means that for value 0 VAR should be ~[0, 0]
- and for value 1, VAR should be ~[1, 1]. We cannot
- represent these ranges.
-
- The only situation in which we can build a valid
- anti-range is when LIMIT_VR is a single-valued range
- (i.e., LIMIT_VR->MIN == LIMIT_VR->MAX). In that case,
- build the anti-range ~[LIMIT_VR->MIN, LIMIT_VR->MAX]. */
- if (limit_vr
- && limit_vr->kind () == VR_RANGE
- && compare_values (limit_vr->min (), limit_vr->max ()) == 0)
- {
- min = limit_vr->min ();
- max = limit_vr->max ();
- }
- else
- {
- /* In any other case, we cannot use LIMIT's range to build a
- valid anti-range. */
- min = max = limit;
- }
-
- /* If MIN and MAX cover the whole range for their type, then
- just use the original LIMIT. */
- if (INTEGRAL_TYPE_P (type)
- && vrp_val_is_min (min)
- && vrp_val_is_max (max))
- min = max = limit;
-
- vr_p->set (min, max, vr_p->equiv (), VR_ANTI_RANGE);
- }
- else if (cond_code == LE_EXPR || cond_code == LT_EXPR)
- {
- min = TYPE_MIN_VALUE (type);
-
- if (limit_vr == NULL || limit_vr->kind () == VR_ANTI_RANGE)
- max = limit;
- else
- {
- /* If LIMIT_VR is of the form [N1, N2], we need to build the
- range [MIN, N2] for LE_EXPR and [MIN, N2 - 1] for
- LT_EXPR. */
- max = limit_vr->max ();
- }
-
- /* If the maximum value forces us to be out of bounds, simply punt.
- It would be pointless to try and do anything more since this
- all should be optimized away above us. */
- if (cond_code == LT_EXPR
- && compare_values (max, min) == 0)
- vr_p->set_varying (TREE_TYPE (min));
- else
- {
- /* For LT_EXPR, we create the range [MIN, MAX - 1]. */
- if (cond_code == LT_EXPR)
- {
- if (TYPE_PRECISION (TREE_TYPE (max)) == 1
- && !TYPE_UNSIGNED (TREE_TYPE (max)))
- max = fold_build2 (PLUS_EXPR, TREE_TYPE (max), max,
- build_int_cst (TREE_TYPE (max), -1));
- else
- max = fold_build2 (MINUS_EXPR, TREE_TYPE (max), max,
- build_int_cst (TREE_TYPE (max), 1));
- /* Signal to compare_values_warnv this expr doesn't overflow. */
- if (EXPR_P (max))
- suppress_warning (max, OPT_Woverflow);
- }
-
- vr_p->update (min, max);
- }
- }
- else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
- {
- max = TYPE_MAX_VALUE (type);
-
- if (limit_vr == NULL || limit_vr->kind () == VR_ANTI_RANGE)
- min = limit;
- else
- {
- /* If LIMIT_VR is of the form [N1, N2], we need to build the
- range [N1, MAX] for GE_EXPR and [N1 + 1, MAX] for
- GT_EXPR. */
- min = limit_vr->min ();
- }
-
- /* If the minimum value forces us to be out of bounds, simply punt.
- It would be pointless to try and do anything more since this
- all should be optimized away above us. */
- if (cond_code == GT_EXPR
- && compare_values (min, max) == 0)
- vr_p->set_varying (TREE_TYPE (min));
- else
- {
- /* For GT_EXPR, we create the range [MIN + 1, MAX]. */
- if (cond_code == GT_EXPR)
- {
- if (TYPE_PRECISION (TREE_TYPE (min)) == 1
- && !TYPE_UNSIGNED (TREE_TYPE (min)))
- min = fold_build2 (MINUS_EXPR, TREE_TYPE (min), min,
- build_int_cst (TREE_TYPE (min), -1));
- else
- min = fold_build2 (PLUS_EXPR, TREE_TYPE (min), min,
- build_int_cst (TREE_TYPE (min), 1));
- /* Signal to compare_values_warnv this expr doesn't overflow. */
- if (EXPR_P (min))
- suppress_warning (min, OPT_Woverflow);
- }
-
- vr_p->update (min, max);
- }
- }
- else
- gcc_unreachable ();
-
- /* Finally intersect the new range with what we already know about var. */
- vr_p->legacy_verbose_intersect (get_value_range (var));
-}
-
-/* Extract value range information from an ASSERT_EXPR EXPR and store
- it in *VR_P. */
-
-void
-vr_values::extract_range_from_assert (value_range_equiv *vr_p, tree expr)
-{
- tree var = ASSERT_EXPR_VAR (expr);
- tree cond = ASSERT_EXPR_COND (expr);
- tree limit, op;
- enum tree_code cond_code;
- gcc_assert (COMPARISON_CLASS_P (cond));
-
- /* Find VAR in the ASSERT_EXPR conditional. */
- if (var == TREE_OPERAND (cond, 0)
- || TREE_CODE (TREE_OPERAND (cond, 0)) == PLUS_EXPR
- || TREE_CODE (TREE_OPERAND (cond, 0)) == NOP_EXPR)
- {
- /* If the predicate is of the form VAR COMP LIMIT, then we just
- take LIMIT from the RHS and use the same comparison code. */
- cond_code = TREE_CODE (cond);
- limit = TREE_OPERAND (cond, 1);
- op = TREE_OPERAND (cond, 0);
- }
- else
- {
- /* If the predicate is of the form LIMIT COMP VAR, then we need
- to flip around the comparison code to create the proper range
- for VAR. */
- cond_code = swap_tree_comparison (TREE_CODE (cond));
- limit = TREE_OPERAND (cond, 0);
- op = TREE_OPERAND (cond, 1);
- }
- extract_range_for_var_from_comparison_expr (var, cond_code, op,
- limit, vr_p);
-}
-
-/* Extract range information from SSA name VAR and store it in VR. If
- VAR has an interesting range, use it. Otherwise, create the
- range [VAR, VAR] and return it. This is useful in situations where
- we may have conditionals testing values of VARYING names. For
- instance,
-
- x_3 = y_5;
- if (x_3 > y_5)
- ...
-
- Even if y_5 is deemed VARYING, we can determine that x_3 > y_5 is
- always false. */
-
-void
-vr_values::extract_range_from_ssa_name (value_range_equiv *vr, tree var)
-{
- const value_range_equiv *var_vr = get_value_range (var);
-
- if (!var_vr->varying_p ())
- vr->deep_copy (var_vr);
- else
- vr->set (var);
-
- if (!vr->undefined_p ())
- vr->equiv_add (var, get_value_range (var), &vrp_equiv_obstack);
-}
-
-/* Extract range information from a binary expression OP0 CODE OP1 based on
- the ranges of each of its operands with resulting type EXPR_TYPE.
- The resulting range is stored in *VR. */
-
-void
-vr_values::extract_range_from_binary_expr (value_range_equiv *vr,
- enum tree_code code,
- tree expr_type, tree op0, tree op1)
-{
- /* Get value ranges for each operand. For constant operands, create
- a new value range with the operand to simplify processing. */
- value_range vr0, vr1;
- if (TREE_CODE (op0) == SSA_NAME)
- vr0 = *(get_value_range (op0));
- else if (is_gimple_min_invariant (op0))
- vr0.set (op0, op0);
- else
- vr0.set_varying (TREE_TYPE (op0));
-
- if (TREE_CODE (op1) == SSA_NAME)
- vr1 = *(get_value_range (op1));
- else if (is_gimple_min_invariant (op1))
- vr1.set (op1, op1);
- else
- vr1.set_varying (TREE_TYPE (op1));
-
- /* If one argument is varying, we can sometimes still deduce a
- range for the output: any + [3, +INF] is in [MIN+3, +INF]. */
- if (INTEGRAL_TYPE_P (TREE_TYPE (op0))
- && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0)))
- {
- if (vr0.varying_p () && !vr1.varying_p ())
- vr0 = value_range (vrp_val_min (expr_type), vrp_val_max (expr_type));
- else if (vr1.varying_p () && !vr0.varying_p ())
- vr1 = value_range (vrp_val_min (expr_type), vrp_val_max (expr_type));
- }
-
- range_fold_binary_expr (vr, code, expr_type, &vr0, &vr1);
-
- /* Set value_range for n in following sequence:
- def = __builtin_memchr (arg, 0, sz)
- n = def - arg
- Here the range for n can be set to [0, PTRDIFF_MAX - 1]. */
-
- if (vr->varying_p ()
- && code == POINTER_DIFF_EXPR
- && TREE_CODE (op0) == SSA_NAME
- && TREE_CODE (op1) == SSA_NAME)
- {
- tree op0_ptype = TREE_TYPE (TREE_TYPE (op0));
- tree op1_ptype = TREE_TYPE (TREE_TYPE (op1));
- gcall *call_stmt = NULL;
-
- if (TYPE_MODE (op0_ptype) == TYPE_MODE (char_type_node)
- && TYPE_PRECISION (op0_ptype) == TYPE_PRECISION (char_type_node)
- && TYPE_MODE (op1_ptype) == TYPE_MODE (char_type_node)
- && TYPE_PRECISION (op1_ptype) == TYPE_PRECISION (char_type_node)
- && (call_stmt = dyn_cast<gcall *>(SSA_NAME_DEF_STMT (op0)))
- && gimple_call_builtin_p (call_stmt, BUILT_IN_MEMCHR)
- && operand_equal_p (op0, gimple_call_lhs (call_stmt), 0)
- && operand_equal_p (op1, gimple_call_arg (call_stmt, 0), 0)
- && integer_zerop (gimple_call_arg (call_stmt, 1)))
- {
- tree max = vrp_val_max (ptrdiff_type_node);
- wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
- tree range_min = build_zero_cst (expr_type);
- tree range_max = wide_int_to_tree (expr_type, wmax - 1);
- vr->set (range_min, range_max, NULL);
- return;
- }
- }
-
- /* Try harder for PLUS and MINUS if the range of one operand is symbolic
- and based on the other operand, for example if it was deduced from a
- symbolic comparison. When a bound of the range of the first operand
- is invariant, we set the corresponding bound of the new range to INF
- in order to avoid recursing on the range of the second operand. */
- if (vr->varying_p ()
- && (code == PLUS_EXPR || code == MINUS_EXPR)
- && TREE_CODE (op1) == SSA_NAME
- && vr0.kind () == VR_RANGE
- && symbolic_range_based_on_p (&vr0, op1))
- {
- const bool minus_p = (code == MINUS_EXPR);
- value_range n_vr1;
-
- /* Try with VR0 and [-INF, OP1]. */
- if (is_gimple_min_invariant (minus_p ? vr0.max () : vr0.min ()))
- n_vr1.set (vrp_val_min (expr_type), op1);
-
- /* Try with VR0 and [OP1, +INF]. */
- else if (is_gimple_min_invariant (minus_p ? vr0.min () : vr0.max ()))
- n_vr1.set (op1, vrp_val_max (expr_type));
-
- /* Try with VR0 and [OP1, OP1]. */
- else
- n_vr1.set (op1, op1);
-
- range_fold_binary_expr (vr, code, expr_type, &vr0, &n_vr1);
- }
-
- if (vr->varying_p ()
- && (code == PLUS_EXPR || code == MINUS_EXPR)
- && TREE_CODE (op0) == SSA_NAME
- && vr1.kind () == VR_RANGE
- && symbolic_range_based_on_p (&vr1, op0))
- {
- const bool minus_p = (code == MINUS_EXPR);
- value_range n_vr0;
-
- /* Try with [-INF, OP0] and VR1. */
- if (is_gimple_min_invariant (minus_p ? vr1.max () : vr1.min ()))
- n_vr0.set (vrp_val_min (expr_type), op0);
-
- /* Try with [OP0, +INF] and VR1. */
- else if (is_gimple_min_invariant (minus_p ? vr1.min (): vr1.max ()))
- n_vr0.set (op0, vrp_val_max (expr_type));
-
- /* Try with [OP0, OP0] and VR1. */
- else
- n_vr0.set (op0, op0);
-
- range_fold_binary_expr (vr, code, expr_type, &n_vr0, &vr1);
- }
-
- /* If we didn't derive a range for MINUS_EXPR, and
- op1's range is ~[op0,op0] or vice-versa, then we
- can derive a non-null range. This happens often for
- pointer subtraction. */
- if (vr->varying_p ()
- && (code == MINUS_EXPR || code == POINTER_DIFF_EXPR)
- && TREE_CODE (op0) == SSA_NAME
- && ((vr0.kind () == VR_ANTI_RANGE
- && vr0.min () == op1
- && vr0.min () == vr0.max ())
- || (vr1.kind () == VR_ANTI_RANGE
- && vr1.min () == op0
- && vr1.min () == vr1.max ())))
- {
- vr->set_nonzero (expr_type);
- vr->equiv_clear ();
- }
-}
-
-/* Extract range information from a unary expression CODE OP0 based on
- the range of its operand with resulting type TYPE.
- The resulting range is stored in *VR. */
-
-void
-vr_values::extract_range_from_unary_expr (value_range_equiv *vr,
- enum tree_code code,
- tree type, tree op0)
-{
- value_range vr0;
-
- /* Get value ranges for the operand. For constant operands, create
- a new value range with the operand to simplify processing. */
- if (TREE_CODE (op0) == SSA_NAME)
- vr0 = *(get_value_range (op0));
- else if (is_gimple_min_invariant (op0))
- vr0.set (op0, op0);
- else
- vr0.set_varying (type);
-
- range_fold_unary_expr (vr, code, type, &vr0, TREE_TYPE (op0));
-}
-
-
-/* Extract range information from a conditional expression STMT based on
- the ranges of each of its operands and the expression code. */
-
-void
-vr_values::extract_range_from_cond_expr (value_range_equiv *vr, gassign *stmt)
-{
- /* Get value ranges for each operand. For constant operands, create
- a new value range with the operand to simplify processing. */
- tree op0 = gimple_assign_rhs2 (stmt);
- value_range_equiv tem0;
- const value_range_equiv *vr0 = &tem0;
- if (TREE_CODE (op0) == SSA_NAME)
- vr0 = get_value_range (op0);
- else if (is_gimple_min_invariant (op0))
- tem0.set (op0);
- else
- tem0.set_varying (TREE_TYPE (op0));
-
- tree op1 = gimple_assign_rhs3 (stmt);
- value_range_equiv tem1;
- const value_range_equiv *vr1 = &tem1;
- if (TREE_CODE (op1) == SSA_NAME)
- vr1 = get_value_range (op1);
- else if (is_gimple_min_invariant (op1))
- tem1.set (op1);
- else
- tem1.set_varying (TREE_TYPE (op1));
-
- /* The resulting value range is the union of the operand ranges */
- vr->deep_copy (vr0);
- vr->legacy_verbose_union_ (vr1);
-}
-
-
-/* Extract range information from a comparison expression EXPR based
- on the range of its operand and the expression code. */
-
-void
-vr_values::extract_range_from_comparison (value_range_equiv *vr,
- gimple *stmt)
-{
- enum tree_code code = gimple_assign_rhs_code (stmt);
- tree type = TREE_TYPE (gimple_assign_lhs (stmt));
- tree op0 = gimple_assign_rhs1 (stmt);
- tree op1 = gimple_assign_rhs2 (stmt);
- bool sop;
- tree val
- = simplifier.vrp_evaluate_conditional_warnv_with_ops (stmt, code, op0, op1,
- false, &sop, NULL);
- if (val)
- {
- /* Since this expression was found on the RHS of an assignment,
- its type may be different from _Bool. Convert VAL to EXPR's
- type. */
- val = fold_convert (type, val);
- if (is_gimple_min_invariant (val))
- vr->set (val);
- else
- vr->update (val, val);
- }
- else
- /* The result of a comparison is always true or false. */
- set_value_range_to_truthvalue (vr, type);
-}
-
/* Helper function for simplify_internal_call_using_ranges and
extract_range_basic. Return true if OP0 SUBCODE OP1 for
SUBCODE {PLUS,MINUS,MULT}_EXPR is known to never overflow or
@@ -1171,228 +200,6 @@ check_for_binary_op_overflow (range_query *query,
return true;
}
-/* Derive a range from a builtin. Set range in VR and return TRUE if
- successful. */
-
-bool
-vr_values::extract_range_from_ubsan_builtin (value_range_equiv *vr, gimple *stmt)
-{
- gcc_assert (is_gimple_call (stmt));
- enum tree_code subcode = ERROR_MARK;
- combined_fn cfn = gimple_call_combined_fn (stmt);
- scalar_int_mode mode;
-
- switch (cfn)
- {
- case CFN_UBSAN_CHECK_ADD:
- subcode = PLUS_EXPR;
- break;
- case CFN_UBSAN_CHECK_SUB:
- subcode = MINUS_EXPR;
- break;
- case CFN_UBSAN_CHECK_MUL:
- subcode = MULT_EXPR;
- break;
- default:
- break;
- }
- if (subcode != ERROR_MARK)
- {
- bool saved_flag_wrapv = flag_wrapv;
- /* Pretend the arithmetics is wrapping. If there is
- any overflow, we'll complain, but will actually do
- wrapping operation. */
- flag_wrapv = 1;
- extract_range_from_binary_expr (vr, subcode,
- TREE_TYPE (gimple_call_arg (stmt, 0)),
- gimple_call_arg (stmt, 0),
- gimple_call_arg (stmt, 1));
- flag_wrapv = saved_flag_wrapv;
-
- /* If for both arguments vrp_valueize returned non-NULL,
- this should have been already folded and if not, it
- wasn't folded because of overflow. Avoid removing the
- UBSAN_CHECK_* calls in that case. */
- if (vr->kind () == VR_RANGE
- && (vr->min () == vr->max ()
- || operand_equal_p (vr->min (), vr->max (), 0)))
- vr->set_varying (vr->type ());
-
- return !vr->varying_p ();
- }
- return false;
-}
-
-/* Try to derive a nonnegative or nonzero range out of STMT relying
- primarily on generic routines in fold in conjunction with range data.
- Store the result in *VR */
-
-void
-vr_values::extract_range_basic (value_range_equiv *vr, gimple *stmt)
-{
- bool sop;
-
- if (is_gimple_call (stmt))
- {
- combined_fn cfn = gimple_call_combined_fn (stmt);
- switch (cfn)
- {
- case CFN_UBSAN_CHECK_ADD:
- case CFN_UBSAN_CHECK_SUB:
- case CFN_UBSAN_CHECK_MUL:
- if (extract_range_from_ubsan_builtin (vr, stmt))
- return;
- break;
- default:
- if (fold_range (*vr, stmt, this))
- {
- /* The original code nuked equivalences every time a
- range was found, so do the same here. */
- vr->equiv_clear ();
- return;
- }
- break;
- }
- }
- /* Handle extraction of the two results (result of arithmetics and
- a flag whether arithmetics overflowed) from {ADD,SUB,MUL}_OVERFLOW
- internal function. Similarly from ATOMIC_COMPARE_EXCHANGE. */
- if (is_gimple_assign (stmt)
- && (gimple_assign_rhs_code (stmt) == REALPART_EXPR
- || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR)
- && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt))))
- {
- enum tree_code code = gimple_assign_rhs_code (stmt);
- tree op = gimple_assign_rhs1 (stmt);
- tree type = TREE_TYPE (gimple_assign_lhs (stmt));
- if (TREE_CODE (op) == code && TREE_CODE (TREE_OPERAND (op, 0)) == SSA_NAME)
- {
- gimple *g = SSA_NAME_DEF_STMT (TREE_OPERAND (op, 0));
- if (is_gimple_call (g) && gimple_call_internal_p (g))
- {
- enum tree_code subcode = ERROR_MARK;
- switch (gimple_call_internal_fn (g))
- {
- case IFN_ADD_OVERFLOW:
- subcode = PLUS_EXPR;
- break;
- case IFN_SUB_OVERFLOW:
- subcode = MINUS_EXPR;
- break;
- case IFN_MUL_OVERFLOW:
- subcode = MULT_EXPR;
- break;
- case IFN_ATOMIC_COMPARE_EXCHANGE:
- if (code == IMAGPART_EXPR)
- {
- /* This is the boolean return value whether compare and
- exchange changed anything or not. */
- vr->set (build_int_cst (type, 0),
- build_int_cst (type, 1), NULL);
- return;
- }
- break;
- default:
- break;
- }
- if (subcode != ERROR_MARK)
- {
- tree op0 = gimple_call_arg (g, 0);
- tree op1 = gimple_call_arg (g, 1);
- if (code == IMAGPART_EXPR)
- {
- bool ovf = false;
- if (check_for_binary_op_overflow (this, subcode, type,
- op0, op1, &ovf))
- vr->set (build_int_cst (type, ovf));
- else if (TYPE_PRECISION (type) == 1
- && !TYPE_UNSIGNED (type))
- vr->set_varying (type);
- else
- vr->set (build_int_cst (type, 0),
- build_int_cst (type, 1), NULL);
- }
- else if (types_compatible_p (type, TREE_TYPE (op0))
- && types_compatible_p (type, TREE_TYPE (op1)))
- {
- bool saved_flag_wrapv = flag_wrapv;
- /* Pretend the arithmetics is wrapping. If there is
- any overflow, IMAGPART_EXPR will be set. */
- flag_wrapv = 1;
- extract_range_from_binary_expr (vr, subcode, type,
- op0, op1);
- flag_wrapv = saved_flag_wrapv;
- }
- else
- {
- value_range_equiv vr0, vr1;
- bool saved_flag_wrapv = flag_wrapv;
- /* Pretend the arithmetics is wrapping. If there is
- any overflow, IMAGPART_EXPR will be set. */
- flag_wrapv = 1;
- extract_range_from_unary_expr (&vr0, NOP_EXPR,
- type, op0);
- extract_range_from_unary_expr (&vr1, NOP_EXPR,
- type, op1);
- range_fold_binary_expr (vr, subcode, type, &vr0, &vr1);
- flag_wrapv = saved_flag_wrapv;
- }
- return;
- }
- }
- }
- }
- /* None of the below should need a 'type', but we are only called
- for assignments and calls with a LHS. */
- tree type = TREE_TYPE (gimple_get_lhs (stmt));
- if (INTEGRAL_TYPE_P (type)
- && gimple_stmt_nonnegative_warnv_p (stmt, &sop))
- set_value_range_to_nonnegative (vr, type);
- else if (vrp_stmt_computes_nonzero (stmt))
- {
- vr->set_nonzero (type);
- vr->equiv_clear ();
- }
- else
- vr->set_varying (type);
-}
-
-
-/* Try to compute a useful range out of assignment STMT and store it
- in *VR. */
-
-void
-vr_values::extract_range_from_assignment (value_range_equiv *vr, gassign *stmt)
-{
- enum tree_code code = gimple_assign_rhs_code (stmt);
-
- if (code == ASSERT_EXPR)
- extract_range_from_assert (vr, gimple_assign_rhs1 (stmt));
- else if (code == SSA_NAME)
- extract_range_from_ssa_name (vr, gimple_assign_rhs1 (stmt));
- else if (TREE_CODE_CLASS (code) == tcc_binary)
- extract_range_from_binary_expr (vr, gimple_assign_rhs_code (stmt),
- TREE_TYPE (gimple_assign_lhs (stmt)),
- gimple_assign_rhs1 (stmt),
- gimple_assign_rhs2 (stmt));
- else if (TREE_CODE_CLASS (code) == tcc_unary)
- extract_range_from_unary_expr (vr, gimple_assign_rhs_code (stmt),
- TREE_TYPE (gimple_assign_lhs (stmt)),
- gimple_assign_rhs1 (stmt));
- else if (code == COND_EXPR)
- extract_range_from_cond_expr (vr, stmt);
- else if (TREE_CODE_CLASS (code) == tcc_comparison)
- extract_range_from_comparison (vr, stmt);
- else if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS
- && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
- vr->set (gimple_assign_rhs1 (stmt));
- else
- vr->set_varying (TREE_TYPE (gimple_assign_lhs (stmt)));
-
- if (vr->varying_p ())
- extract_range_basic (vr, stmt);
-}
-
/* Given two numeric value ranges VR0, VR1 and a comparison code COMP:
- Return BOOLEAN_TRUE_NODE if VR0 COMP VR1 always returns true for
@@ -1408,8 +215,8 @@ vr_values::extract_range_from_assignment (value_range_equiv *vr, gassign *stmt)
static tree
-compare_ranges (enum tree_code comp, const value_range_equiv *vr0,
- const value_range_equiv *vr1, bool *strict_overflow_p)
+compare_ranges (enum tree_code comp, const value_range *vr0,
+ const value_range *vr1, bool *strict_overflow_p)
{
/* VARYING or UNDEFINED ranges cannot be compared. */
if (vr0->varying_p ()
@@ -1808,219 +615,24 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
return true;
}
-/* Given a range VR, a LOOP and a variable VAR, determine whether it
- would be profitable to adjust VR using scalar evolution information
- for VAR. If so, update VR with the new limits. */
-
-void
-vr_values::adjust_range_with_scev (value_range_equiv *vr, class loop *loop,
- gimple *stmt, tree var)
-{
- tree min, max;
- if (bounds_of_var_in_loop (&min, &max, this, loop, stmt, var))
- {
- if (vr->undefined_p () || vr->varying_p ())
- {
- /* For VARYING or UNDEFINED ranges, just about anything we get
- from scalar evolutions should be better. */
- vr->update (min, max);
- }
- else if (vr->kind () == VR_RANGE)
- {
- /* Start with the input range... */
- tree vrmin = vr->min ();
- tree vrmax = vr->max ();
-
- /* ...and narrow it down with what we got from SCEV. */
- if (compare_values (min, vrmin) == 1)
- vrmin = min;
- if (compare_values (max, vrmax) == -1)
- vrmax = max;
-
- vr->update (vrmin, vrmax);
- }
- else if (vr->kind () == VR_ANTI_RANGE)
- {
- /* ?? As an enhancement, if VR, MIN, and MAX are constants, one
- could just intersect VR with a range of [MIN,MAX]. */
- }
- }
-}
-
-/* Dump value ranges of all SSA_NAMEs to FILE. */
-
-void
-vr_values::dump (FILE *file)
-{
- size_t i;
-
- for (i = 0; i < num_vr_values; i++)
- {
- if (vr_value[i] && ssa_name (i))
- {
- print_generic_expr (file, ssa_name (i));
- fprintf (file, ": ");
- dump_value_range (file, vr_value[i]);
- fprintf (file, "\n");
- }
- }
-
- fprintf (file, "\n");
-}
-
-/* Initialize VRP lattice. */
-
-vr_values::vr_values () : simplifier (this)
-{
- values_propagated = false;
- num_vr_values = num_ssa_names * 2;
- vr_value = XCNEWVEC (value_range_equiv *, num_vr_values);
- vr_phi_edge_counts = XCNEWVEC (int, num_ssa_names);
- bitmap_obstack_initialize (&vrp_equiv_obstack);
-}
-
-/* Free VRP lattice. */
-
-vr_values::~vr_values ()
-{
- /* Free allocated memory. */
- free (vr_value);
- free (vr_phi_edge_counts);
- bitmap_obstack_release (&vrp_equiv_obstack);
-
- /* So that we can distinguish between VRP data being available
- and not available. */
- vr_value = NULL;
- vr_phi_edge_counts = NULL;
-}
-
-
-/* A hack. */
-static class vr_values *x_vr_values;
-
-/* Return the singleton value-range for NAME or NAME. */
-
-static inline tree
-vrp_valueize (tree name)
-{
- if (TREE_CODE (name) == SSA_NAME)
- {
- const value_range_equiv *vr = x_vr_values->get_value_range (name);
- if (vr->kind () == VR_RANGE
- && (TREE_CODE (vr->min ()) == SSA_NAME
- || is_gimple_min_invariant (vr->min ()))
- && vrp_operand_equal_p (vr->min (), vr->max ()))
- return vr->min ();
- }
- return name;
-}
-
-/* Return the singleton value-range for NAME if that is a constant
- but signal to not follow SSA edges. */
-
-static inline tree
-vrp_valueize_1 (tree name)
-{
- if (TREE_CODE (name) == SSA_NAME)
- {
- /* If the definition may be simulated again we cannot follow
- this SSA edge as the SSA propagator does not necessarily
- re-visit the use. */
- gimple *def_stmt = SSA_NAME_DEF_STMT (name);
- if (!gimple_nop_p (def_stmt)
- && prop_simulate_again_p (def_stmt))
- return NULL_TREE;
- const value_range_equiv *vr = x_vr_values->get_value_range (name);
- tree singleton;
- if (vr->singleton_p (&singleton))
- return singleton;
- }
- return name;
-}
-
-/* Given STMT, an assignment or call, return its LHS if the type
- of the LHS is suitable for VRP analysis, else return NULL_TREE. */
-
-tree
-get_output_for_vrp (gimple *stmt)
-{
- if (!is_gimple_assign (stmt) && !is_gimple_call (stmt))
- return NULL_TREE;
-
- /* We only keep track of ranges in integral and pointer types. */
- tree lhs = gimple_get_lhs (stmt);
- if (TREE_CODE (lhs) == SSA_NAME
- && ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
- /* It is valid to have NULL MIN/MAX values on a type. See
- build_range_type. */
- && TYPE_MIN_VALUE (TREE_TYPE (lhs))
- && TYPE_MAX_VALUE (TREE_TYPE (lhs)))
- || POINTER_TYPE_P (TREE_TYPE (lhs))))
- return lhs;
-
- return NULL_TREE;
-}
-
-/* Visit assignment STMT. If it produces an interesting range, record
- the range in VR and set LHS to OUTPUT_P. */
-
-void
-vr_values::vrp_visit_assignment_or_call (gimple *stmt, tree *output_p,
- value_range_equiv *vr)
-{
- tree lhs = get_output_for_vrp (stmt);
- *output_p = lhs;
-
- /* We only keep track of ranges in integral and pointer types. */
- if (lhs)
- {
- enum gimple_code code = gimple_code (stmt);
-
- /* Try folding the statement to a constant first. */
- x_vr_values = this;
- tree tem = gimple_fold_stmt_to_constant_1 (stmt, vrp_valueize,
- vrp_valueize_1);
- x_vr_values = NULL;
- if (tem)
- {
- if (TREE_CODE (tem) == SSA_NAME
- && (SSA_NAME_IS_DEFAULT_DEF (tem)
- || ! prop_simulate_again_p (SSA_NAME_DEF_STMT (tem))))
- {
- extract_range_from_ssa_name (vr, tem);
- return;
- }
- else if (is_gimple_min_invariant (tem))
- {
- vr->set (tem);
- return;
- }
- }
- /* Then dispatch to value-range extracting functions. */
- if (code == GIMPLE_CALL)
- extract_range_basic (vr, stmt);
- else
- extract_range_from_assignment (vr, as_a <gassign *> (stmt));
- }
-}
-
/* Helper that gets the value range of the SSA_NAME with version I
or a symbolic range containing the SSA_NAME only if the value range
is varying or undefined. Uses TEM as storage for the alternate range. */
-const value_range_equiv *
-simplify_using_ranges::get_vr_for_comparison (int i, value_range_equiv *tem,
+const value_range *
+simplify_using_ranges::get_vr_for_comparison (int i, value_range *tem,
gimple *s)
{
/* Shallow-copy equiv bitmap. */
- const value_range_equiv *vr = query->get_value_range (ssa_name (i), s);
+ const value_range *vr = query->get_value_range (ssa_name (i), s);
/* If name N_i does not have a valid range, use N_i as its own
range. This allows us to compare against names that may
have N_i in their ranges. */
if (vr->varying_p () || vr->undefined_p ())
{
- tem->set (ssa_name (i));
+ tree ssa = ssa_name (i);
+ tem->set (ssa, ssa);
return tem;
}
@@ -2035,196 +647,26 @@ simplify_using_ranges::get_vr_for_comparison (int i, value_range_equiv *tem,
tree
simplify_using_ranges::compare_name_with_value
(enum tree_code comp, tree var, tree val,
- bool *strict_overflow_p, bool use_equiv_p,
- gimple *s)
+ bool *strict_overflow_p, gimple *s)
{
- /* Get the set of equivalences for VAR. */
- bitmap e = query->get_value_range (var, s)->equiv ();
-
/* Start at -1. Set it to 0 if we do a comparison without relying
on overflow, or 1 if all comparisons rely on overflow. */
int used_strict_overflow = -1;
/* Compare vars' value range with val. */
- value_range_equiv tem_vr;
- const value_range_equiv *equiv_vr
+ value_range tem_vr;
+ const value_range *equiv_vr
= get_vr_for_comparison (SSA_NAME_VERSION (var), &tem_vr, s);
bool sop = false;
tree retval = compare_range_with_value (comp, equiv_vr, val, &sop);
if (retval)
used_strict_overflow = sop ? 1 : 0;
- /* If the equiv set is empty we have done all work we need to do. */
- if (e == NULL)
- {
- if (retval && used_strict_overflow > 0)
- *strict_overflow_p = true;
- return retval;
- }
-
- unsigned i;
- bitmap_iterator bi;
- EXECUTE_IF_SET_IN_BITMAP (e, 0, i, bi)
- {
- tree name = ssa_name (i);
- if (!name)
- continue;
-
- if (!use_equiv_p
- && !SSA_NAME_IS_DEFAULT_DEF (name)
- && prop_simulate_again_p (SSA_NAME_DEF_STMT (name)))
- continue;
-
- equiv_vr = get_vr_for_comparison (i, &tem_vr, s);
- sop = false;
- tree t = compare_range_with_value (comp, equiv_vr, val, &sop);
- if (t)
- {
- /* If we get different answers from different members
- of the equivalence set this check must be in a dead
- code region. Folding it to a trap representation
- would be correct here. For now just return don't-know. */
- if (retval != NULL
- && t != retval)
- {
- retval = NULL_TREE;
- break;
- }
- retval = t;
-
- if (!sop)
- used_strict_overflow = 0;
- else if (used_strict_overflow < 0)
- used_strict_overflow = 1;
- }
- }
-
if (retval && used_strict_overflow > 0)
*strict_overflow_p = true;
-
return retval;
}
-
-/* Given a comparison code COMP and names N1 and N2, compare all the
- ranges equivalent to N1 against all the ranges equivalent to N2
- to determine the value of N1 COMP N2. Return the same value
- returned by compare_ranges. Set *STRICT_OVERFLOW_P to indicate
- whether we relied on undefined signed overflow in the comparison. */
-
-
-tree
-simplify_using_ranges::compare_names (enum tree_code comp, tree n1, tree n2,
- bool *strict_overflow_p, gimple *s)
-{
- /* Compare the ranges of every name equivalent to N1 against the
- ranges of every name equivalent to N2. */
- bitmap e1 = query->get_value_range (n1, s)->equiv ();
- bitmap e2 = query->get_value_range (n2, s)->equiv ();
-
- /* Use the fake bitmaps if e1 or e2 are not available. */
- static bitmap s_e1 = NULL, s_e2 = NULL;
- static bitmap_obstack *s_obstack = NULL;
- if (s_obstack == NULL)
- {
- s_obstack = XNEW (bitmap_obstack);
- bitmap_obstack_initialize (s_obstack);
- s_e1 = BITMAP_ALLOC (s_obstack);
- s_e2 = BITMAP_ALLOC (s_obstack);
- }
- if (e1 == NULL)
- e1 = s_e1;
- if (e2 == NULL)
- e2 = s_e2;
-
- /* Add N1 and N2 to their own set of equivalences to avoid
- duplicating the body of the loop just to check N1 and N2
- ranges. */
- bitmap_set_bit (e1, SSA_NAME_VERSION (n1));
- bitmap_set_bit (e2, SSA_NAME_VERSION (n2));
-
- /* If the equivalence sets have a common intersection, then the two
- names can be compared without checking their ranges. */
- if (bitmap_intersect_p (e1, e2))
- {
- bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
- bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
-
- return (comp == EQ_EXPR || comp == GE_EXPR || comp == LE_EXPR)
- ? boolean_true_node
- : boolean_false_node;
- }
-
- /* Start at -1. Set it to 0 if we do a comparison without relying
- on overflow, or 1 if all comparisons rely on overflow. */
- int used_strict_overflow = -1;
-
- /* Otherwise, compare all the equivalent ranges. First, add N1 and
- N2 to their own set of equivalences to avoid duplicating the body
- of the loop just to check N1 and N2 ranges. */
- bitmap_iterator bi1;
- unsigned i1;
- EXECUTE_IF_SET_IN_BITMAP (e1, 0, i1, bi1)
- {
- if (!ssa_name (i1))
- continue;
-
- value_range_equiv tem_vr1;
- const value_range_equiv *vr1 = get_vr_for_comparison (i1, &tem_vr1, s);
-
- tree t = NULL_TREE, retval = NULL_TREE;
- bitmap_iterator bi2;
- unsigned i2;
- EXECUTE_IF_SET_IN_BITMAP (e2, 0, i2, bi2)
- {
- if (!ssa_name (i2))
- continue;
-
- bool sop = false;
-
- value_range_equiv tem_vr2;
- const value_range_equiv *vr2 = get_vr_for_comparison (i2, &tem_vr2,
- s);
-
- t = compare_ranges (comp, vr1, vr2, &sop);
- if (t)
- {
- /* If we get different answers from different members
- of the equivalence set this check must be in a dead
- code region. Folding it to a trap representation
- would be correct here. For now just return don't-know. */
- if (retval != NULL && t != retval)
- {
- bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
- bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
- return NULL_TREE;
- }
- retval = t;
-
- if (!sop)
- used_strict_overflow = 0;
- else if (used_strict_overflow < 0)
- used_strict_overflow = 1;
- }
- }
-
- if (retval)
- {
- bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
- bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
- if (used_strict_overflow > 0)
- *strict_overflow_p = true;
- return retval;
- }
- }
-
- /* None of the equivalent ranges are useful in computing this
- comparison. */
- bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
- bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
- return NULL_TREE;
-}
-
/* Helper function for vrp_evaluate_conditional_warnv & other
optimizers. */
@@ -2233,7 +675,7 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops_using_ranges
(enum tree_code code, tree op0, tree op1, bool * strict_overflow_p,
gimple *s)
{
- const value_range_equiv *vr0, *vr1;
+ const value_range *vr0, *vr1;
vr0 = (TREE_CODE (op0) == SSA_NAME) ? query->get_value_range (op0, s) : NULL;
vr1 = (TREE_CODE (op1) == SSA_NAME) ? query->get_value_range (op1, s) : NULL;
@@ -2255,7 +697,6 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops
(gimple *stmt,
enum tree_code code,
tree op0, tree op1,
- bool use_equiv_p,
bool *strict_overflow_p,
bool *only_ranges)
{
@@ -2277,7 +718,7 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops
occurs when the chosen argument is zero and does not occur if the
chosen argument is not zero. */
tree x;
- if (overflow_comparison_p (code, op0, op1, use_equiv_p, &x))
+ if (overflow_comparison_p (code, op0, op1, &x))
{
wide_int max = wi::max_value (TYPE_PRECISION (TREE_TYPE (op0)), UNSIGNED);
/* B = A - 1; if (A < B) -> B = A - 1; if (A == 0)
@@ -2314,7 +755,7 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops
}
else
gcc_unreachable ();
- const value_range_equiv *vr0 = query->get_value_range (op0, stmt);
+ const value_range *vr0 = query->get_value_range (op0, stmt);
/* If vro, the range for OP0 to pass the overflow test, has
no intersection with *vr0, OP0's known range, then the
overflow test can't pass, so return the node for false.
@@ -2339,113 +780,14 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops
return ret;
if (only_ranges)
*only_ranges = false;
- /* Do not use compare_names during propagation, it's quadratic. */
- if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME
- && use_equiv_p)
- return compare_names (code, op0, op1, strict_overflow_p, stmt);
- else if (TREE_CODE (op0) == SSA_NAME)
- return compare_name_with_value (code, op0, op1,
- strict_overflow_p, use_equiv_p, stmt);
+ if (TREE_CODE (op0) == SSA_NAME)
+ return compare_name_with_value (code, op0, op1, strict_overflow_p, stmt);
else if (TREE_CODE (op1) == SSA_NAME)
return compare_name_with_value (swap_tree_comparison (code), op1, op0,
- strict_overflow_p, use_equiv_p, stmt);
+ strict_overflow_p, stmt);
return NULL_TREE;
}
-/* Given (CODE OP0 OP1) within STMT, try to simplify it based on value range
- information. Return NULL if the conditional cannot be evaluated.
- The ranges of all the names equivalent with the operands in COND
- will be used when trying to compute the value. If the result is
- based on undefined signed overflow, issue a warning if
- appropriate. */
-
-tree
-simplify_using_ranges::vrp_evaluate_conditional (tree_code code, tree op0,
- tree op1, gimple *stmt)
-{
- bool sop;
- tree ret;
- bool only_ranges;
-
- /* Some passes and foldings leak constants with overflow flag set
- into the IL. Avoid doing wrong things with these and bail out. */
- if ((TREE_CODE (op0) == INTEGER_CST
- && TREE_OVERFLOW (op0))
- || (TREE_CODE (op1) == INTEGER_CST
- && TREE_OVERFLOW (op1)))
- return NULL_TREE;
-
- sop = false;
- ret = vrp_evaluate_conditional_warnv_with_ops (stmt, code, op0, op1, true,
- &sop, &only_ranges);
-
- if (ret && sop)
- {
- enum warn_strict_overflow_code wc;
- const char* warnmsg;
-
- if (is_gimple_min_invariant (ret))
- {
- wc = WARN_STRICT_OVERFLOW_CONDITIONAL;
- warnmsg = G_("assuming signed overflow does not occur when "
- "simplifying conditional to constant");
- }
- else
- {
- wc = WARN_STRICT_OVERFLOW_COMPARISON;
- warnmsg = G_("assuming signed overflow does not occur when "
- "simplifying conditional");
- }
-
- if (issue_strict_overflow_warning (wc))
- {
- location_t location;
-
- if (!gimple_has_location (stmt))
- location = input_location;
- else
- location = gimple_location (stmt);
- warning_at (location, OPT_Wstrict_overflow, "%s", warnmsg);
- }
- }
-
- if (warn_type_limits
- && ret && only_ranges
- && TREE_CODE_CLASS (code) == tcc_comparison
- && TREE_CODE (op0) == SSA_NAME)
- {
- /* If the comparison is being folded and the operand on the LHS
- is being compared against a constant value that is outside of
- the natural range of OP0's type, then the predicate will
- always fold regardless of the value of OP0. If -Wtype-limits
- was specified, emit a warning. */
- tree type = TREE_TYPE (op0);
- const value_range_equiv *vr0 = query->get_value_range (op0, stmt);
-
- if (vr0->varying_p ()
- && INTEGRAL_TYPE_P (type)
- && is_gimple_min_invariant (op1))
- {
- location_t location;
-
- if (!gimple_has_location (stmt))
- location = input_location;
- else
- location = gimple_location (stmt);
-
- warning_at (location, OPT_Wtype_limits,
- integer_zerop (ret)
- ? G_("comparison always false "
- "due to limited range of data type")
- : G_("comparison always true "
- "due to limited range of data type"));
- }
- }
-
- return ret;
-}
-
-
/* Visit conditional statement STMT. If we can determine which edge
will be taken out of STMT's basic block, record it in
*TAKEN_EDGE_P. Otherwise, set *TAKEN_EDGE_P to NULL. */
@@ -2479,55 +821,12 @@ simplify_using_ranges::vrp_visit_cond_stmt (gcond *stmt, edge *taken_edge_p)
fprintf (dump_file, "\n");
}
- /* Compute the value of the predicate COND by checking the known
- ranges of each of its operands.
-
- Note that we cannot evaluate all the equivalent ranges here
- because those ranges may not yet be final and with the current
- propagation strategy, we cannot determine when the value ranges
- of the names in the equivalence set have changed.
-
- For instance, given the following code fragment
-
- i_5 = PHI <8, i_13>
- ...
- i_14 = ASSERT_EXPR <i_5, i_5 != 0>
- if (i_14 == 1)
- ...
-
- Assume that on the first visit to i_14, i_5 has the temporary
- range [8, 8] because the second argument to the PHI function is
- not yet executable. We derive the range ~[0, 0] for i_14 and the
- equivalence set { i_5 }. So, when we visit 'if (i_14 == 1)' for
- the first time, since i_14 is equivalent to the range [8, 8], we
- determine that the predicate is always false.
-
- On the next round of propagation, i_13 is determined to be
- VARYING, which causes i_5 to drop down to VARYING. So, another
- visit to i_14 is scheduled. In this second visit, we compute the
- exact same range and equivalence set for i_14, namely ~[0, 0] and
- { i_5 }. But we did not have the previous range for i_5
- registered, so vrp_visit_assignment thinks that the range for
- i_14 has not changed. Therefore, the predicate 'if (i_14 == 1)'
- is not visited again, which stops propagation from visiting
- statements in the THEN clause of that if().
-
- To properly fix this we would need to keep the previous range
- value for the names in the equivalence set. This way we would've
- discovered that from one visit to the other i_5 changed from
- range [8, 8] to VR_VARYING.
-
- However, fixing this apparent limitation may not be worth the
- additional checking. Testing on several code bases (GCC, DLV,
- MICO, TRAMP3D and SPEC2000) showed that doing this results in
- 4 more predicates folded in SPEC. */
-
bool sop;
val = vrp_evaluate_conditional_warnv_with_ops (stmt,
gimple_cond_code (stmt),
gimple_cond_lhs (stmt),
gimple_cond_rhs (stmt),
- false, &sop, NULL);
+ &sop, NULL);
if (val)
*taken_edge_p = find_taken_edge (gimple_bb (stmt), val);
@@ -2619,336 +918,6 @@ find_case_label_ranges (gswitch *stmt, const value_range *vr,
return false;
}
-/* Visit switch statement STMT. If we can determine which edge
- will be taken out of STMT's basic block, record it in
- *TAKEN_EDGE_P. Otherwise, *TAKEN_EDGE_P set to NULL. */
-
-void
-vr_values::vrp_visit_switch_stmt (gswitch *stmt, edge *taken_edge_p)
-{
- tree op, val;
- const value_range_equiv *vr;
- size_t i = 0, j = 0, k, l;
- bool take_default;
-
- *taken_edge_p = NULL;
- op = gimple_switch_index (stmt);
- if (TREE_CODE (op) != SSA_NAME)
- return;
-
- vr = get_value_range (op);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "\nVisiting switch expression with operand ");
- print_generic_expr (dump_file, op);
- fprintf (dump_file, " with known range ");
- dump_value_range (dump_file, vr);
- fprintf (dump_file, "\n");
- }
-
- if (vr->undefined_p ()
- || vr->varying_p ()
- || vr->symbolic_p ())
- return;
-
- /* Find the single edge that is taken from the switch expression. */
- take_default = !find_case_label_ranges (stmt, vr, &i, &j, &k, &l);
-
- /* Check if the range spans no CASE_LABEL. If so, we only reach the default
- label */
- if (j < i)
- {
- gcc_assert (take_default);
- val = gimple_switch_default_label (stmt);
- }
- else
- {
- /* Check if labels with index i to j and maybe the default label
- are all reaching the same label. */
-
- val = gimple_switch_label (stmt, i);
- if (take_default
- && CASE_LABEL (gimple_switch_default_label (stmt))
- != CASE_LABEL (val))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, " not a single destination for this "
- "range\n");
- return;
- }
- for (++i; i <= j; ++i)
- {
- if (CASE_LABEL (gimple_switch_label (stmt, i)) != CASE_LABEL (val))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, " not a single destination for this "
- "range\n");
- return;
- }
- }
- for (; k <= l; ++k)
- {
- if (CASE_LABEL (gimple_switch_label (stmt, k)) != CASE_LABEL (val))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, " not a single destination for this "
- "range\n");
- return;
- }
- }
- }
-
- *taken_edge_p = find_edge (gimple_bb (stmt),
- label_to_block (cfun, CASE_LABEL (val)));
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, " will take edge to ");
- print_generic_stmt (dump_file, CASE_LABEL (val));
- }
-}
-
-
-/* Evaluate statement STMT. If the statement produces a useful range,
- set VR and corepsponding OUTPUT_P.
-
- If STMT is a conditional branch and we can determine its truth
- value, the taken edge is recorded in *TAKEN_EDGE_P. */
-
-void
-vr_values::extract_range_from_stmt (gimple *stmt, edge *taken_edge_p,
- tree *output_p, value_range_equiv *vr)
-{
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "\nextract_range_from_stmt visiting:\n");
- print_gimple_stmt (dump_file, stmt, 0, dump_flags);
- }
-
- if (!stmt_interesting_for_vrp (stmt))
- gcc_assert (stmt_ends_bb_p (stmt));
- else if (is_gimple_assign (stmt) || is_gimple_call (stmt))
- vrp_visit_assignment_or_call (stmt, output_p, vr);
- else if (gimple_code (stmt) == GIMPLE_COND)
- simplifier.vrp_visit_cond_stmt (as_a <gcond *> (stmt), taken_edge_p);
- else if (gimple_code (stmt) == GIMPLE_SWITCH)
- vrp_visit_switch_stmt (as_a <gswitch *> (stmt), taken_edge_p);
-}
-
-/* Visit all arguments for PHI node PHI that flow through executable
- edges. If a valid value range can be derived from all the incoming
- value ranges, set a new range in VR_RESULT. */
-
-void
-vr_values::extract_range_from_phi_node (gphi *phi,
- value_range_equiv *vr_result)
-{
- tree lhs = PHI_RESULT (phi);
- const value_range_equiv *lhs_vr = get_value_range (lhs);
- bool first = true;
- int old_edges;
- class loop *l;
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "\nVisiting PHI node: ");
- print_gimple_stmt (dump_file, phi, 0, dump_flags);
- }
-
- bool may_simulate_backedge_again = false;
- int edges = 0;
- for (size_t i = 0; i < gimple_phi_num_args (phi); i++)
- {
- edge e = gimple_phi_arg_edge (phi, i);
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- " Argument #%d (%d -> %d %sexecutable)\n",
- (int) i, e->src->index, e->dest->index,
- (e->flags & EDGE_EXECUTABLE) ? "" : "not ");
- }
-
- if (e->flags & EDGE_EXECUTABLE)
- {
- value_range_equiv vr_arg_tem;
- const value_range_equiv *vr_arg = &vr_arg_tem;
-
- ++edges;
-
- tree arg = PHI_ARG_DEF (phi, i);
- if (TREE_CODE (arg) == SSA_NAME)
- {
- /* See if we are eventually going to change one of the args. */
- gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
- if (! gimple_nop_p (def_stmt)
- && prop_simulate_again_p (def_stmt)
- && e->flags & EDGE_DFS_BACK)
- may_simulate_backedge_again = true;
-
- const value_range_equiv *vr_arg_ = get_value_range (arg);
- /* Do not allow equivalences or symbolic ranges to leak in from
- backedges. That creates invalid equivalencies.
- See PR53465 and PR54767. */
- if (e->flags & EDGE_DFS_BACK)
- {
- if (!vr_arg_->varying_p () && !vr_arg_->undefined_p ())
- {
- vr_arg_tem.set (vr_arg_->min (), vr_arg_->max (), NULL,
- vr_arg_->kind ());
- if (vr_arg_tem.symbolic_p ())
- vr_arg_tem.set_varying (TREE_TYPE (arg));
- }
- else
- vr_arg = vr_arg_;
- }
- /* If the non-backedge arguments range is VR_VARYING then
- we can still try recording a simple equivalence. */
- else if (vr_arg_->varying_p ())
- vr_arg_tem.set (arg);
- else
- vr_arg = vr_arg_;
- }
- else
- {
- if (TREE_OVERFLOW_P (arg))
- arg = drop_tree_overflow (arg);
-
- vr_arg_tem.set (arg);
- }
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "\t");
- print_generic_expr (dump_file, arg, dump_flags);
- fprintf (dump_file, ": ");
- dump_value_range (dump_file, vr_arg);
- fprintf (dump_file, "\n");
- }
-
- if (first)
- vr_result->deep_copy (vr_arg);
- else
- vr_result->legacy_verbose_union_ (vr_arg);
- first = false;
-
- if (vr_result->varying_p ())
- break;
- }
- }
-
- if (vr_result->varying_p ())
- goto varying;
- else if (vr_result->undefined_p ())
- goto update_range;
-
- old_edges = vr_phi_edge_counts[SSA_NAME_VERSION (lhs)];
- vr_phi_edge_counts[SSA_NAME_VERSION (lhs)] = edges;
-
- /* To prevent infinite iterations in the algorithm, derive ranges
- when the new value is slightly bigger or smaller than the
- previous one. We don't do this if we have seen a new executable
- edge; this helps us avoid an infinity for conditionals
- which are not in a loop. If the old value-range was VR_UNDEFINED
- use the updated range and iterate one more time. If we will not
- simulate this PHI again via the backedge allow us to iterate. */
- if (edges > 0
- && gimple_phi_num_args (phi) > 1
- && edges == old_edges
- && !lhs_vr->undefined_p ()
- && may_simulate_backedge_again)
- {
- /* Compare old and new ranges, fall back to varying if the
- values are not comparable. */
- int cmp_min = compare_values (lhs_vr->min (), vr_result->min ());
- if (cmp_min == -2)
- goto varying;
- int cmp_max = compare_values (lhs_vr->max (), vr_result->max ());
- if (cmp_max == -2)
- goto varying;
-
- /* For non VR_RANGE or for pointers fall back to varying if
- the range changed. */
- if ((lhs_vr->kind () != VR_RANGE || vr_result->kind () != VR_RANGE
- || POINTER_TYPE_P (TREE_TYPE (lhs)))
- && (cmp_min != 0 || cmp_max != 0))
- goto varying;
-
- /* If the new minimum is larger than the previous one
- retain the old value. If the new minimum value is smaller
- than the previous one and not -INF go all the way to -INF + 1.
- In the first case, to avoid infinite bouncing between different
- minimums, and in the other case to avoid iterating millions of
- times to reach -INF. Going to -INF + 1 also lets the following
- iteration compute whether there will be any overflow, at the
- expense of one additional iteration. */
- tree new_min = vr_result->min ();
- tree new_max = vr_result->max ();
- if (cmp_min < 0)
- new_min = lhs_vr->min ();
- else if (cmp_min > 0
- && (TREE_CODE (vr_result->min ()) != INTEGER_CST
- || tree_int_cst_lt (vrp_val_min (vr_result->type ()),
- vr_result->min ())))
- new_min = int_const_binop (PLUS_EXPR,
- vrp_val_min (vr_result->type ()),
- build_int_cst (vr_result->type (), 1));
-
- /* Similarly for the maximum value. */
- if (cmp_max > 0)
- new_max = lhs_vr->max ();
- else if (cmp_max < 0
- && (TREE_CODE (vr_result->max ()) != INTEGER_CST
- || tree_int_cst_lt (vr_result->max (),
- vrp_val_max (vr_result->type ()))))
- new_max = int_const_binop (MINUS_EXPR,
- vrp_val_max (vr_result->type ()),
- build_int_cst (vr_result->type (), 1));
-
- vr_result->update (new_min, new_max, vr_result->kind ());
-
- /* If we dropped either bound to +-INF then if this is a loop
- PHI node SCEV may known more about its value-range. */
- if (cmp_min > 0 || cmp_min < 0
- || cmp_max < 0 || cmp_max > 0)
- goto scev_check;
-
- goto infinite_check;
- }
-
- goto update_range;
-
-varying:
- vr_result->set_varying (TREE_TYPE (lhs));
-
-scev_check:
- /* If this is a loop PHI node SCEV may known more about its value-range.
- scev_check can be reached from two paths, one is a fall through from above
- "varying" label, the other is direct goto from code block which tries to
- avoid infinite simulation. */
- if (scev_initialized_p ()
- && (l = loop_containing_stmt (phi))
- && l->header == gimple_bb (phi))
- adjust_range_with_scev (vr_result, l, phi, lhs);
-
-infinite_check:
- /* If we will end up with a (-INF, +INF) range, set it to
- VARYING. Same if the previous max value was invalid for
- the type and we end up with vr_result.min > vr_result.max. */
- if ((!vr_result->varying_p () && !vr_result->undefined_p ())
- && !((vrp_val_is_max (vr_result->max ()) && vrp_val_is_min (vr_result->min ()))
- || compare_values (vr_result->min (), vr_result->max ()) > 0))
- ;
- else
- vr_result->set_varying (TREE_TYPE (lhs));
-
- /* If the new range is different than the previous value, keep
- iterating. */
-update_range:
- return;
-}
-
/* Simplify boolean operations if the source is known
to be already a boolean. */
bool
@@ -3063,7 +1032,7 @@ simplify_using_ranges::simplify_div_or_mod_using_ranges
if (rhs_code == TRUNC_MOD_EXPR
&& TREE_CODE (op1) == SSA_NAME)
{
- const value_range_equiv *vr1 = query->get_value_range (op1, stmt);
+ const value_range *vr1 = query->get_value_range (op1, stmt);
if (range_int_cst_p (vr1))
op1min = vr1->min ();
}
@@ -3557,8 +1526,7 @@ simplify_using_ranges::fold_cond (gcond *cond)
return true;
}
- /* ?? vrp_folder::fold_predicate_in() is a superset of this. At
- some point we should merge all variants of this code. */
+ // FIXME: Audit the code below and make sure it never finds anything.
edge taken_edge;
vrp_visit_cond_stmt (cond, &taken_edge);
@@ -4428,24 +2396,3 @@ simplify_using_ranges::simplify (gimple_stmt_iterator *gsi)
return false;
}
-
-/* Set the lattice entry for VAR to VR. */
-
-void
-vr_values::set_vr_value (tree var, value_range_equiv *vr)
-{
- if (SSA_NAME_VERSION (var) >= num_vr_values)
- return;
- vr_value[SSA_NAME_VERSION (var)] = vr;
-}
-
-/* Swap the lattice entry for VAR with VR and return the old entry. */
-
-value_range_equiv *
-vr_values::swap_vr_value (tree var, value_range_equiv *vr)
-{
- if (SSA_NAME_VERSION (var) >= num_vr_values)
- return NULL;
- std::swap (vr_value[SSA_NAME_VERSION (var)], vr);
- return vr;
-}
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index 8c8f031..6ad9fb2 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -20,7 +20,6 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_VR_VALUES_H
#define GCC_VR_VALUES_H
-#include "value-range-equiv.h"
#include "value-query.h"
// Abstract class to return a range for a given SSA.
@@ -33,21 +32,13 @@ public:
simplify_using_ranges (range_query *query = NULL,
int not_executable_flag = 0);
~simplify_using_ranges ();
- void set_range_query (class range_query *q, int not_executable_flag = 0)
- { query = q; m_not_executable_flag = not_executable_flag; }
-
bool simplify (gimple_stmt_iterator *);
-
- // ?? These should be cleaned, merged, and made private.
- tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *);
- void vrp_visit_cond_stmt (gcond *, edge *);
bool fold_cond (gcond *);
+private:
+ void vrp_visit_cond_stmt (gcond *, edge *);
tree vrp_evaluate_conditional_warnv_with_ops (gimple *stmt, enum tree_code,
- tree, tree, bool,
- bool *, bool *);
+ tree, tree, bool *, bool *);
bool simplify_casted_cond (gcond *);
-
-private:
bool simplify_truth_ops_using_ranges (gimple_stmt_iterator *, gimple *);
bool simplify_div_or_mod_using_ranges (gimple_stmt_iterator *, gimple *);
bool simplify_abs_using_ranges (gimple_stmt_iterator *, gimple *);
@@ -61,11 +52,8 @@ private:
bool two_valued_val_range_p (tree, tree *, tree *, gimple *);
bool op_with_boolean_value_range_p (tree, gimple *);
- tree compare_name_with_value (enum tree_code, tree, tree, bool *, bool,
- gimple *);
- tree compare_names (enum tree_code, tree, tree, bool *, gimple *s);
- const value_range_equiv *get_vr_for_comparison (int, value_range_equiv *,
- gimple *s);
+ tree compare_name_with_value (enum tree_code, tree, tree, bool *, gimple *);
+ const value_range *get_vr_for_comparison (int, value_range *, gimple *s);
tree vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code,
tree, tree,
bool *, gimple *s);
@@ -89,95 +77,6 @@ private:
vec<edge> m_flag_set_edges; // List of edges with flag to be cleared.
};
-/* The VR_VALUES class holds the current view of range information
- for all the SSA_NAMEs in the IL.
-
- It can be used to hold context sensitive range information during
- a dominator walk or it may be used to hold range information in the
- standard VRP pass as ranges are propagated through the lattice to a
- steady state.
-
- This information is independent of the range information that gets
- attached to SSA_NAMEs. A pass such as VRP may choose to transfer
- the global information it produces into global range information that
- gets attached to an SSA_NAME. It's unclear how useful that global
- information will be in a world where we can compute context sensitive
- range information fast or perform on-demand queries. */
-class vr_values : public range_query
-{
- public:
- vr_values (void);
- ~vr_values (void);
-
- virtual bool range_of_expr (vrange &r, tree expr, gimple *stmt) override;
- virtual tree value_of_expr (tree, gimple * = NULL) override;
- virtual tree value_on_edge (edge, tree) override;
- virtual tree value_of_stmt (gimple *, tree = NULL_TREE) override;
- virtual const value_range_equiv *get_value_range (const_tree,
- gimple * = NULL) override;
- void set_vr_value (tree, value_range_equiv *);
- value_range_equiv *swap_vr_value (tree, value_range_equiv *);
-
- void set_def_to_varying (const_tree);
- void set_defs_to_varying (gimple *);
- bool update_value_range (const_tree, value_range_equiv *);
- tree op_with_constant_singleton_value_range (tree);
- void adjust_range_with_scev (value_range_equiv *, class loop *,
- gimple *, tree);
- virtual void dump (FILE *) override;
-
- void extract_range_for_var_from_comparison_expr (tree, enum tree_code,
- tree, tree,
- value_range_equiv *);
- void extract_range_from_phi_node (gphi *, value_range_equiv *);
- void extract_range_basic (value_range_equiv *, gimple *);
- void extract_range_from_stmt (gimple *, edge *, tree *, value_range_equiv *);
-
- /* Indicate that propagation through the lattice is complete. */
- void set_lattice_propagation_complete (void) { values_propagated = true; }
-
- /* Allocate a new value_range object. */
- value_range_equiv *allocate_value_range_equiv (void)
- { return range_query::allocate_value_range_equiv (); }
- void free_value_range (value_range_equiv *vr)
- { free_value_range_equiv (vr); }
-
- private:
- value_range_equiv *get_lattice_entry (const_tree);
- bool vrp_stmt_computes_nonzero (gimple *);
- void extract_range_from_assignment (value_range_equiv *, gassign *);
- void extract_range_from_assert (value_range_equiv *, tree);
- void extract_range_from_ssa_name (value_range_equiv *, tree);
- void extract_range_from_binary_expr (value_range_equiv *, enum tree_code,
- tree, tree, tree);
- void extract_range_from_unary_expr (value_range_equiv *, enum tree_code,
- tree, tree);
- void extract_range_from_cond_expr (value_range_equiv *, gassign *);
- void extract_range_from_comparison (value_range_equiv *, gimple *);
- void vrp_visit_assignment_or_call (gimple*, tree *, value_range_equiv *);
- void vrp_visit_switch_stmt (gswitch *, edge *);
- bool extract_range_from_ubsan_builtin (value_range_equiv *, gimple *);
-
- /* This probably belongs in the lattice rather than in here. */
- bool values_propagated;
-
- /* Allocations for equivalences all come from this obstack. */
- bitmap_obstack vrp_equiv_obstack;
-
- /* Value range array. After propagation, VR_VALUE[I] holds the range
- of values that SSA name N_I may take. */
- unsigned int num_vr_values;
- value_range_equiv **vr_value;
-
- /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
- number of executable edges we saw the last time we visited the
- node. */
- int *vr_phi_edge_counts;
- simplify_using_ranges simplifier;
-};
-
-extern tree get_output_for_vrp (gimple *);
-
extern bool range_fits_type_p (const value_range *vr,
unsigned dest_precision, signop dest_sgn);
extern bool bounds_of_var_in_loop (tree *min, tree *max, range_query *,